How ClickOnce Manifest Generation works with MSBuild

Summary: Discusses how to build a ClickOnce application from the command-line outside of Visual Studio .NET using MSBuild. Also provides an overview of the manifest generation tasks and shows how to use them directly. This document assumes some familiarity with MSBuild and the structure of XML manifest files.

Note: This document was developed prior to the product's release to manufacturing, and as such, you may find inconsistencies with the details included here and those found in the shipping product. The information is based on the product at the time this document was created and should be used for planning purposes only. Information is subject to change at any time without prior notice. Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual property rights covering subject matter in this document. Except as expressly provided in any written license agreement from Microsoft, the furnishing of this document does not give you any license to these patents, trademarks, copyrights, or other intellectual property.

Building from the command-line is important for some customers to reproduce the build in an automated way, in a build lab for instance.

Should be familiar with MSBuild and ClickOnce publishing.

Introduction

A major new capability of Whidbey is the ability to build your projects outside of the Visual Studio 2005 IDE. In fact, all you need to build your projects is the .NET Framework, Visual Studio 2005 is not required strictly for building projects! This is a key capability for customers who need to be able to reproduce the build using an automated process. For instance, in a central build lab or using advanced scripting techniques beyond the scope of the project itself.

This document discusses the following topics. First, the basics of building from the command line a ClickOnce deployment using an existing project created with Visual Studio 2005. Next for those who wish to know what’s going on under the hood, an overview of MSBuild will be given focusing on how generating ClickOnce manifests are integrated into this system. Finally, the components that perform the manifest generation will be described in detail, along with a few additional samples demonstrating how to control them directly.

The next section discusses how manifests are actually generation within the MSBuild system. This is not required reading unless you have a need to interact with the MSBuild tasks for manifest generation directly, or if you are just interested in the lower level details.

Basics of command line build

Before we can demonstrate building from the command-line, we need  to create a project. Follow these steps to create a new project.

 

  1. Start Visual Studio 2005.
  2. Choose File, New Project to open the New Project dialog.
  3. Create a new Windows Application (Visual Basic or Visual C#) and name it “CmdLineDemo”.
  4. Choose the Build menu and select the Publish command.
  5. From the wizard, click on Finish.
  6. Save the project, and choose a folder if necessary.

 

Now that we have a project that we’ve published for the first time, let’s exit Visual Studio .NET and see if we can reproduce the build outside of the IDE.

 

  1. Exit Visual Studio 2005.
  2. Open a Visual Studio Command Prompt, click on Start, All Programs, Microsoft Visual Studio 2005 Beta, Visual Studio Tools, Visual Studio Command Prompt. This should open a command prompt in the root folder of the current user.
    image001.jpg
  3. Change the current directory to the location of the project you just built above.
    For example, type “chdir My Documents/Visual Studio/Projects/CmdLineDemo”.
  4. Type “msbuild /target:publish”.

 

This will produce a full ClickOnce application deployment in a sub-folder named “publish”.

 

image002.jpg

 

CmdLineDemo.application is the deployment manifest. The CmdLineDemo_1.0.0.0 folder contains files CmdLineDemo.exe and CmdLineDemo.exe.manifest, which is the ClickOnce application manifest. Setup.exe is the bootstrapper, which by default is configured to install the .NET Framework. The DotNetFX folder contains the redistributables for the .NET Framework. This is everything you need to deploy your application over the web or via UNC or CD/DVD!

So how is this “publish” folder produced? When you invoke “msbuild /target:publish” at the command line, it tells the MSBuild system to build the project and create a ClickOnce deployment in the “publish” folder. This is equivalent to selecting the Publish command in the IDE in step #4 above. Breaking this down, the “msbuild” part runs a program named “msbuild.exe” which is on the path in the Visual Studio command prompt environment. The “/target:publish” part tells MSBuild to invoke the “publish” target, which we’ll discuss in more detail shortly. Incidentally, the other interesting target is the “build” target, which simply builds your application. If you just wanted to build your project you can achieve that by typing “msbuild”. The “build” target is the default target for this project, so you don’t explicitly need to specify it. So typing “msbuild” or “msbuild /target:build” is equivalent to selecting the Build command in the IDE.

 In addition to invoking the “publish” target, there are several settings in your project that control how the ClickOnce deployment is generated within the “publish” target. It may be important to understand these details in order to properly manage your command-line builds. The next few sections discuss the various project settings that primarily influence publishing and ClickOnce manifest generation.

Other than the application itself, there are three factors which directly influence the ClickOnce application and the generated manifests. These factors are publishing properties, publishing item metadata, and the base app.manifest file.

Publishing properties

When you performed step #4 above the following properties were inserted into your project file.

 

CmdLineDemo.vbproj / CmdLineDemo.csproj

<GenerateManifests>true</GenerateManifests>

<PublishUrl>http://localhost/CmdLineDemo</PublishUrl>

<Install>true</Install>

<ApplicationVersion>1.0.0.*</ApplicationVersion>

<ApplicationRevision>1</ApplicationRevision>

<UpdateEnabled>true</UpdateEnabled>

<UpdateRequired>false</UpdateRequired>

<UpdateMode>Foreground</UpdateMode>

<UpdateInterval>7</UpdateInterval>

<UpdateIntervalUnits>Days</UpdateIntervalUnits>

<UpdateUrlEnabled>false</UpdateUrlEnabled>

<IsWebBootstrapper>true</IsWebBootstrapper>

<BootstrapperEnabled>true</BootstrapperEnabled>

These properties are controlled in the IDE from the Publish, Security, and Signing property pages of the application designer. Below is a description of the publishing properties, along with an indication of how each is set in the various property pages of the application designer.

GenerateManifests determines whether ClickOnce manifests are to be generated. This is set by the “Enable ClickOnce security settings” checkbox on the Security page.

The following properties are set on the Publish page.

PublishUrl is the location where the application will be published to in the IDE. It is inserted into the ClickOnce application manifest if neither the InstallUrl or UpdateUrl are specified. This is set by the “Publishing location” textbox on the Publish page.

ApplicationVersion specifies the version of the ClickOnce application. This is a four digit version number. If the last digit is a “*”, then the ApplicationRevision is substituted. This value is set by the “Major”, “Minor”, and “Build” textboxes on the Publish page.

ApplicationRevision specifies the revision . This is an integer increment each time you publish in the IDE. This value is set by the “Revision” textbox on the Publish page.

Install determines whether the application is an installed application, or a run-from-web application. This is set by the “online/offline” radio buttons on the Publish page.

InstallUrl (not shown) is the location where users will install the application from. If specified, this value is burned into the setup.exe bootstrapper if the IsWebBootstrapper property is enabled. It is also inserted into the application manifest if the UpdateUrl is not specified.

The following properties are set on the Application Updates dialog, accessed from the Publish page.

UpdateEnabled indicates whether the application should check for updates. This is set by the “check for updates” checkbox on the Update dialog, accessed from the Publish page.

UpdateMode specifies either Foreground updates or Background updates.

UpdateInterval specifies how frequently the application should check for updates.

UpdateIntervalUnits specifies the whether the UpdateInterval value is in units of hours, days, or weeks.

UpdateUrl (not shown) is the location from which the application will receive updates. If specified, this value is inserted into the application manifest. This value is set by the “Update location” textbox on Update dialog, accessed from the Publish page.

The following properties are set on the Prerequisites dialog, accessed from the Publish page.

BootstrapperEnabled determines whether or not to genereate the setup.exe bootstrapper.

IsWebBootstrapper determines whether the setup.exe bootstrapper works over the web or in disk based mode.

Why are there three URL’s? If you are publishing to a web URL, only PublishURL needs to be specified. You only need to specify the other URL’s if they are different from the PublishURL. In the IDE, you may want to publish to a different path from which your end-users to install. For example, you could set the PublishURL to an FTP path and set the InstallURL to a web URL. In this case, the PublishURL is only used in the IDE to transfer the files, but not used in the command-line builds. Finally, UpdateUrl can be used if you want to publish a ClickOnce application that updates itself from a separate location from which it is installed.

Incidentally, you can override any of these properties at the command line without altering the project file itself. For example, the following will build the ClickOnce application deployment without the bootstrapper.

msbuild /target:publish /property:BootstrapperEnabled=false

Publishing item metadata

In Visual Studio 2005 the Application Files dialog, accessed from the Publish page, allows you to customize how each file is published. For example, you can specify that certain files should not be published with the application. How this actually works

 

 

For example, you can specify that an .txt file is a data file, or What if you want to set certain files into a group, or set an assembly as a prerequisite? This is controlled with publishing attributes, which appear on various items in your project.

These attributes are set in Visual Studio 2005 on the File dialog, accessed from the Publish page. The Type setting allows you to control whether the file is included or excluded from the deployment. If excluded, a file will not be present in the publish folder and will not appear in the generated manifest. An additional setting for Type dependends on whether the item is a file (i.e. .xml, .mdf) or an assembly (i.e. .dll, .exe). For files there is an additional setting to flag a file as a data file. Flagging a file as a data file tells ClickOnce to migrate that file between multiple versions of your application. For assemblies there is an additional setting that to flag an assembly as a prerequisite. A prerequisite required by the application, but not deployed with it. The assembly will appear in the manifest and ClickOnce will insure it is installed in the Global Assembly Cache before allowing the application to be installed or run.

app.manifest

 

 

As you can see, any project designed in Visual Studio 2005 can be built and published at the command line using MSBuild. Even sophisticated multi-project solutions can be built in this manner. The only feature not supported at the command line is the ability to easily transfer your application to a web server or FTP server using FrontPage Server Extensions. However, you can compensate for this using batch files or other command line tools.

This is everything you need to know to get started building ClickOnce applications created in Visual Studio 2005 from the command-line. The next section discusses how manifests are actually generation within the MSBuild system. This is not required reading unless you have a need to interact with the MSBuild tasks for manifest generation directly, or if you are just interested in the lower level details.

How it works (Advanced)

How does it work? … diagram showing publishing properties, targets, and xmake tasks

Publish target depends on build target

Important for customers that build solutions that want to control the tasks directly, not leverage a Visual Studio project.

 

Overview of MSBuild

 

What is MSBuild?

XML based build engine

How does it relate to ClickOnce publishing?

Enables building projects outside the IDE, even without Visual Studio .NET installed!

All project build functionality is based on MSBuild.

Total parity between IDE and command-line builds.

No Venus

 

Show how to override properties from command-line, i.e. msbuild /target:publish /property:PublishUrl=foo

 

GenerateApplicationManifest Task

The GenerateApplicationManifest task generates a ClickOnce application manifest. A ClickOnce application manifest is an XML document that describes an application by providing a specification of its identity, all of its required dependencies and files, and the level of trust the application requires to run. All files are hashed and the manifest is signed in order to guarantee application integrity. This section includes a sample application manifest and follows with a description of task inputs that control how the manifest is generated.

Sample Application Manifest

This is a sample ClickOnce application manifest named “Sample.exe.manifest” that illustrates the characteristic output of the GenerateApplicationManifest task.

    <?xml version="1.0" encoding="utf-8"?>

    <asmv1:assembly

      xmlns="urn:schemas-microsoft-com:asm.v2"

      xmlns:asmv1="urn:schemas-microsoft-com:asm.v1"

      xmlns:asmv2="urn:schemas-microsoft-com:asm.v2"

      xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"

      manifestVersion="1.0" >

 

      <asmv1:assemblyIdentity

(1)     name="Sample.exe"

(2)     version="1.0.0.0"

(3)     publicKeyToken="3cb8aba78866dbbf"

(4)     language="neutral"

(5)     processorArchitecture="msil"

        type="win32" />

 

(6)   <description asmv2:iconFile="Sample.ico">

(7)     This is a sample.

      </description>

 

(7)   <trustInfo>

        <security>

          <applicationRequestMinimum>

            <PermissionSet Unrestricted="true" ID="FullTrust" />

            <defaultAssemblyRequest permissionSetReference="FullTrust" />

          </applicationRequestMinimum>

        </security>

      </trustInfo>

 

(8)   <entryPoint>

        <assemblyIdentity

          name="Sample"

          version="1.0.0.0"

          language="neutral"

          processorArchitecture="msil" />

          <commandLine file="Sample.exe" parameters="" />

      </entryPoint>

 

(9)   <dependency>

        <dependentAssembly codebase="Sample.exe" size="13312">

          <assemblyIdentity

            name="Sample"

            version="1.0.0.0"

            language="neutral"

            processorArchitecture="msil" />

          <hash>…</hash>

        </dependentAssembly>

      </dependency>

 

(10)  <dependency optional="true">

        <dependentAssembly

(11)      codebase="Foo.dll"

          size="16309"

(12)      group="MyData">

          <assemblyIdentity

            name="Foo"

            version="1.0.0.0"

            language="neutral"

            processorArchitecture="msil" />

          <hash>…</hash>

        </dependentAssembly>

      </dependency>

 

(13)  <dependency>

        <dependentAssembly prerequisite="true">

          <assemblyIdentity

            name="Bar"

            version="1.0.0.0"

            publicKeyToken="3cb8aba78866dbbf"

            language="neutral"

            processorArchitecture="msil" />

        </dependentAssembly>

      </dependency>

 

      <dependency>

        <dependentAssembly preRequisite="true">

          <assemblyIdentity

            name="Microsoft-Windows-CLRCoreComp"

(14)        version="2.0.3600.0" />

        </dependentAssembly>

      </dependency>

 

(15)  <file name="Sample.exe.config" size="1374">

        <hash>…</hash>

      </file>

 

(16)  <file name="Sample.ico" size="766">

        <hash>…</hash>

      </file>

 

(17)  <file

        name="Foo.mdf"

        size="148376

(18)    group="MyData"

(19)    optional="true"

(20)    writeableType="applicationData" >

        <hash>…</hash>

      </file>

 

(21)  <dsig:Signature Id="StrongNameSignature">…</dsig:Signature>

 

    </asmv1:assembly>

Task Inputs

The GenerateAplicationManifest task generates an application manifest according to the set of task inputs as described below. Note that some descriptions have numeric references to the sample above in order to more clearly illustrate the generated output.

AssemblyName specifies the name attribute of the assembly identity of the manifest. If not specified, then the value is obtained from the base manifest specified by the InputManifest input, or inferred from the value specified in the OutputManifest. This string is inserted into the name (1) attribute of the assemblyIdentity element.

AssemblyVersion specifies the version attribute for the assembly identity of the manifest. If not specified then the value is obtained from the base manifest specified by the InputManifest input or from the assembly specified in the EntryPoint input. This string is inserted into the version (2) attribute of the assemblyIdentity element.

CertificateFile specifies a key file for X509 certificate signing of the manifest. The item specification must be a relative or absolute path to a certificate (.cer) file. This input item causes the Signature (18) element to be generated. It also determines the publicKeyToken (3) attribute for the assembly identity of the manifest.

CertificatePassword specifies the password to use when certificate signing. It is required if CertificateFile is specified.

Dependencies specifies one or more application dependencies that are part of the application. These are additional .NET assemblies required by the main entry point assembly to be deployed along with the application. The item specification must be a relative or absolute path to a .NET assembly (.dll or .exe) file. Each input item will generate a separate dependency element (9, 10) in the manifest. Item metadata can be used to specify optional (10) and group (12) attributes, or to specify a codebase (11) attribute other than the default value inferred from the item specification.

Description specifies a description for the manifest. This string appears in the description element (6) of the manifest.

EntryPoint specifies a single item that determines the entry point of the application. This is the main program launched when the ClickOnce application is invoked from the deployment manifest or launched from the start menu. The item specification must be a relative or absolute path to a .NET assembly executable (.exe) file. Item metadata can be used to specify optional (10) and group (12) attributes, or to specify a codebase (11) attribute other than the default value inferred from the item specification.

FallbackCulture specifies

Files specifies one or more application files that are part of the application. These are additional loose files such as images, config files, or local databases to be deployed along with the application. The item specification must be a relative or absolute path to a file. Each input item will generate a separate file element (15, 16, 17) in the manifest. Use item metadata to specify optional (18), group (19), and writeableType (20) attributes, or to specify a name attribute other than the default value inferred from the item specification.

FXVersion specifies the version of the .NET Framework required by this application. This value determines the version attribute on the generated “Microsoft-Windows-CLRCoreComp” platform dependency.

IconFile specifies

InputManifest specifies a base manifest to the manifest generation process. The item specification must be a relative or absolute path to a manifest file. The only requirement is that the root element must be the assembly element in the asmv1 namespace. No additional attributes or sub-elements are required, so this can be thought of as a partial manifest template. In a Visual Studio .NET project, this is an optional hidden file called “app.manifest” which is inserted into a project whenever custom permissions are configured on the Security page. It is primarily used to specify the trustInfo element to define custom permission sets. However, additional custom attributes or sub-elements on the root assembly element can be defined. Custom attributes or sub-elements on file and dependency elements is not allowed, and will be dropped.

IsolatedComReferences specifies one or more COM components to be isolated. The item specification must be a relative or absolute path to a type-library file. This provides the ability to deploy COM components “registration free”. In a Visual Studio .NET project, any project references of type “ActiveX” with Isolated property set to True will be routed into this input.

KeyFile specifies a key file for strong-name signing of the manifest. The item specification must be a relative or absolute path to a key file, specifically either a strong-name key file ( .snk) or an encrypted strong-name key file (.pfx). This input item causes the Signature (18) element to be generated. It also determines the publicKeyToken (3) attribute for the assembly identity of the manifest.

NativeReferences specifies one or more native dependencies required by the application. These are additional Win32 assemblies required by the main entry point assembly to be deployed along with the application. The item specification must be a relative or absolute path to a native assembly (.dll or .manifest) file. Each input item will generate a separate dependency element in the manifest. However, these dependency elements are distinguished from other dependency elements in that they are generated in the asmv1 namespace, allowing the runtime to resolve native bindings such as “registration free” COM components. Item metadata can be used to specify optional (10) and group (12) attributes, or to specify a codebase (11) attribute other than the default value inferred from the item specification.

OSVersion specifies the minimum Windows platform version. For example, “5.1.2600.0” specifies that the application requires Windows XP, which is emitted by default if you are using “registration free”COM.

OutputManifest determines the name of the output manifest file. The item specification must be a relative or absolute file path. If not specified, then the path is inferred either from the identity defined in the base manifest specified by the InputManifest input, or from the filename specified in the EntryPoint input.

Platform specifies the processor architecture of the application. Valid values are

Prerequisites specifies one or more application dependencies required by the application. These are additional assemblies required by the main entry point assembly, but are not deployed with the application. Instead they are assumed to have been pre-deployed via a separate deployment mechanism such as MSI or SMS. However, they are specified here so that ClickOnce can verify their existance before application startup. The item specification must be either a relative or absolute path to a .NET assembly (.dll or .exe) file, or am assembly strong-name. Each input item will generate a separate dependency element (13) in the manifest, flagged with a prerequisite attribute.

Satellites specifies one or more satellite assemblies required by the application for the corresponding TargetCulture. These deployed along with the application. The item specification must be a relative or absolute path to a .NET satellite assembly (.dll) file. Each input item will generate a separate, optional dependency element in the manifest.

TargetCulture specifies the culture of the application. If not specified, culture neutral is the default.

TrustInfoFile specifies one or more trust licenses to insert into the manifest. The item specification must be a relative or absolute path to a trust license (.tlic) file. Trust licenses are created in a tool called “MAGE” and are primarily used in a corporate environment to allow applications to be deployed over a managed network.

 

GenerateDeploymentManifest

Sample.application

    <?xml version="1.0" encoding="utf-8"?>

    <asmv1:assembly

      xmlns="urn:schemas-microsoft-com:asm.v2"

      xmlns:asmv1="urn:schemas-microsoft-com:asm.v1"

      xmlns:asmv2="urn:schemas-microsoft-com:asm.v2"

      xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"

      manifestVersion="1.0" >

 

      <asmv1:assemblyIdentity

(1)     name="Sample.application"

(2)     version="1.0.0.0"

(3)     publicKeyToken="3cb8aba78866dbbf"

(4)     language="neutral"

(5)     processorArchitecture="msil" />

 

      <asmv1:description

(6)     asmv2:publisher="Microsoft"

(7)     asmv2:product="Sample" >

(8)     This is a sample

      </asmv1:description>

 

      <deployment install="true">

        <subscription>

          <update>

            <beforeApplicationStartup />

          </update>

        </subscription>

        <deploymentProvider codebase="http://myserver/Sample.application" />

      </deployment>

 

      <dependency>

        <dependentAssembly

          codebase="Sample_1.0.0.0/Sample.exe.manifest"

          size="3422">

          <assemblyIdentity

            name="Sample.exe"

            version="1.0.0.0"

            publicKeyToken="3cb8aba78866dbbf"

            language="neutral"

            processorArchitecture="msil" />

          <hash>…</hash>

        </dependentAssembly>

      </dependency>

      <dsig:Signature Id="StrongNameSignature">…</dsig:Signature>

 

    </asmv1:assembly>

發佈了156 篇原創文章 · 獲贊 0 · 訪問量 28萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章