Vista and Virtualization

I’d read about virtualization and how to avoid it and how to structure your application so that it could write to directories like Program Files without getting caught but I still managed to get in a right twist with it. The best overview of it that I’ve read is here.

The problem is that once you’ve triggered it you’re stuck with it. Depending on how you try to access the file you’ll get the actual file in the directory or the virtualized file. I tried my program without the manifest to force higher privilege first and it appeared to work. I then got the manifest working and tried to modify the license. The changes had no effect. If I loaded the file in a text editor however the changes were there. Freaking weird. I had assumed that since I started changing things properly with the correct permissions that it would sort it out but I was wrong. Instead the program loaded the virtualized file each time.

Ironically a deinstall didn’t always remove the virtualized file. If I ran it from the Start menu the virtualized file remained so that when I reinstalled it was there again. If I ran the uninstall from the Control Panel it did get removed however. All in all a fun feature to discover when you’re developing 😉

Looking at the results of running procmon I suspect that the way to un-virtualize a file is to remove it from the C:\Users\%username%\AppData\Local\VirtualStore\ directory. Once that file has been deleted so long as you behave I assume that you won’t get virtualized.

I’ve now realised that it’s really important for all your executables to have the manifest specifying the access level required for the program. That’s even if you want to run ‘asInvoker’ which is typically just as the user. My previous post on the subject mentions how to setup the manifest but Aaron’s UI Design Blog has more on the subject of Virtualization and how to spot when it’s in action.

This is the sort of scenario you can see if you don’t have the manifest compiled in. Say your app is a text editor. Lets also say you have a license file in one of the directories that will get virtualized. What happens if the user decides to edit that file? It gets virtualized. Your program wrote to it and it wasn’t with elevated privileges. If they then decide to register your program because it’s so cool you spawn a process to elevate privileges and write to the license file. Only you write to the actual file not the virtualized one because you’ve done everything by the rules. The user then loads your program as usual without elevated privileges. Which license file does it pick up? The one that got virtualized. The one that you registered is sitting there, they load it in their text editor and can see the correct information. Only the program isn’t loading it!

If instead you have specified asInvoker in your manifest then you will get an access violation when you try to save to that file in the first place. Much more manageable.

Note: I’m using NSIS as an installer rather than an MSI based one so different installers may vary when it comes to the uninstall. The service packs may changes things too. And then there’s the fact that virtualization will disappear when us developers have learned to avoid being naughty!

Advantage in .net for VO developers – using ADS 7 & 8 with the same code

If you need to support both Advantage 7 and 8 with .net 2.0 code you probably want to look at the DbProviderFactory. That way you can make use of the .Net dataprovider for .net 2.0 for 8.0 and if you connect to 7.0 you can use the OLE Db driver.

You might also want to use the DbConnectionStringBuilder to build the connection string.

Here is some example code for creating the Connection and Parameter objects. Commands can be created from the Connection objects.

public DbConnection GetConnection()
{
    DbConnection con;
    string factory;
    string tableType;
    if (_v7Compatibility)
    {
        factory = "System.Data.OleDb";
        _connectionType = "ADS_REMOTE_SERVER|ADS_LOCAL_SERVER";
        tableType = "ADS_CDX";
    }
    else
    {
        factory = "Advantage.Data.Provider";
        _connectionType = "local|remote";
        tableType = "CDX";
    }
    _factory = DbProviderFactories.GetFactory(factory);
    DbConnectionStringBuilder builder = _factory.CreateConnectionStringBuilder();
    builder["ServerType"] = _connectionType;
    builder["Data Source"] = _datapath;
    builder["CharType"] = _chartype;
    builder["FilterOptions"] = "RESPECT_WHEN_COUNTING";
    builder["TrimTrailingSpaces"] = true;
    builder["TableType"] = tableType;

    con = _factory.CreateConnection();
    con.ConnectionString = builder.ConnectionString;
    con.Open();
    return con;
}

public DbParameter CreateParameter(string name, object value)
{
    DbParameter param = _factory.CreateParameter();
    param.ParameterName = name;
    param.Value = value;
    return param;
}


The downside of using the DbProviderFactory is that the .Net data provider must be installed into the GAC and the factories xml file. The Advantage installer only works on machines with Visual Studio installed as well (currently) so it’s not much use when deploying to a server. This means that you have to install by hand (copying over gacutil by hand) or create your own installer that does all the hardwork. Neither are particularly ideal. I’ve yet to figure out how to use Wix or the Visual Studio installer projects to install into the .net 2.0 GAC properly.

The other downside of using the factory is that you can only use the lowest common denominator of functions. You have to give up the more advanced methods and parameters provided by the Advantage library. Well ‘have’ is a strong word, you can cast the Db* objects to their actual type and then use the more advanced methods but there is more work involved. You need to check the actual type of the object, then cast it and then use it. That also means that you must have a direct reference to the Assembly – even if you aren’t using it at that site. In other words a site running ADS 7.0 would still have t o have the version 8.0 drivers installed.

Vista, UAC elevation and MSBuild

While making an application that requires UAC elevation in Vista I used this neat article to create my manifest and add it to Visual Studio. The one problem with that is that the MSBuild build then failed to add that manifest. The problem is that $DevEnvDir variable is not defined when run by MSBuild. This makes sense when you think about it because MSBuild is installed on all machines with the .net framework but not all those machines might have Visual Studio. To fix the problem just add the following parameter, “/property:DevEnvDir=C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\”
.

In my batch file the complete line looks like this,

c:\Windows\Microsoft.NET\Framework\v2.0.50727\msbuild.exe Basher.sln "/property:DevEnvDir=C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\"

You might also need to change the build event to have a slash straight after the variable. This makes it,

"$(DevEnvDir)\..\..\SDK\v2.0\bin\mt.exe" -manifest "$(ProjectDir)$(TargetName).exe.manifest" –outputresource:"$(TargetDir)$(TargetFileName)";#1

Another thing to watch out for if you launch your program to do the task with elevated access is what happens if the user cancels the access.   In the case of .Net you might get a “System.ComponentModel.Win32Exception: The operation was canceled by the user”.  This probably translates to a normal error return from ShellExecute if you are doing it from win32.

.net development tools

Having started developing a serious program in .net I’ve been experimenting with a lot of .net development tools. As well as mbUnit and TestDriven.net there are a couple of things I’m finding useful. Resharper is really useful for making Visual Studio even easier to use. It has a bunch of refactoring things that are fairly useful. The things that are most useful though are the additional syntax highlighting and the improved auto-complete. The killer is the way that it highlights unused variables in light grey. It’s a really nice cue that lets you spot redundant or broken code. It even spots missing items from String.Format lists. Very cool. The only reason I haven’t bought it yet is that my car stole my money. Using Visual Studio without it is really making me appreciate how much I liked it.

Another tool is MSBuild – it actually comes with the .net framework but it’s worth looking at. I tried NAnt but for my simple needs MSBuild seems to work best. It builds your programs using the same solutions and projects as Visual Studio so you can switch between the two seamlessly and you don’t have to maintain two separate build files.

For editing I’ve found that the ViEmu extensions for Visual Studio make it a lot easier to use on a laptop. I have spent the money on that. If you like vim it’s well worth it. If not it’s really not going to do it for you.

Why you should use MbUnit

Saying that you should use MbUnit because it allows you to keep track of what tests pass and fail in daily build reports misses the biggest reason to use it.

I never could understand the point of the *Unit unit test framework but now I do. It’s really quick and easy to use. You create a library and adds some public classes and label them as test fixtures. Include the project you want to test and code up some tests. Then run the class library via the console or the gui application.

using System.Collections.Generic;
using MbUnit.Framework;
using MyLib;

namespace UnitTests
{
    [TestFixture]
    public class CommandLineParserTests
    {
        [Test]
        public void BoundCheck()
        {
            CommandLineParser parser = new CommandLineParser();
            parser.parseCommandLine("");
            Assert.AreEqual(parser.GetRest().Count, 0);
            Assert.AreEqual(parser.GetProgram(), "");
        }

        [RowTest]
        [Row("test.exe", "test.exe", new string[] {}, new string[] {}, new string[] {}, new string[] {} )]
        [Row("..\\bleh test", "..\\bleh", new string[] {"test"}, new string[] {}, new string[] {}, new string[] {} )]
        [Row("\"C:\\Program Files\\UltraEdit\\uedit32.exe\" file.txt", "C:\\Program Files\\UltraEdit\\uedit32.exe", new string[] { "file.txt"}, new string[] {}, new string[] {}, new string[] {} )]
        [Row("test.txt gooner.txt ", "test.txt", new string[] {"gooner.txt"}, new string[] {}, new string[] {}, new string[] {} )]
        [Row("test.txt  gooner.txt ", "test.txt", new string[] {"gooner.txt"}, new string[] {}, new string[] {}, new string[] {} )]
        [Row("test.txt   gooner.txt  test", "test.txt", new string[] {"gooner.txt", "test"}, new string[] {}, new string[] {}, new string[] {} )]
        [Row("test.txt gooner.txt - ", "test.txt", new string[] {"gooner.txt", "-"}, new string[] {}, new string[] {}, new string[] {} )]
        public void NothingExpected(string commandLine, string program, string []rest, string []flags, string []param, string []values)
        {
            CommandLineParser parser = new CommandLineParser();
            parser.parseCommandLine(commandLine);

            List<string> lRest = new List<string>(rest);
            List<string> lFlags = new List<string>(flags);
            List<string> lParams = new List<string>(param);
            List<string> lValues = new List<string>(values);
            Assert.AreEqual(program, parser.GetProgram());
            for (int i = 0; i < parser.GetRest().Count; i++)
            {
                Assert.AreEqual(parser.GetRest()[i], lRest[i]);
            }
            foreach(string flag in lFlags)
            {
                Assert.IsTrue(parser.IsFlagSet(flag));
            }
            for (int i = 0 ; i < lParams.Count; i++ )
            {
                string flag = lParams[i];
                string value = lValues[i];
                Assert.IsTrue(parser.IsFlagSet(flag));
                Assert.AreEqual(value, parser.GetValue(flag));
            }
        }
	}
}


You might want to look at TestDriven.net too. It’s useful for running the tests through the debugger or just in the IDE.

Getting the command line on .net

There appear to be 3 ways to get the command line in .net. The first and simplest is to just declare a string array in the arguments for your main method. This gives you the parameters as a list. All the quotes and breaks between the words have been interpreted for you and you just have to use the list. The one thing missing from this is the program file that was traditionally the first element in languages like C.

static void Main(string[] args)
{

The second is to call System.Environment.GetCommandLineArgs(). This again gives you an array. The main reason you might want this is that it has the program name as the first element. Useful if you want to find the path* the program was executed from or want to put the actual program name in a usage message for example.

The third is to get the System.Environment.CommandLine. This is a string of the complete command line. If you are converting over an old command line parser to .net from a language that received the command line in that format (VO springs to mind) you might want to use it. Alternatively commands like echo that need the exact command line with spacing intact would want to get it this way.

* don’t trust the first parameter completely, it can be faked.

Web design purity

If you’ve been paying attention to web design recently you will have noticed that it has been cleaned up a lot. The different parts of the system have been divided up into layers for their tasks and people have discovered the benefits of keeping things nicely seperated.

Chris Heilmann has an excellent example of a couple of list boxes that can be filtered that doesn’t break down if javascript is turned off. If you run the example with javascript turned on you see two list boxes and the second one is filtered based on what is selected in the first one. If you have it turned off you have a single list box with the relationship visible in the list box. It’s all rather neat. He is able to use proper HTML to define the list box you see if javascript is turned off and if it is turned on the javascript reads the HTML for the information for the lists and then creates the new combo boxes.

What happens if the relationship is messier than that? I have an application where I have two lists, one a list of customers, the other the list of applications they run. A customer can have multiple systems and the systems will be used by multiple customers. If in the non-javascript version I do my list in the same way it will go on for miles. I would rather simply have the two lists and allow the user to select an incorrect system. I can then validate at the server side. So far so good. That is a reasonable solution for what to do without the javascript. The user doesn’t make mistakes about the system too often and if they do make one, it will be caught.

Now I need to build the javascript side. This should simply filter the list of systems to only include those used by the customer. How do I do that? There is no information about that relationship within the HTML. If I’m really neat I should have no javascript directly within the HTML and I don’t think generating the javascript is particularly great either.

In the end I embedded some javascript in the HTML which setup a variable containing the relationship. The javascript for adjusting the lists simply uses that variable. It’s not too pretty but it solves the job and as far as I can see is the best compromise. I’m already looking at the customer and system lists so generating the information about the relationship seems to make sense. If javascript is turned off it’s just a bit of dead text to the browser so it doesn’t hurt anything.

Is there a better way to solve the problem?