NetInverse Developers Blog

March 9, 2009
Category: .Net, Build — Tags: — admin @ 7:59 pm

It is very common that you need to run some commands on a remote server. For example, you may want to config your source control server to start a build process on a dedicated build machine once it receives any checkins. To achieve this, you can leverage the WMI scripting APIs.

The steps are:

  1. Use SWbemLocator to create Locator object
  2. Use the Locator object to connect to the remote server and get back a Service object
  3. Use the Service object to get a Win32 process object
  4. Finally, use the Process object to issue your command

WMI WbemScripting script sample:

    Function RemoteExecute(strServer, strUser, strPassword, CmdLine)
        Const Impersonate = 3

        RemoteExecute = -1

        Set Locator = CreateObject("WbemScripting.SWbemLocator")
        Set Service = Locator.ConnectServer(strServer, "root\cimv2", strUser, strPassword)

        Service.Security_.ImpersonationLevel = Impersonate
        Set Process = Service.Get("Win32_Process")

        result = Process.Create(CmdLine, , , ProcessId)

        If (result <> 0) Then
            WScript.Echo "Creating Remote Process Failed: " & result
            Wscript.Quit
        End If

        RemoteExecute = ProcessId
    End Function

NAnt is very popular in the .Net development community. You may want to write a C# extension for NAnt scripts to achieve some build automations on remote servers. You can achieve that easily too. I am posting a WMI C# sample below for your reference too.

WMI C# sample:

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Management;

    namespace WMISample
    {
        class Program
        {
            static void Main(string[] args)
            {
                string remoteMachine = "localhost";

                ConnectionOptions connOptions = new ConnectionOptions();
                connOptions.Impersonation = ImpersonationLevel.Impersonate;
                connOptions.EnablePrivileges = true;

                ManagementScope manScope = new ManagementScope(
                    String.Format(@"\\{0}\ROOT\CIMV2", remoteMachine), connOptions);
                manScope.Connect();

                ObjectGetOptions objectGetOptions = new ObjectGetOptions();
                ManagementPath managementPath = new ManagementPath("Win32_Process");
                ManagementClass processClass = new ManagementClass(
                    manScope, managementPath, objectGetOptions);

                ManagementBaseObject inParams = processClass.GetMethodParameters("Create");

                inParams["CommandLine"] = @"notepad.exe";
                ManagementBaseObject outParams = processClass.InvokeMethod("Create", inParams, null);

                Console.WriteLine("Creation of the process returned: " + outParams["returnValue"]);
                Console.WriteLine("Process ID: " + outParams["processId"]);
                Console.ReadLine();
            }
        }
    }
March 8, 2009
Category: Build — Tags: , , — admin @ 8:37 pm

I converted an old VS2003 project into VS2005 and tried to build it with an existing Nant build script. Nant started to fail with a following error: Error loading GUID of project…

NAnt 0.85 (Build 0.85.2470.0; nightly; 10/6/2006)
Copyright (C) 2001-2006 Gerry Shaw
http://nant.sourceforge.net
Buildfile: file:///C:/projects/MyProject.build
Target framework: Microsoft .NET Framework 2.0
Target(s) specified: Build  
    [echo] Using 'net-2.0' framework on 'win32' platform.
Build:
BuildProjects:
[echo] Current base directory: .
[echo] Building all projects under base directory...
[solution] Starting solution build. 
BUILD FAILED - 0 non-fatal error(s), 1 warning(s)
Error loading GUID of project 'C:\MyProject\DBAccess.csproj'.
Couldn't locate ProjectGuid in project 'C:\MyProject\DBAccess.csproj'
Total time: 0.8 seconds.

My build file as below was working before I converted the project using VS2005.

        <target name="Build">
          ...
            <solution configuration="${configuration}">
                <projects basedir="${basedir}">
                    <include name="**\*.csproj"/>
                </projects>
            </solution>
        </target>

After digging into the Nant online doc, I found that the current version of Nant doesn’t support VS2005 project . Visual Studio 2005 uses the MSBuild project file to store build information about managed projects. Project settings added and changed through Visual Studio are reflected in the .*proj file that is generated for each project. Visual Studio uses a hosted instance of MSBuild to build managed projects, meaning that a managed project can be built in Visual Studio and from the command line (even without Visual Studio installed), with identical results. Thus the solution is use MSBuild to build VS2005 project file. I changed the Nant script as below:

        <target name="exec-msbuild">
            <exec program="msbuild"
                commandline='"${solution.file}" /v:q /nologo
    /t:${solution.target} /p:Configuration=${configuration}' />
        </target>

Now my project successfully migrated to VS2005 and .Net 2.0.

©2009 NetInverse. All rights reserved. Powered by WordPress