Saturday, August 26, 2006

Have MSBuild script collect userinput

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/have_msbuild_script_collect_userinput.htm]

MSBuild is great for automated batch processes. It's easy to set properties in the script itself using the . However, MSBuild is powerful enough that you can also collect user input with a WinForm.

Why would you do this, given that the whole point of a build process is to be automated? ... Because MSBuild is an automation language, it can be used not just for builds but to
ultimately automate any task. For some tasks that you kick off manually (like installations, deployments, instrumentation, etc...) you may want to collect the user input up front.

Doing this requires three steps.

  1. Use MSBuild's exec task to call a WinForm exe (that you create with a Windows Form project). Note that you may want to compile the windows project first, and then call the newly created exe.
  2. Have the WinForm app close, returning an error
  3. Back in the MSBuild script, collect this error information and handle it how you want.

The first step is easy, lets look at the second one. There are several different ways we can return error information from a WinForm.

  1. We could throw an exception, but that just pops up a messy JIT window, tells the user that the app failed, and doesn't return an error to the build process.
  2. We could have the WinForm write out to a log file, and then have the MSBuild script fail if that file exists - but that requires extra files and is messy.
  3. We could modify the return code of program.cs (just like you can modify a console app's return code) to return an integer, and that set that int with a static variable. This is our best option of the three - no external files, and the error is handled gracefully.

With this technique, everything becomes easy: Our MSBuild script can be simple:

  "EndPoint">
   
    "WindowsApplication1\WindowsApplication1.csproj"
        Targets="Build"
        Properties="Configuration=Debug" />
   
    "Start UI" />
    "WindowsApplication1\bin\Debug" Command="WindowsApplication1.exe" />

    "Done, do other stuff now..." />
 

The WinForm is easy:

  static class Program  {    ///     /// The main entry point for the application.    ///     [STAThread]    static int Main()    {      Application.EnableVisualStyles();      Application.SetCompatibleTextRenderingDefault(false);      Application.Run(new Form1());      return _intReturnCode;    }    private static int _intReturnCode = 0;    public static int ReturnCode    {      get { return _intReturnCode; }      set { _intReturnCode = value; }    }      }

 

We can then set the static variable "ReturnCode" anywhere in the WinForm by setting Program.ReturnCode.

(Note that we can also have the WinForm use Console.Writeline(), which will be logged in the MSBuild script).

Having the MSBuild script take user input is an easy trick to perform, and may be helpful for certain tasks.

No comments:

Post a Comment