views:

2643

answers:

3

What would be the way to retrieve the Windows SDK folder in an MSBuild task?

Using the generateBootstrapper task I'm creating a bootstrapper for my setup to be able to install the pre-requisites. This task needs the path to the folder where the pre-requisite packages are located, i.e. the Windows SDK folder

"C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bootstrapper\Packages\"

when using Visual Studio 2008. So far I have been using a hard-coded path but this won't work on any system. Is there a better way to get the path?

This is my build script:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"&gt;
    <ItemGroup>
     <BootstrapperFile Include="Microsoft.Net.Framework.2.0">
      <ProductName>.NET Framework 2.0</ProductName>
     </BootstrapperFile>
     <BootstrapperFile Include="Microsoft.Windows.Installer.3.1">
      <ProductName>Windows Installer 3.1</ProductName>
     </BootstrapperFile>
    </ItemGroup>

    <Target Name="Bootstrapper">
        <GenerateBootstrapper ApplicationFile="mySetup.msi" 
            Culture="de-DE" 
            ApplicationName="My Application" 
            OutputPath="$(OutDir)\de-DE" 
            BootstrapperItems="@(BootstrapperFile)" 
            Path="C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bootstrapper\Packages\" />

        <GenerateBootstrapper ApplicationFile="mySetup.msi" 
            Culture="en-US" 
            ApplicationName="My Application" 
            OutputPath="$(OutDir)\en-US" 
            BootstrapperItems="@(BootstrapperFile)" 
            Path="C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bootstrapper\Packages\" />
    </Target>
</Project>
+2  A: 

The path to the bootstrapper is stored under the registry key:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\GenericBootstrapper\3.5

To find out the packages folder, open this, read the "Path" registry value, and append "Packages" on the end and that should give you the full path to the folder you want.

For example:

string bootStrapperPackagesFolder = "";

RegistryKey regKey = Registry.LocalMachine.OpenSubKey
   (@"SOFTWARE\Microsoft\GenericBootstrapper\3.5");
if (regKey != null)
{
   bootStrapperPackagesFolder = (string)regKey.GetValue("Path");
   if (bootStrapperPackagesFolder != null)
   {
      bootStrapperPackagesFolder += @"Packages\";
      Console.WriteLine(bootStrapperPackagesFolder);
   }
}
John Sibly
+3  A: 

Hi, thanks John. According to your post I edited the MSBuild script to read the folder from the registry. It was however not necessary to append "Packages" on the end, that was another mistake in my original script.

The following is the working script:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"&gt;

    <PropertyGroup>
        <WindowsSDKPath>$(registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\GenericBootstrapper\3.5@Path)</WindowsSDKPath>
    </PropertyGroup>

    <ItemGroup>
        <BootstrapperFile Include="Microsoft.Net.Framework.2.0">
                <ProductName>.NET Framework 2.0</ProductName>
        </BootstrapperFile>
        <BootstrapperFile Include="Microsoft.Windows.Installer.3.1">
                <ProductName>Windows Installer 3.1</ProductName>
        </BootstrapperFile>
    </ItemGroup>

    <Target Name="Bootstrapper">
        <GenerateBootstrapper ApplicationFile="mySetup.msi" 
            Culture="de-DE" 
            ApplicationName="My Application" 
            OutputPath="$(OutDir)\de-DE" 
            BootstrapperItems="@(BootstrapperFile)" 
            Path="$(WindowsSDKPath)" />

        <GenerateBootstrapper ApplicationFile="mySetup.msi" 
            Culture="en-US" 
            ApplicationName="My Application" 
            OutputPath="$(OutDir)\en-US" 
            BootstrapperItems="@(BootstrapperFile)" 
            Path="$(WindowsSDKPath)" />
    </Target>
</Project>
0xA3
+4  A: 

You can also use the GetFrameworkSdkPath MSBuild task.

<GetFrameworkSdkPath>
  <Output TaskParameter="Path" PropertyName="SdkPath" />
</GetFrameworkSdkPath>

For example:

<GenerateBootstrapper 
  ApplicationFile="$(SolutionName).application"
  ApplicationName="$(ClickOnceAppTitle)"
  ApplicationUrl="$(ClickOnceUrl)"
  BootstrapperItems="@(BootstrapperFile)"
  Culture="en"
  FallbackCulture="en-US"
  Path="$(WindowsSDKPath)"
  OutputPath="." />
Jeremy DeVoss