How to extend target file to include registry settings for web project package

How to extend target file to include registry settings for web project package

  • Comments 2

Web project package and deployment targets files are written with extensibility in mind.  User can easily extend a property to include more functionalities in their package by using msbuild targets and properties. 

If we check the Microsoft.Web.Publishing.targets file under “%Program Files%\MSBuild\Microsoft\VisualStudio\v10.0\Web\”, we can see the following, which means if file $(WebPublishPipelineProjectName).wpp.targets exists in the project directory, we’ll import it automatically when build package or publish.

  <!--***************************************************************-->
  <!--To allow the Team build to have custom setting for the Web Application project without change the project file  -->
  <!--by default, if user have a file call $(WebPublishPipelineProjectName).wpp.targets, we will import these setting in before we start  -->
  <!--***************************************************************-->
  <PropertyGroup>
    <WebPublishPipelineCustomizeTargetFile Condition="'$(WebPublishPipelineCustomizeTargetFile)'==''">$(WebPublishPipelineProjectDirectory)\$(WebPublishPipelineProjectName).wpp.targets</WebPublishPipelineCustomizeTargetFile>
  </PropertyGroup>

  <Import Project="$(WebPublishPipelineCustomizeTargetFile)" Condition="Exists($(WebPublishPipelineCustomizeTargetFile))"/>

Here’s steps to create a customized target file to include some registry keys in the web package by using msdeploy’s regKey provider. (The link contains the functionality and limitation of regKey provider)

 

1. Create a file WebApplicationName.wpp.targets in the same folder as your web project (e.g. if the project file is WebApplication1.vbproj, then name the file WebApplication1.wpp.targets) with following content:

<!--********************************************************************-->
<!-- Task CollectRegKeysForPackage -->
<!-- RegKey reference: http://technet.microsoft.com/en-us/library/dd569085(WS.10).aspx -->
<!--********************************************************************-->
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <!--Targets get execute before this Target-->
    <OnBeforeCollectRegKeysForPackage Condition="'$(OnBeforeCollectRegKeysForPackage)'==''">
    </OnBeforeCollectRegKeysForPackage>
    <!--Targets get execute after this Target-->
    <OnAfterCollectRegKeysForPackage Condition="'$(OnAfterCollectRegKeysForPackage)'==''">
    </OnAfterCollectRegKeysForPackage>

    <CollectRegKeysForPackageDependsOn Condition="'$(CollectRegKeysForPackageDependsOn)'==''">
      $(OnBeforeCollectRegKeysForPackage);
      Build;
    </CollectRegKeysForPackageDependsOn>
  </PropertyGroup>

  <PropertyGroup>
    <IncludeRegKeyForMyProject Condition="'$(IncludeRegKeyForMyProject)'==''">False</IncludeRegKeyForMyProject>
    <MyRegKeyPath Condition="'$(MyRegKeyPath)'==''"></MyRegKeyPath>
    <AfterAddContentPathToSourceManifest Condition="'$(AfterAddContentPathToSourceManifest)'==''">
      $(AfterAddContentPathToSourceManifest);
      CollectRegKeysForPackage;
    </AfterAddContentPathToSourceManifest>
  </PropertyGroup>

  <ItemGroup>
    <MyRegkeys Include = "$(MyRegKeyPath)"/>
  </ItemGroup>

  <Target Name="CollectRegKeysForPackage"
          DependsOnTargets="$(CollectRegKeysForPackageDependsOn)"
          Condition="$(IncludeRegKeyForMyProject) AND '$(MyRegKeyPath)'!=''">

    <Message Text="Adding %(MyRegkeys.Identity)" />
    <ItemGroup>
      <MsDeploySourceManifest Include="regkey"
                                 Condition="$(IncludeRegKeyForMyProject)">
        <Path>%(MyRegkeys.Identity)</Path>
      </MsDeploySourceManifest>
    </ItemGroup>
    <CallTarget Targets="$(OnAfterCollectRegKeysForPackage)" RunEachTargetSeparately="false" />
  </Target>
</Project>

2. Package the project from command line using parameters such as the following to include multiple registry keys (seperated by ; sign) in the package.

msbuild WebApplication1.vbproj /target:package /p:IncludeRegKeyForMyProject=True;MyRegKeyPath="hkey_current_user\control panel\desktop\windowmetrics;hkey_current_user\control panel\desktop\colors"

In obj\debug\package\WebApplication1.SourceManifest.xml file, you should see two regkey providers are defined:

<?xml version="1.0" encoding="utf-8"?>
<sitemanifest>
  <regkey path="hkey_current_user\control panel\desktop\windowmetrics" />
  <regkey path="hkey_current_user\control panel\desktop\colors" />
  <IisApp path="D:\temp\WebApplication1\WebApplication1\obj\Debug\Package\PackageTmp" managedRuntimeVersion="v4.0" />
  <setAcl path="D:\temp\WebApplication1\WebApplication1\obj\Debug\Package\PackageTmp" setAclResourceType="Directory" />
  <setAcl path="D:\temp\WebApplication1\WebApplication1\obj\Debug\Package\PackageTmp" setAclUser="anonymousAuthenticationUser" setAclResourceType="Directory" />
</sitemanifest>

3. To proves it works, we change the hkey_current_user\control panel\desktop\windowmetrics\MenuWidth from –285 to –284, then we deploy the package locally from command line:

WebApplication1.deploy.cmd /y

4. We see the following line which showed that the corresponding registry is updated.

Info: Updating regValue (hkey_current_user\control panel\desktop\windowmetrics\MenuWidth).

5. Or we can import the package from IIS

image

After installation finishes, from its details tab, there are the following messages:

[2/9/2010 11:55:05 AM] Source regValue (hkey_current_user\control panel\desktop\windowmetrics\MenuWidth) does not match destination (hkey_current_user\control panel\desktop\windowmetrics\MenuWidth) differing in attributes (value['-285','-284']). Update pending.
[2/9/2010 11:55:05 AM] Source regValue (hkey_current_user\control panel\desktop\windowmetrics\MenuWidth) replaced with changed attributes (parameters) because of rule EnvironmentVariableNormalize.
[2/9/2010 11:55:05 AM] Updating regValue (hkey_current_user\control panel\desktop\windowmetrics\MenuWidth).

 

If you simply want to hardcode the registry keys for your project and don’t want to worry about more extensions, here’s a simplified version:

<!--********************************************************************-->
<!-- Task CollectRegKeysForPackage -->
<!-- RegKey reference: http://technet.microsoft.com/en-us/library/dd569085(WS.10).aspx -->
<!--********************************************************************-->
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <PropertyGroup>
    <!-- Extends the AfterAddContentPathToSourceManifest action do also collect registry keys-->
    <!-- Hard code -->
    <MyRegKeyPath Condition="'$(MyRegKeyPath)'==''">hkey_current_user\control panel\desktop\windowmetrics;hkey_current_user\control panel\desktop\colors</MyRegKeyPath>
    <AfterAddContentPathToSourceManifest Condition="'$(AfterAddContentPathToSourceManifest)'==''">
      $(AfterAddContentPathToSourceManifest);
      CollectRegKeysForPackage;
    </AfterAddContentPathToSourceManifest>
  </PropertyGroup>

  <ItemGroup>
    <MyRegkeys Include = "$(MyRegKeyPath)"/>
  </ItemGroup>
  
  <Target Name="CollectRegKeysForPackage" Condition="'$(MyRegKeyPath)'!=''">
    <Message Text="Adding %(MyRegkeys.Identity)" />
    <ItemGroup>
      <MsDeploySourceManifest Include="regkey">
        <Path>%(MyRegkeys.Identity)</Path>
      </MsDeploySourceManifest>
    </ItemGroup>
  </Target>
</Project>

Note: if you change an existing target file (this.wpp.targets).  You need to restart VS IDE to allow the target file cache to be unloaded and reloaded, in order for package/publish using the change.

Xinyang Qiu | Visual Web Devloper
Leave a Comment
  • Please add 1 and 3 and type the answer here:
  • Post
  • Do I need to expllicitly list the assemblies to download from GAC? I am wondering what the  need for the Registry key file is when all I want is for MSbuild to make certain it downloads the necessary files as it packages my application?

  • @Dollarjunkie, no you don't need to do these kind of things normally.  You should rely on NuGet packages these days instead of using GAC, these are especially true if you publish your project to a host that you don't have control of.

Page 1 of 1 (2 items)