You are on page 1of 66

ClickOnce Deployment Overview

ClickOnce Overview
ClickOnce is a smart client deployment mechanism that is part of the .NET Framework 2.0. ClickOnce enables automatic deployment and update of smart client applications over the network from a deployment server. Using ClickOnce, you can take advantage of the capabilities of smart client applications and have the ease of maintenance and update of server-based applications. To deploy or update a ClickOnce deployed application, you only need to publish your application to a deployment server and provide a link to the application to your users. When a user launches the application through the link, the application is automatically deployed and cached on the client computer; then it launches and runs from there. ClickOnce supports many options, including the following: HTTP, UNC, or CD/DVD can be used for deployment. A URL or the Start menu can be used to launch the application. The application can be used online-only or online and offline. Updates can be checked for and applied at times you designate. Updates can be obtained from the location you specify. Updates can be mandatory or optional. A programmatic API can be used to explicitly control the update process.

ClickOnce Deployment Modes


ClickOnce supports two deployment modes: installed and online-only. The installed mode (available offline and online) supports the use of the application on the client computer even if the client computer is offline with respect to the deployment server. Installed applications allow the user to launch the application with a Start menu shortcut created when the application is first deployed to the client computer. Online-only applications must be launched through a URL to the deployment manifest on the server every time they are used; therefore, the client computer must be able to connect to the deployment server to run the application. The ability to operate offline with respect to the deployment server is unrelated to the application's ability or inability to operate offline with respect to the back-end services the application is designed to communicate with for normal operations. Other forms of connectivity checking will need to be used to determine whether the application can communicate with its back-end services after application launch.

ClickOnce Update Options


ClickOnce supports both automatic updates and programmatic updates. The automatic updates are done by the ClickOnce runtime on the client computer before or after the

application starts, and a number of options are supported. Programmatic updates are done through the ApplicationDeployment class in the System.Deployment.Application namespace. For an example of using the ApplicationDeployment class, see the AppraiserWorkbench sample application in the Smart Client Software Factory. For more information, see "How to: Add On-Demand Updates to the BankBranchWorkbench Application." The options for automatic updates include the following: Checking for updates before the application starts, after the application starts, or both Making an update optional or required Checking for updates on a scheduled basis Checking for updates in a location different from the original installation

ClickOnce automatic updating downloads an update as soon as it is available on the server and applies the update the next time the application runs. As a result, if you want to delay the application of an update after it is on an update server, you will have do one of two things: Use the ClickOnce programmatic API to detect when the update is available, and delay programmatically downloading the update until your delay criteria is met (possibly by checking a remote service that tells the application when to update). Use a dynamic loading mechanism, such as the Composite UI Application Block profile catalog, to determine when to load and start using a file. ClickOnce can download updates immediately when they are available, but the profile catalog determines when those updates are applied. For more information, see "How to: Apply New Module Updates at a Future Time in a Composite UI Application Block Application."

ClickOnce Publishing Process


The first step in ClickOnce deployment is publishing the application. This means placing the application files on the deployment server and generating two manifest files associated with a ClickOnce publication: the deployment manifest and the application manifest. The deployment manifest contains information about the publication, including the deployment provider URL, which indicates where the application will be launched from, the update policy, and a reference to the application manifest. The application manifest contains the list of files that the application is composed of and the set of permissions required to run the application. You can publish ClickOnce applications from Visual Studio 2005 using an SDK tool named the Manifest Generating and Editing tool (Mage) or a custom tool that uses the ClickOnce publishing APIs. Visual Studio exposes most of the capabilities needed for ClickOnce publishing. However, Visual Studio may not be available or desired for IT administrators who manage ClickOnce deployments on the server. Mage is designed to address most common administrative tasks for ClickOnce and is a lightweight .NET Framework Windows-based application that can be given to your administrators. However, Mage requires too many very detailed steps, performed in the correct order, for common tasks such as modifying the application files listed in the application manifest. To make these tasks simpler, a custom utility is needed. The Manifest Manager Utility sample utility included with this community resource kit demonstrates how to use the ClickOnce publishing API to manage deployment and

application manifests in a simpler way. This tool is used for updating application manifest file lists and deployment manifest settings in automated procedures for the How-to topics in this community resource kit. Figure 1 illustrates the typical structure for a ClickOnce application publication. It includes a root folder for the application, which contains the default deployment manifest (.application file). A subfolder is created for each version of the application that is published, and that folder contains the application manifest (.manifest file) for that version in addition to all the application files (suffixed with a .deploy file name extension). The default deployment manifest is updated to point to the application manifest for the most recent version published when you publish from Visual Studio. Visual Studio also generates version-specific deployment manifests in the root folder for each version published; each deployment manifest points to its respective application manifest. This allows you to easily perform a server-side rollback of the application to a previous version by simply replacing the default deployment manifest with one of the version specific deployment manifests. Additionally, Visual Studio generates a Setup.exe file for the bootstrapping application and a Publish.htm test deployment page in the root folder when it publishes.

Figure 1 ClickOnce publish folder structure If you manually generate or update a ClickOnce application publication using either Mage or a custom tool, you are not constrained to this folder and file structure. For any particular ClickOnce publication, the chain of dependencies includes the following: A deployment manifest that points to itself or another deployment manifest through the embedded deployment provider URL (ClickOnce supports a one-hop redirect through this URL). A deployment manifest that points to the application manifest through an embedded code base URL. An application manifest that contains relative paths to each of the application files. These files must reside in the same folder or a subfolder from where the application manifest resides. The application files themselves, usually with a .deploy file name extension appended to the file name to simplify mapping these files to MIME types on the deployment server. ClickOnce automatically strips off the .deploy file name extension on the client side after the file is downloaded.

Publishing Scenarios
There are several publishing scenarios that are often encountered with an automatic deployment mechanism such as ClickOnce. These scenarios include the following:

Broadcast deployment. A new version is placed on the deployment server and everyone starts downloading it in the same time frame immediately after it is published. This is the default approach of ClickOnce, but it can pose scalability challenges for large organizations. For more information about handling the server load for this scenario, see "Handling High Deployment Server Load." Adopting the staged deployment or future deployment strategies can also help alleviate this scalability problem. Staged deployment. A new version is placed on the deployment server, but different groups are expected to download the update at different times. For example, in a bank branch scenario, Branch A may be expected to do its updates on Monday, Branch B on Tuesday, Branch C on Wednesday, and so on. This would require each branch to use a different launch URL for its application so that separate physical installations are present on the client computer. Future deployment. A new version is available, but it needs to be applied at a specific point in the future. For example, you may want all client computers to start using the new version at 9:00 A.M. Monday morning when the new server components that the client computer will communicate with are activated. In this case, you will need to allow client computers to download and cache the new software version ahead of time so that the switch to the new version can be done at a specific time that is not affected by deployment server loading. For more information, see "How to: Apply New Module Updates at a Future Time in a Composite UI Application Block Application."

ClickOnce Deployment Architecture


ClickOnce treats each published version of an application as an atomic unit. That publication consists of the deployment manifest, application manifest, and all the application files for that version. The publish version is specified through the deployment manifest, and each deployment manifest refers to a single application manifest and its associated collection of application files. The client computer must have the .NET Framework 2.0 installed to do a ClickOnce deployment to that computer. The .NET Framework can be deployed a variety of ways, including Windows Update, Microsoft Systems Management Server, or the ClickOnce Bootstrapper. The only specific platform requirement on the server side is the ability to return the manifests and application files with the appropriate MIME types. To understand where everything goes in a ClickOnce deployment, it is best to perform the steps of a deployment and update from an architecture view. When a ClickOnce application is first published, the files are placed on the deployment server and the deployment manifest refers to the most recently published version. At this point, no changes have been made to the client computer (see Figure 1).

Figure 1 After publishing, before deployment After the user clicks a link to the deployment manifest, the initial deployment of the application occurs and the application files are copied to the client computer under the user's profile. If the application is deployed as an installed application, a Start menu shortcut is added and an Add or Remove Programs item is added. The application launches, and the user interacts with the application as a locally installed smart client application (see Figure 2). The user can continue to use the application by launching it from the Start menu shortcut.

Figure 2 After initial ClickOnce deployment At some point in the future, an update is published to the deployment server. The earlier version of the application may or may not be removed from the deployment server at that time. The default deployment manifest for the application is updated to point to the new version of the application (see Figure 3).

Figure 3 New version published to server With the default ClickOnce update settings, the next time the user launches the application on the client computer, the ClickOnce runtime on the client computer detects that a new version is available on the server. A new version is created under the user's profile on the client computer, and the application files for the new version are copied into that folder. If a file from the previous version is unchanged between versions (determined by a hash of the file placed in the application manifest), it is copied locally on the client computer from the previous version's cache folder. If a file has changed or is new, it is downloaded from the server and cached in the new version's cache folder under the user's profile. The Start menu shortcut is updated, and the new version of the application is launched on the client computer (see Figure 4).

Figure 4 Update detected and deployed to client computer Note that the previous version is not removed from the client computer when a new version is installed. This allows the user to roll back to the previous version through Add or Remove Programs if the Minimum Required Version property is not set in the new version by the publisher. ClickOnce keeps only one previous version cached on the client computer for installed applications.

Deploying for Multiple Groups


A common requirement is to have different application functionality exposed to different sets of users based on their roles. The roles may be based on functional roles, such as customer, teller, and branch manager, where you want to expose distinctly different functionality to each role. The roles may also be based on some other type of group distinction, such as end users, beta testers, Q&A, and developers, where each role sees roughly the same functionality, but each role actually executes a different code base to get that functionality. For the purposes of this guidance, a division that requires different users to execute different code bases is considered to be a group. With the role-based security in the .NET Framework, you can determine a user's role at run time to change the behavior of the application based on role. For example, as your form loads, you can check to see if the user is a branch manager, and the user is not a branch manager, certain options on the screen can be made unavailable. When using the Composite UI Application Block, you can set roles for different modules in the profile catalog and use that to determine which modules are available to each role. Between these two capabilities, it is straightforward to handle requirements for role-based modification of application behavior on a single code base. ClickOnce can be used to provide different code bases for different groups. A single user may be part of a single group or multiple groups, and if a user is part of multiple groups, the user needs to be able to run multiple versions of the application on the same computer at the same time. An example of this is a developer or tester who wants to be able to run both the beta version of an application and the production version of the same application side by side to compare functionality or features. To meet this requirement, you can publish multiple versions of your application to the deployment server and direct users in different groups to the appropriate deployment manifest for the version that you want them to run. The different versions can even share some files on the server side if desired. For more information, see "How to: Share Application Files Across Multiple Application Versions." Usually in ClickOnce, when you publish a new version of your application, the default deployment manifest is overwritten with the new version's deployment manifest, and there is no way for client computers to deploy and run the earlier version from the server. If the application is configured to check for updates, the client computer will detect the new version and will be updated the next time it runs if it has connectivity to the deployment server. In fact, the installation engine in ClickOnce also uses the deployment manifest name to help distinguish individual applications. This means that even if you publish two different versions of your application to two different URLs, you will not be able to run them as separate applications on the same computer from the same user account unless they have a different deployment manifest name. When the second application is deployed to the client computer, it overwrites the deployment information for the first application if the deployment is signed with the same publisher certificate and has the same deployment manifest name. As a result, the usual versioning behavior of ClickOnce is not sufficient for you to execute more than one version of an application on your computer at any one time. When you publish multiple versions of your application to target multiple groups, you have to distinguish them with different deployment manifests, with each having a unique deployment manifest name. The different versions of the application do not necessarily have to be distinguished by version numbers, although they should, and they can be placed in the same folder on the deployment server if desired. Because the deployment manifests have unique names, the URLs to them will be different, so the client computer

will see the different versions as separate and distinct applications and will install both versions of the application on the client computer and allow them to run side by side. Unfortunately, Visual Studio does not provide control over the deployment manifest name that is generated, so you will have to use Mage or a custom tool to modify the manifests after publishing from Visual Studio. For more information about how to support multiple user groups using deployment manifest naming, see "How to: Publish Different Versions of the Same Application for Two Different Groups."

Handling High Deployment Server Load


For low-to-moderate load scenarios, you will probably publish your applications to a single deployment server and provide your users with the link to the deployment manifest. However, if you are part of a large organization, this can cause problems when it is time to roll out new applications or updates. If you release an update and thousands of workers come in to work first thing in the morning and start trying to download that update, two things will happen. The first is that the deployment server may be put under a tremendous load, depending on the size of the update and number of users. The second is that it could take a very long time for the application to download the update and launch for each user if you are doing automatic updates before the application starts (this is the default behavior). There are several ways to address this issue: Network load balancing. You could place the ClickOnce publication on several identically configured servers with the same network address and it would be transparent to the users and to the ClickOnce addressing that the load is distributed across multiple servers. This would address both initial deployment and updates. Publish to multiple servers. You could publish the application to more than one server and have different parts of the organization download and launch the application from different physical addresses to manually distribute the load. This would address both initial deployment and updates. This would also address the staged deployment scenario discussed earlier. Download updates in the background. You could use the ClickOnce programmatic API to check for updates and download them on a background thread. This would not reduce the load on the server, but it would make it so the users do not have to wait for the update to occur before launching the application. This would only address updates; it would not help with initial deployment of new applications. Download updates in the background on a random/variable schedule. You could use the ClickOnce programmatic API to check for updates and download them in the background, but have the checks and downloads happen at different times for different client computers. This could be done with a random wait period in the update code or a remote scheduling service that the client computer calls out to before trying to check for downloads. This would address only updates, not initial deployment, but it would also reduce the load on the server.

For more information, see "How to: Share Application Files Across Multiple Application Versions" and "How to: Implement a Custom ClickOnce Deployment Server File Repository."

Implementing a Custom ClickOnce Server File Repository


When a ClickOnce application is launched, the ClickOnce runtime on the client computer issues a series of file requests to the deployment server to download the files that are required to install and run the application. The requested files include the deployment manifest, application manifest, and each of the application files (which are typically stored on the server with a .deploy file name extension). ClickOnce first requests the deployment manifest and obtains the URL to the application manifest from that file. Then it requests the application manifest and obtains the relative paths of each of the application files from that manifest. It then requests each application file based on that relative path from the location of the application manifest on the server. You can deploy ClickOnce applications using HTTP or a UNC file path. Using a UNC file path only works on the intranet, and the file transfer from the deployment server to the client computer is simply a file copy performed by the operating system. As a result, there is no real opportunity to intercept the file request on the server and to modify or control the file transfer process. However, when you choose to deploy your application over HTTP, you have more options and opportunities to control the process. The HTTP requests will be serviced by your Web server, and you can intercept the incoming file requests and obtain the files or modify them as needed before streaming back the files in the response message. For simple scenarios, you will just publish the ClickOnce files to the Web server under a virtual directory as described in the other ClickOnce publishing topics in the Smart Client Software Factory. However, for more advanced scenarios, you may not want to store the manifests and application files on the server in the usual way. You may want to store the files in a database, dynamically retrieve them from a remote location, or dynamically generate the files. Using HTTP deployment, you can do these things by intercepting the file requests on the Web server and then dynamically obtaining the file streams from whatever location is appropriate for your requirements. To do this in ASP.NET, you could use either an HTTP module or handler. Because the files themselves represent the endpoint of a request, a handler is more appropriate. For information about the steps to perform for this approach, see "How to: Implement a Custom ClickOnce Deployment Server File Repository."

Deployment Activities
You can use Visual Studio to publish an application with a single step. When Visual Studio publishes an application, it includes project files and references that have been configured as application files on the Publish tab of the project properties page. By default, this includes the application executable, configuration file, any referenced libraries, and project files that have the Build Action property set to Content. This means that if your application depends on other libraries or files that it dynamically loads, they will not be published with your application if they are not part of your project. For example, with Composite UI Application Block applications, you usually do not reference modules that will deploy with the shell because the shell is designed to be decoupled from the modules that will load into it at run time. As a result, you need a way to include your modules and any other dynamic dependencies into the ClickOnce publication.

The .NET Framework 2.0 SDK includes the manifest tools Mageui.exe (Windows UI application) and Mage.exe (command line tool). These tools are collectively referred to as Mage. With these tools, you can create manifests or modify manifests after they are published from Visual Studio. With Mage, you can access most, but not all, of the content of a manifest. For example, you can use Mage to add all application files from a single folder, but you cannot add multiple files from different paths. Mage does not support all the publishing scenarios addressed in this document. Specifically, it does not allow you to add application files that reside in different folders, even though the ClickOnce deployment mechanisms in the .NET Framework runtime do support deploying application files residing in different folders on the server. Mage also has the disadvantage that, because of its low level access to individual settings in individual manifests, it makes common publishing scenarios more complex than they need to be. The Manifest Manager Utility is a custom utility that supports all the scenarios in this document with a more automated approach. This utility uses the API exposed through the Microsoft.Build.Tasks.Deployment namespace. You can consult the code for the Manifest Manager Utility in this package as an example of how to use that API to obtain low level and full access to the manifest manipulation API. The key classes used in this utility are the ManifestReader, ManifestWriter, DeploymentManifest, ApplicationManifest, and X509Certificate2 classes. This section describes activities that developers perform when publishing and deploying smart client applications with ClickOnce. Where appropriate, the activities are described using both the Manifest Manager Utility (automated) and Mage (manual) so that you can see the steps the utility automates. To use ClickOnce deployment, you must have an application that is ready to deploy. The following How-to topics use the Bank Branch Client reference implementation as the application that is being deployed: "How to: Publish an Initial Version of a Composite UI Application Block Application" "How to: Deploy an Initial Version of a Composite UI Application Block Application" "How to: Publish an Updated Version of a Composite UI Application Block Application" "How to: Deploy an Updated Version of a Composite UI Application Block Application" "How to: Move an Application to a Different Server" "How to: Add On-Demand Programmatic Update to an Application" "How to: Publish Two Different Versions of an Application for Two Different Groups" "How to: Restrict Access to Different Versions Based on User Role" "How to: Apply New Module Updates at a Future Time in a Composite UI Application Block Application"

How to: Publish an Initial Version of a Composite UI Application Block Application


To use ClickOnce for deployment, you must first publish the initial version of the application and have users launch it through a link to the deployment manifest. With a simple Windows Forms application, this can be done by publishing from Visual Studio. With a Composite UI Application Block application that dynamically loads modules not referenced in the Visual Studio shell project, you have to perform some extra steps to prepare the published application for deployment. To publish an initial version of a Composite UI Application Block application with the Manifest Manager Utility 1. In Visual Studio, publish the shell application. 2. Open the Manifest Manager Utility, and then open the deployment manifest. 3. Select the additional files you need to add to the application. 4. Save the manifests. 5. Provide your users with a URL to the deployment manifest. For more information about this procedure, see "Automated: Publishing an Initial Version of a Composite UI Application Block Application with the Manifest Manager Utility." To manually publish an initial version of a Composite UI Application Block application 1. In Visual Studio, publish the shell application. 2. Copy the modules that will be dynamically loaded into the shell to the publish folder, and then add .deploy file name extensions to them. 3. Run Mageui.exe and update the application manifest to include the modules and any associated file resources. 4. Save and sign the application manifest. 5. In Mage, open the deployment manifest, and then refresh the application manifest reference. 6. Save and sign the deployment manifest. 7. Provide a URL to the deployment manifest to your users. For more information about this procedure, see "Manual: Publishing an Initial Version of a Composite UI Application Block Application with Mage."

Automated: Publishing an Initial Version of a Composite UI Application

Block Application with Manifest Manager Utility


Prerequisites
This topic requires the following: The Smart Client Software Factory must be installed. Internet Information Services (IIS) must be installed. The ManifestManagerUtility solution must be built. The BankBranchWorkbench reference implementation solution must be built.

Applies To
The procedures in this topic apply to Composite UI Application Block applications that will be deployed through ClickOnce and that have modules that will be loaded through the profile catalog.

Steps
To publish the application from Visual Studio 1. Expand the Infrastructure solution folder. 2. Right-click Shell, and then click Publish. 3. Click Finish to accept the default settings. The project will be built and published to the location set on the Publish tab of the project properties page (http://localhost/GlobalBank.Shell/). To add the additional modules using the Manifest Manager Utility 1. Run the ManifestManagerUtility.exe utility. 2. On the File menu, click Open. 3. Browse to and select the published deployment manifest (C:\Inetpub\wwwroot\GlobalBank.Shell\GlobalBank.Shell.application). The commonly modified values from the deployment manifest and the list of files from the referenced application manifest will be loaded into the utility (see Figure 1).

Figure 1 Manifest Manager Utility 4. On the Edit menu, click Add Files. 5. Navigate to the build output folder for the BankBranchWorkbench solution (C:\Program Files\Microsoft SCSF\bin\Debug). 6. In the Add Application Files dialog box, select the following files to add them to the application manifest (see Figure 2), and then click Open: BasicAccounts.ServiceProxies.dll GlobalBank.BasicAccounts.Interface.dll GlobalBank.BasicAccounts.Module.dll GlobalBank.BranchSystems.Interface.dll GlobalBank.BranchSystems.Layout.dll GlobalBank.BranchSystems.Module.dll GlobalBank.BranchSystems.ServiceProxies.dll GlobalBank.Infrastructure.Module.dll Microsoft.Practices.EnterpriseLibrary.Caching.dll

Figure 2 Add Application Files dialog box 7. On the File menu, click Save. 8. In the Select Publisher Certificate to Sign Manifest dialog box, click Browse, and then navigate to the publisher certificate that was generated by Visual Studio when you first published the application (C:\Program Files\Microsoft SCSF\BankTellerWorkbench\Source\Src\Infrastructure\Shell\Shell_TemporaryKey.pfx ). Figure 3 illustrates this dialog box.

Figure 3 Manifest signing dialog box 9. Click Save and Sign.

Outcome
The published GlobalBank.Shell application is ready for users to launch. In this case, you would provide them with a link to http://<yourmachinename>/GlobalBank.Shell/GlobalBank.Shell.application. The downloaded application will include the Composite UI Application Block modules that are dynamically loaded based on the profile catalog.

Related Guidance
For the manual approach to publishing the application using the SDK Mage tool, see "Manual: Publishing an Initial Version of a Composite UI Application Block Application with Mage."

Manual: Publishing an Initial Version of a Composite UI Application Block Application with Mage
This topic describes how to publish an initial version of a Composite UI Application Block application using the .NET Framework 2.0 SDK Mage tool.

Preparation
This topic requires the following: The Smart Client Software Factory must be installed. Internet Information Services (IIS) must be installed. The BankBranchWorkbench reference implementation solution must be built.

Summary of Steps
You will publish the Bank Branch client application with the following steps: 1. In Visual Studio, publish the Shell application. 2. Copy the additional module files to the publish directory, and then add .deploy file name extensions to them. 3. Update the application manifest using Mage. 4. Update the deployment manifest using Mage.

Outcome
The Bank Branch client application will be ready to deploy through ClickOnce. You will be able to provide a link to the deployment manifest to your users and they will be able to click the link to download and launch the application on their computer.

Related Guidance
For the steps to accomplish the deployment of the application after it is published, see "How to: Deploy an Initial Version of a Composite UI Application Block Application."

Manual Steps
You first need to publish the Shell application from Visual Studio to generate the manifests and to publish the application outputs as application files. To publish the Shell Application from Visual Studio 1. Expand the Infrastructure solution folder. 2. Right-click Shell, and then click Publish. 3. Click Finish in the Publish Wizard to accept the default settings.

The project will be built and published to the location set on the Publish tab of the project properties page (http://localhost/GlobalBank.Shell/). To copy the additional module files to the publish folder Copy the following files from the build output folder (C:\Program Files\Microsoft SCSF\bin\Debug) to the application files publish folder (C:\Inetpub\wwwroot\GlobalBank.Shell\GlobalBank.Shell_1_0_0_0): BasicAccounts.ServiceProxies.dll GlobalBank.BasicAccounts.Interface.dll GlobalBank.BasicAccounts.Module.dll GlobalBank.BranchSystems.Interface.dll GlobalBank.BranchSystems.Layout.dll GlobalBank.BranchSystems.Module.dll GlobalBank.BranchSystems.ServiceProxies.dll GlobalBank.Infrastructure.Module.dll Microsoft.Practices.EnterpriseLibrary.Caching.dll

To update the application manifest with Mage 1. Open a Visual Studio 2005 command prompt, type mage, and then press ENTER. 2. On the Mage toolbar, click Open a manifest file. 3. In the published application files folder (C:\Inetpub\wwwroot\GlobalBank.Shell\GlobalBank.Shell_1_0_0_0), click the application manifest (GlobalBank.Shell.exe.manifest), and then click Open. 4. In the left pane, click Files. 5. Click the Populate button (see Figure 1).

Figure 1 Mage application manifest files 6. In the This will permanently rename files dialog box, click OK. 7. On the File menu, click Save. 8. In the Signing Options dialog box, click the ellipsis button (...), navigate to the publisher certificate that was generated by Visual Studio when you first published from there (C:\Program Files\Microsoft

SCSF\BankTellerWorkbench\Source\Src\Infrastructure\Shell\Shell_TemporaryKey.pfx ), and then click it. 9. Click OK to save and sign the manifest. To update the deployment manifest with Mage 1. On the Mage toolbar, click Open a manifest file. 2. Navigate to the root publish folder (C:\Inetpub\wwwroot\GlobalBank.Shell), and then click GlobalBank.Shell.application. 3. In the left pane, click Application Reference (see Figure 2).

Figure 2 Mage deployment manifest application reference 4. In the right pane, click Select Manifest, navigate to the GlobalBank.Shell_1_0_0_0 subfolder of the publish folder, and then click GlobalBank.Shell.exe.manifest. 5. In the main Mage window, click Save. 6. Click the ellipsis button (...), and then select the same publisher certificate (.pfx file) as you did in the previous procedure. 7. In the Signing Options dialog box, click OK. 8. Close Mage.

How to: Deploy an Initial Version of a Composite UI Application Block Application


After an application is properly published to a deployment server, it is ready to deploy. You (as a user) deploy a ClickOnce application to a client computer by clicking the link that was provided to you by the publisher. For this activity, you will treat your development computer as the client computer, in addition to it being the deployment server. To complete this topic, you will need to have

completed the automated or manual procedures of the topic "How to: Publish an Initial Version of a Composite UI Application Block Application." This procedure will deploy and run the Bank Branch client application on your computer through ClickOnce. For the Bank Branch client application to run correctly, you have to have the Web services running that it calls at run time. This procedure also demonstrates that there is no functionality in the initial version for viewing credit card account information because the initial version published did not include the CreditCardModule. That module will be deployed as part of the procedure, "How to: Publish an Updated Version of a ClickOnce Application." To deploy an initial version of an application to a client computer 1. Start the services that the application calls at run time. 2. Click the link provided to you for launching the application. 3. Accept the security warning prompt to install the application. 4. Log on to the application and check the functionality. For more information about this procedure, see "Automated: Deploy an Initial Version of a ClickOnce Application."

Automated: Deploy an Initial Version of a ClickOnce Application


Prerequisites
This topic requires the following: Either the automated or manual procedures in "How to: Publish an Initial Version of a Composite UI Application Block Application" must be completed. The GlobalBank database using the GlobalBank.sql script in the C:\Program Files\Microsoft SCSF\BankTellerWorkbench\Source folder must be installed. The BankBranchWorkbench reference implementation solution in Visual Studio must be open.

Applies To
The procedures in this topic apply to any application that is deployed through ClickOnce.

Steps
The first two procedures are required for the BankBranchWorkbench reference implementation because it requires connectivity to its Web services at run time. It uses the ProfileCatalogServices Web service to determine the modules to load at run time and the GlobalBankServices Web service to access the back-end data for the application. Because the initial version of the application that was published did not include the CreditCardModule, you need to remove some information from the ProfileCatalog.xml

file used by the ProfileCatalogServices Web service to determine the modules to dynamically load by the Bank Branch client application at run time. To remove the credit card module from the initial version of the application 1. In the solution, expand ProfileCatalogServices. 2. Double-click the ProfileCatalog.xml file in that solution to open it in the editor. 3. Locate the last ModuleInfo element in that file, which contains the module information for the CreditCardAccounts module, and remove that element.
<!--<ModuleInfo AssemblyFile="GlobalBank.CreditCardAccounts.Module.dll"> <Roles> <Role Allow="Officer"/> <Role Allow="BranchManager"/> </Roles> </ModuleInfo>-->

4. Save and close the file. The default URLs used by the Bank Branch client application use the ports assigned for running the Web services through the ASP.NET Development Server in Visual Studio 2005. As a result, the development server instances must be running before you attempt to launch the application with ClickOnce. To run the BankBranchWorkbench solution Web services through the debugger 1. Build the solution. 2. On the Debug menu, click Start Debugging to start a debug session. In addition to starting the client application, this also starts two instances of the ASP.NET Development Server for the two Web services. 3. In the Authentication dialog box, click Cancel. 4. When the authentication exception is thrown in the debugger, click Stop Debugging on the Debug menu. Do not close Visual Studio. The ASP.NET Development Server instances continue to run until Visual Studio is closed. To deploy and launch the application through ClickOnce 1. Open Internet Explorer. 2. In the Address box, type the address of the deployment manifest (http://localhost/GlobalBank.Shell/GlobalBank.Shell.application), and then press ENTER. The ClickOnce launch will begin and you will see the launch dialog shown in Figure 1.

Figure 1 ClickOnce Launch Dialog 3. In the Application Install - Security Warning dialog box, click Install. By default the security permissions for a ClickOnce publication are set to request Full Trust for the application, which is more than the launch zone (Local Intranet in this case) would grant.

Figure 2 ClickOnce Security Warning Dialog 4. Click Install to elevate the permissions for the application to Full Trust. The application downloads to the client machine from the deployment server and a progress dialog is presented while the files are downloading (see Figure 3).

Figure 3 Download Progress Dialog 5. To confirm the functionality of the application and the absence of credit card module functionality, perform the steps in Manual: Check for Credit Card Module Functionality. 6. Close the application. To run the application from the start menu On the taskbar, click Start, point to All Programs, look for a group named the same as the company that is set for your computer (the company shown in the splash screen when you start Visual Studio under your name), and then click GlobalBank.Shell.

After ClickOnce checks the server to see if there are any updates available on the deployment server, the application launches from the locally cached version.

Outcome
You have a ClickOnce deployed version of the Bank Branch client application installed on your computer. You can run this application at any time by clicking the shortcut for it on the Start menu. You can remove the application using Add or Remove Programs. The Web services will need to be running on the appropriate port to avoid application failure because it is designed to be run online only. However, you could configure the Web services under Internet Information Services (IIS) as a virtual directory and modify the URLs used by the application and it would work out as well.

Related Guidance
For information about launching the application when an update is available on the server, see "How to: Deploy an Updated Version of a Composite UI Application Block Application."

Manual: Check for Credit Card Module Functionality


Preparation
To perform the steps in this procedure, you should first have completed one of the following procedures: "How to: Deploy an Initial Version of a Composite UI Application Block Application" "How to: Deploy an Updated Version of a Composite UI Application Block Application."

Summary of Steps
In this procedure, you exercise the functionality of the Bank Branch client application to check whether Credit Card Module functionality is available. You will do the following: 1. Launch the Bank Branch client application. 2. Find a customer in the database. 3. Add the customer to the service queue. 4. Open the customer details. 5. Try to view credit card account details.

Outcome
If the credit card module has not yet been deployed, nothing happens when you doubleclick a credit card account in the customer details. If the credit card module has been successfully deployed, a new view will be presented when you double-click a credit card account that represents the credit card module's view.

Related Guidance
None.

Manual Steps
Perform the following procedure to confirm that the application is working correctly. To confirm application functionality

1. Launch the application through either an initial ClickOnce deployment or from the Start menu. 2. In the User Authentication dialog box, type Spike in the User Name box, type Password3 in the Password box, and then click OK. If you see a dialog box that indicates there has been a problem, the possible reasons for it are: All required files were not included when the application was published. Web services are not running to answer calls from the client application. The CreditCardModule information in the ProfileCatalog.xml file has not been commented out (as described in the first procedure of this topic).

3. In the main window of the Bank Branch client application, click Manage the customer queue. 4. In the Customer Queue pane, click the Find Customer link (see Figure 1).

Figure 1 Customer queue management 5. In the Find Customer dialog box, type Leonids in the First Name box, and then click Find. 6. In the Find Customer Results dialog box (which shows the matching customer), click Queue for Service. 7. In the Add Reason/Add To Queue dialog box, click any option in the Reason Code drop-down combo box, and then click OK. The customer you selected appears under My Customers view in the main window. 8. Double-click the name of the customer. The Customer Details view will fill the right pane of the window (see Figure 2).

Figure 2 Customer Details view 9. To confirm that the CreditCardModule is not currently being called, double-click the Gold credit card account listed in the lower right. Nothing should happen. In a later procedure, you will deploy the CreditCardModule as an update to the application. 10. Close the application.

Outcome
You have exercised the functionality of a ClickOnce deployed version of the Bank Branch client application and confirmed whether credit card module functionality is present.

Related Guidance
For information about launching the application when an update is available on the server, see "How to: Deploy an Updated Version of a Composite UI Application Block Application."

How to: Publish an Updated Version of a Composite UI Application Block Application


After your application is published and users have installed the application and are using it, you may need to roll out updates to add new functionality or to provide bug fixes. With the default automatic updating capability of ClickOnce, this involves simply publishing a new version of your application.

You have the option of overwriting the previous version on the deployment server or publishing a new version along side the previous version. It is often better to do the latter so that you can easily switch to the previous version if there is a problem with the new version. For the automated and manual versions of this procedure, you will publish a new version of the Bank Branch client application that includes the CreditCardModule to add a new Composite UI Application Block module to an application through a ClickOnce update. To publish a new application version 1. Make the desired modifications to the application for the new release. 2. Build and test the application. 3. Publish the new version from Visual Studio if the updates are contained in the shell application or any referenced assemblies, or directly update the published version on the deployment server if the changes are contained in new modules. Note: If you publish from Visual Studio and need to update the manifests with a tool after publishing to add additional modules, your publication will be in an inconsistent state until you finish updating the manifests. Visual Studio directly updates the default deployment manifest. If there are client computers running that will check for updates in the time between when you publish from Visual Studio and when you finish updating the manifests with a tool, they will see the update in the default deployment manifest and may download an inconsistent update. As a result, you should publish updates to a location where no one will be checking for updates until the update is in a consistent state and is ready to be distributed to client computers. After that, you can copy it to the real publish location to make it go live. For more information about this procedure, see "Automated: Publish an Updated Version of a Composite UI Application Block Application" or "Manual: Publish an Updated Version of a Composite UI Application Block Application."

Automated: Publish an Updated Version of a Composite UI Application Block Application


Prerequisites
This topic requires the following: Either the automated or manual procedures in "How to: Publish an Initial Version of a Composite UI Application Block Application" must be completed. The procedures in "How to: Deploy an Initial Version of a Composite UI Application Block Application" must be completed.

Applies To
The procedures in this topic apply to deployment of new modules or files as an application update through ClickOnce.

Steps
To create a copy of the previous application files folder on the deployment server 1. In Windows Explorer, open the publish folder for the application (C:\Inetpub\wwwroot\GlobalBank.Shell). 2. Right-click the folder that contains the previous version (GlobalBank.Shell_1_0_0_0), and then click Copy. 3. Right-click in the right pane, and then click Paste. 4. Rename the new folder GlobalBank.Shell_1_1_0_0. To use the Manifest Manager Utility to update the manifests 1. Run the Manifest Manager Utility application. 2. On the File menu, click Open. 3. Navigate to the publish folder (C:\Inetpub\wwwroot\GlobalBank.Shell), click GlobalBank.Shell.application, and then click Open. 4. In the Version box, type 1.1.0.0. 5. Next to the Application Manifest box, click Select. 6. Navigate to the GlobalBank.Shell_1_1_0_0 folder, click GlobalBank.Shell.exe.manifest, and then click Open. 7. On the Edit menu, click Add Files. 8. In the Add Application Files dialog box, navigate, if necessary, to the build output folder for the BankBranchWorkbench solution (C:\Program Files\Microsoft SCSF\bin\Debug). 9. Select the following two files, and then click Open: GlobalBank.CreditCardAccounts.Interface.dll GlobalBank.CreditCardAccounts.Module.dll

10. In the Browse For Folder dialog box, select GlobalBank.Shell_1_1_0_0 subfolder under the publish folder, and then click OK. 11. On the File menu, click Save. 12. If the Path box does not already contain the correct certificate file path, click Browse, and then click the certificate file created by Visual Studio when you first published (C:\Program Files\Microsoft SCSF\BankTellerWorkbench\Source\Src\Infrastructure\Shell\Shell_TemporaryKey.pfx ). 13. Click Sign and Save.

Outcome
You have a new version of the application published on the deployment server. The default deployment manifest (GlobalBank.Shell.application) has been updated to point to that version, and the new files have been added to that version's application manifest. The new version is ready to be deployed and will be automatically detected by the client application the next time it is launched by the user.

Related Guidance
For the manual steps this procedure automates, see "Manual: Publish an Updated Version of a Composite UI Application Block Application."

Manual: Publish an Updated Version of a Composite UI Application Block Application


Preparation
This topic requires the following: Either the automated or manual procedures in "How to: Publish an Initial Version of a Composite UI Application Block Application" must be completed. The procedures in "How to: Deploy an Initial Version of a Composite UI Application Block Application" must be completed.

Summary of Steps
To manually publish a new version of an application on the deployment server, you will perform the following steps: 1. Create a copy of the previous version's application files folder. 2. Copy the new files into the new folder. 3. Update the version and application files list in the application manifest with Mage. 4. Update the version and application reference in the deployment manifest with Mage.

Outcome
You will have a new version of the application published on the deployment server. The default deployment manifest (GlobalBank.Shell.application) will be updated to point to that version and the new files will have been added to that version's application manifest. The new version is ready to be deployed and will be automatically detected by the client application the next time it is launched by the user.

Related Guidance
For the automated steps for this procedure, see "Automated: Publish an Updated Version of a Composite UI Application Block Application."

Manual Steps
To create a copy of the previous application files folder on the deployment server 1. In Windows Explorer, open the publish folder for the application (C:\Inetpub\wwwroot\GlobalBank.Shell).

2. Right-click the folder that contains the previous version (GlobalBank.Shell_1_0_0_0), and then click Copy. 3. Right-click in the right pane, and then click Paste. 4. Rename the new folder GlobalBank.Shell_1_1_0_0. To copy the CreditCardModule files into the new folder 1. Copy the following two files into the new version's publish folder from the build output folder for the BankBranchWorkbench solution (C:\Program Files\Microsoft SCSF\bin\Debug): GlobalBank.CreditCardAccounts.Interface.dll GlobalBank.CreditCardAccounts.Module.dll

To update the application manifest 1. Run the Mage tool (in a Visual Studio 2005 command prompt window, type mage). 2. On the File menu, click Open. 3. Navigate to the new version's subfolder under the publish folder (C:\Inetpub\wwwroot\GlobalBank.Shell), and then click the new version's application manifest (\GlobalBank.Shell_1_1_0_0\GlobalBank.Shell.exe.manifest). 4. In the Version box, type 1.1.0.0. 5. In the left pane, click Files. 6. In the right pane, click Populate. 7. When prompted about renaming files, click OK. 8. On the File menu, click Save. 9. Click the ellipsis button (...) next to the File box for selecting a publisher certificate file. 10. Navigate to the publisher certificate that was generated by Visual Studio when you first published from there (C:\Program Files\Microsoft SCSF\BankTellerWorkbench\Source\Src\Infrastructure\Shell\Shell_TemporaryKey.pfx ), and then click it. 11. Click OK. To update the deployment manifest 1. On the Mage toolbar, click Open. 2. Navigate to the publish folder (C:\Inetpub\wwwroot\GlobalBank.Shell), click the default deployment manifest (GlobalBank.Shell.application), and then click Open. 3. In the Version box, type 1.1.0.0. 4. In the left pane, click Application Reference. 5. Click the Select Manifest button. 6. Navigate to the new version's application manifest (\GlobalBank.Shell_1_1_0_0\GlobalBank.Shell.exe.manifest), click it, and then click Open. 7. On the File menu, click Save. 8. Click the ellipsis button (...) next to the File box for selecting a publisher certificate file.

9. Navigate to the publisher certificate that was generated by Visual Studio when you first published from there (C:\Program Files\Microsoft SCSF\BankTellerWorkbench\Source\Src\Infrastructure\Shell\Shell_TemporaryKey.pfx ), click it, and then click OK. 10. Close Mage.

How to: Deploy an Updated Version of a Composite UI Application Block Application


If you use the default update settings for a ClickOnce publication, the application will always try to check the deployment server for updates before launching the application. If there are no updates or if the deployment server is unreachable, the application will just start the last installed version. If the deployment server has an update available, the user will be prompted that an update is available and allow them to accept the update or skip it. If they accept the update, the updated files will be downloaded before launching the application and the new version will launch instead. There are many variations from this behavior possible because of the different update settings in ClickOnce. For more information about the various options and their associated update behavior, see Smart Client Deployment with ClickOnce by Brian Noyes. For more information about this book, see http://www.softinsight.com/clickoncebook. In this procedure, you will launch the client application, see that an update is available, and then run that update. Because the update you will be applying is to add the CreditCardModule to the application, you will also have to update the profile catalog Web service to remove the module information for the CreditCardModule so that it will be loaded when the application starts and checks with the ProfileCatalogServices Web service to see what modules should be loaded. For more information about this procedure, see "Automated: Deploy an Updated Version of a ClickOnce Application."

Automated: Deploy an Updated Version of a Composite UI Application Block Application


Prerequisites
This topic requires the following: An initial version of the application must be published. For more information, see "How to: Publish an Initial Version of a Composite UI Application Block Application."

An initial version of the application must be deployed. For more information, see "How to: Deploy an Initial Version of a Composite UI Application Block Application." An updated version of the application must be published. For more information, see "How to: Publish an Updated Version of a Composite UI Application Block Application." The BankBranchWorkbench solution in Visual Studio must be open.

Applies To
The procedures in this topic apply to any ClickOnce application that you have deployed and published an update for.

Steps
The first step is only required for the BankBranchWorkbench reference implementation because it uses a remote profile catalog through the ProfileCatalogServices Web service to determine the modules to load. To enable the CreditCardModule in ProfileCatalogServices 1. In the Services solution folder, expand the ProfileCatalogServices project, and then open the ProfileCatalog.xml file. 2. At the bottom of the file for CreditCardModule, remove the ModuleInfo element.
<ModuleInfo AssemblyFile="GlobalBank.CreditCardAccounts.Module.dll"> <Roles> <Role Allow="Officer"/> <Role Allow="BranchManager"/> </Roles> </ModuleInfo>

3. Save and close the file. To run the application in the debugger to start the ASP.NET Development Servers 1. On the Debug menu, click Start Debugging to start a debug session. This starts the ASP.NET Development Server instances for the services that the application needs when it runs. 2. On the Debug menu, click Stop Debugging. Do not close Visual Studio. The ASP.NET Development Server instances continue to run until Visual Studio is closed. To launch the client application 1. On the taskbar, click Start, point to All Programs, point to the company name for your operating system installation (the company that is shown in the Visual Studio splash screen under your name), and then click GlobalBank.Shell. 2. In the Update Available dialog box, click OK. 3. Follow the procedure, "Manual: Check for Credit Card Module Functionality," to verify that the credit card functionality is now available. The abbreviated steps to verify the credit card functionality are: a. Log on with the user name Spike and the password Password3.

b. Enter the customer details for Leonids Paturskis. c. Double-click the credit card account listed. The credit card view should be presented as shown in Figure 1.

Figure 1 CreditCardModule view

Outcome
The application update has been successfully deployed to the client computer.

Related Guidance
For detailed information about the client application after it launches, see "Manual: Check for Credit Card Module Functionality."

How to: Move an Application to a Different Server


When developing an application that will be deployed with ClickOnce, you should locally test ClickOnce deployment and functionality of your application on a regular basis to confirm that you are not making design or implementation choices that will not work as expected in the ClickOnce execution context. At some point, you need allow other audiences such as Quality Assurance (QA) or end users to gain access to your published application. In an enterprise environment, you may not have direct access to the QA servers or production servers to directly publish to them. Disciplined release procedures should prevent you from doing that anyway. When you publish from Visual Studio, the first thing Visual Studio does when you initiate publishing is rebuild the application. Each time you build an application, you end up with

a set of executables that is different from those you used for previous tests and your application could potentially not work correctly after it is rebuilt. It is not sufficient to copy the manifests and application files to a new server to host the published application on a different server. One of the security protections includes embedding the deployment provider URL (labeled Install URL in Visual Studio and Start Location in Mage) in the deployment manifest. This ensures that if someone manages to obtain your published application files, the files cannot be installed on that person's server and then users allowed to launch the application from that server. Any time you move your published application to a different location, you have to update the deployment provider URL in the deployment manifest to reflect the new location of the application. Because this changes the contents of the manifest and the manifest contains a digital signature, you must also re-sign the deployment manifest with a publisher certificate. It is also unlikely in a large enterprise environment that you will be using your company's production publisher certificate when you are developing your application. To sign a ClickOnce deployment, you need a .pfx file that contains both the public keys and private keys for the publisher certificate. In large organizations, access to the private keys for company certificates is usually closely controlled to avoid exploitation by former or malicious employees. As a result, in addition to updating the deployment provider URL when you move the application to a production server, you will likely also have to re-sign the manifests. Both the application manifest and the deployment manifest must be signed with the same publisher certificate. The deployment manifest contains an application reference that includes the public key token of the application manifest. So, if you sign the application manifest with a new certificate, you also have to update the application reference in the deployment manifest in addition to updating the deployment provider URL and then sign the deployment manifest. Note: If an application has already been deployed to clients with one publisher certificate, you cannot publish an update to the application using a new publisher certificate. Updates must be signed with the same publisher certificate as the previous versions or the update will fail and the application will be disabled. This feature is designed to protect you from other people tampering with your application and signing it with their own certificate because they do not have access to yours. To summarize, when you move an application to a new server, you will perform one of the following two procedures. To move the application and sign with the same publisher certificate 1. Copy the contents of the application's publish folder to a folder on the new deployment server. This can be done using any file copy mechanism. 2. Open the deployment manifest and update the deployment provider URL to the URL that users will use to launch the application from the new server. 3. Sign the deployment manifest with the same publisher certificate that was used to publish the version you are copying. To move the application and sign with a different publisher certificate 1. Copy the contents of the application's publish folder to a folder on the new deployment server. This can be done using any file copy mechanism. 2. Open the application manifest and sign it with the new publisher certificate. 3. Open the deployment manifest and update the deployment provider URL.

4. Update the application reference within the deployment manifest to the newly-signed application manifest. 5. Sign the deployment manifest with the new publisher certificate. For detailed information about how to complete the preceding two procedures, see "Automated: Move an Application to a Different Server" or "Manual: Move an Application to a Different Server Using a Script."

Automated: Move an Application to a Different Server


Prerequisites
To perform this procedure, you must have first published your application and confirmed that it launches and runs correctly through ClickOnce on your local computer or a development server. For this procedure, you will move the Bank Branch client application to a different deployment folder on your local computer. As a result, you must have first published the application and tested it. One of the following procedures must be performed before this procedure: "How to: Publish an Initial Version of a Composite UI Application Block Application" or" How to: Publish an Updated Version of a Composite UI Application Block Application."

Applies To
The procedures in this topic apply to any ClickOnce published application that you need to move to another server and sign with a new publisher certificate.

Steps
This procedure moves the published Bank Branch client to a new location on your computer and uses a different launch protocol to launch the application. To move the application to the new server location 1. In Windows Explorer, copy the contents of the publish folder (C:\Inetpub\wwwroot\GlobalBank.Shell). 2. If your local computer does not have a C:\Temp folder, create one. 3. Paste the contents of the publish folder into the C:\Temp folder. To generate a new publisher certificate to sign the manifests with 1. Create a new Windows-based application project in Visual Studio. 2. On the View menu of the project, click Property Pages, and then click the Signing tab. 3. Select the Sign the ClickOnce Manifests check box. 4. Click Create Test Certificate. 5. In the Create Test Certificate dialog box, leave the password boxes clear, and then click OK.

A new .pfx file will be added to the project with a name of <ProjectName>_TemporaryKey.pfx (for example WindowsApplication1_TemporaryKey.pfx). 6. Close the solution. 7. Copy the .pfx file from the project folder of the project you just created, and then paste it into the C:\Temp folder. To update the manifests 1. Open the Manifest Manager Utility. 2. On the File menu, click Open. 3. Navigate to the new folder location (C:\temp\GlobalBank.Shell), click the deployment manifest (GlobalBank.Shell.application), and then click Open. 4. In the Deployment Provider box, change the value to \\<YourComputerName>\GlobalBank.Shell\GlobalBank.Shell.application. 5. On the File menu, click Save. 6. Click the ellipsis button (...) to navigate to C:\Temp, and then select the publisher certificate key file you created in the previous procedure (WindowsApplication1_TemporaryKey.pfx). 7. Click Save and Sign. 8. Close the Manifest Manager Utility. To test the application, set up the UNC file share. To set up the publish folder as a UNC share folder 1. Right-click C:\Temp\GlobalBank.shell, and then click Sharing and Security. 2. Click the Sharing tab, and then click Share This Folder. 3. Click OK. To launch the application, Web services has to be running as described in the procedure, "Automated: Deploy an Updated Version of a Composite UI Application Block Application." To install and launch the application from the new location 1. From a command prompt, type the UNC path to the deployment manifest (\\<YourComputerName>\GlobalBank.Shell\GlobalBank.Shell.application), and then press ENTER. 2. In the Application Install - Security Warning dialog box, click Install to launch the application.

Outcome
The ClickOnce publication is staged to a new server, signed with a different publisher certificate, and is ready to be deployed to clients with the URL specified in the deployment provider.

Related Guidance
None.

Manual: Move an Application to a Different Server Using a Script


The Mage.exe command line tool supports making modifications to the deployment and application manifests and then re-signing them with a publisher certificate using the command line. This can be scripted for more automated publishing to multiple servers. To do this, you have to redistribute the Mage.exe command-line tool and call it with appropriate command line arguments after the application files and manifests are copied to a target server. You also have to have a publisher certificate available to re-sign the manifests because of the modifications Mages makes to the files. That certificate could be the hosting organization's own publisher certificate (issued by a third party or selfgenerated) or one provided to the hosting organization by the publisher. The following procedure describes how to create and execute a republishing script. To stage Mage.exe and the publisher certificate to the new publish location 1. Create the new publish folder on the server, and then place the ClickOnce application files and manifests there with the same file structure and folder structure as the original publish location. 2. From the .NET Framework SDK\Bin folder, copy Mage.exe, and then paste it in the publish folder. 3. Locate your publisher certificate .pfx file, copy it, and then paste it in the publish folder. 4. (Optional; this step is required only if signing with a publisher certificate different than the original publisher.) Assuming an application manifest name of MyApp.exe.manifest in a subfolder of the publish folder named MyApp_1_0_0_0, a publisher certificate file name of MyCert.pfx, and a password for that file of pwd, run the following command line from the publish folder: mage.exe Sign MyApp_1_0_0_0\MyApp.exe.manifest CertFile MyCert.pfx Password pwd 5. Assuming a deployment manifest name of MyApp.application and a URL to the application for users of http://myappserver/MyApp/MyApp.application, update the deployment manifest deployment provider, application reference, and re-sign with the following information: Mage.exeUpdate MyApp.application AppManifest MyApp_1_0_0_0\MyApp.exe.manifest ProviderURL http://myappserver/MyApp/MyApp.application CertFile MyCert.pfxPassword pwd

How to: Add On-Demand Programmatic Update to the Application


The automatic update options of ClickOnce work well for simple applications, but they do not provide explicit control of when application updates are downloaded and applied. As

a result, the user may have to wait for an indeterminate period of time for their application to launch if a large update is being downloaded or if the server is under high load. If you want to explicitly control when updates are detected and downloaded, you can use the ClickOnce programmatic API to perform your application updating after your application starts. This kind of updating is often referred to as on-demand updates with ClickOnce. This topic describes how to add on-demand updates to the Bank Branch client application to check for updates in the background after the application launches. On-demand updates can be combined with automatic updates if you want users to be able to check for updates whenever they want. This is logical only if you also select the automatic update option to check for updates after the application starts and to check on a (relatively infrequent) scheduled basis. If you are using on-demand updates, you usually use them as your only update mechanism so your code can explicitly control when the updates occur. If you do this, you will usually want to check for updates on a timer or on a background thread, download the updates when they are available, and prompt the user when the update is ready to be applied to minimize the interruption for the user. The ApplicationDeployment class exposes the on-demand API for performing ClickOnce programmatic updates. The class exposes both synchronous and asynchronous versions of the update API. The asynchronous methods use the new asynchronous invocation pattern introduced in the .NET Framework 2.0, which is based on synchronization contexts. These asynchronous methods ensure that their corresponding completed events are raised on the UI thread if the update is initiated from the UI thread; this removes the need for explicit marshaling of the event calls to the UI thread. To apply on-demand updates 1. Add code to your application to check for and download updates whenever it is appropriate for your application. 2. Disable automatic updates when you publish the application. 3. Specify an update location URL in the publishing properties that will be used by the ClickOnce API to perform update checking when you invoke it with the on-demand API. For detailed information about adding on-demand updates to the BankBranchWorkbench application, see "Manual: Add On-Demand Programmatic Update to the Application." ClickOnce always applies the update the next time the application is launched after it is downloaded through the on-demand API. If you want to delay applying the functionality contained in the update, you can use the ProfileCatalogService Web service to ensure that newly downloaded modules are not applied until some point in the future by not listing those modules in the profile catalog. For an example of how to do this, see "How to: Apply Updates at a Future Time."

Manual: Add On-Demand Programmatic Update to the Application

Preparation
To prepare for this procedure, do the following: Copy the BankBranchWorkbench solution folder. You will be making modifications to the BankBranchWorkbench reference implementation in this procedure. To avoid the need to reinstall the Smart Client Software Factory to restore the original version, make a copy of the reference implementation solution folder under the Smart Client Software Factory installation so you can easily restore the original version. Use Add or Remove Programs to uninstall all previous versions of the GlobalBank.Shell application installed through ClickOnce. There may be more than one installation of the application if you performed the procedure, "How to: Move an Application to a Different Server Using a Script." Remove previous publications from the deployment server. To do this, remove all contents from the publish folder (C:\Inetpub\wwwroot\GlobalBank.Shell).

Summary of Steps
In this procedure, you will do the following: 1. Turn off automatic updating through ClickOnce and supply an update location URL. 2. Add code to the application to perform on demand updates. 3. Test the update process.

Outcome
Your application checks for updates in the background based on a timer interval that you control. When updates are detected, they are immediately downloaded and the user is prompted to restart the application.

Related Guidance
For complete details of all ClickOnce update options and how to apply them, see Smart Client Deployment with ClickOnce by Brian Noyes. For more information about this book, see http://www.softinsight.com/clickoncebook.

Manual Steps
To configure ClickOnce update settings 1. In the Shell application, click Property Pages on the View menu, and then click the Publish tab. 2. Click Updates. 3. Clear the The application should check for updates check box. 4. In the Update Location box at the bottom of the dialog box, type the update URL (http://localhost/GlobalBank.Shell/). Note: If you disable update checking, you must explicitly set the update location; otherwise, the deployment provider URL will not be set in the deployment manifest and on-demand updates will fail. However, you could

manually set the deployment provider URL through the Manifest Manager Utility or Mage. 5. Click OK. 6. Under Publish Version, set the version to 1.0.0.0. 7. Clear the Automatically increment revision with each publish check box. 8. Click Publish Now. To add timed on-demand update checking 1. In the Designer, open ShellForm.cs. 2. Move a timer from the Toolbox onto the form. 3. In the Properties window of the timer, set the Interval property to 60000 (milliseconds) to check for updates every minute. 4. In the Properties window, go to the Events view. 5. Add an event handler named OnCheckForUpdates for the Tick event. 6. In the Code view, add a using statement for the System.Deployment.Application and System.ComponentModel namespaces. C#
using System.Deployment.Application; using System.ComponentModel;

7. Modify the constructor to enable the timer (that is, start it ticking) and hook up event handlers if the application has been launched through ClickOnce. C#
public ShellForm() { InitializeComponent(); _layoutWorkspace.Name = WorkspaceNames.LayoutWorkspace; // Check to see if you are running through a ClickOnce launch if (ApplicationDeployment.IsNetworkDeployed) { timer1.Enabled = true; // Hook up event handler for update check completed events ApplicationDeployment.CurrentDeployment.CheckForUpdateCompleted += OnCheckForUpdatesCompleted; ApplicationDeployment.CurrentDeployment.UpdateCompleted += new AsyncCompletedEventHandler(OnUpdateCompleted); } }

8. Add the following code to the event handler for the Tick event. C#
private void OnCheckForUpdate(object sender, System.EventArgs e) { // Check to ensure running through ClickOnce if (ApplicationDeployment.IsNetworkDeployed) {

// Check for updates async ApplicationDeployment.CurrentDeployment.CheckForUpdateAsync(); } }

9. Add the following Boolean flag member to the form. C#


bool m_RequiredUpdateDetected = false;

10. Add the following event handler for the CheckForUpdateCompleted event. C#
void OnCheckForUpdatesCompleted(object sender, CheckForUpdateCompletedEventArgs e) { if (e.UpdateAvailable) { if (e.IsUpdateRequired) { m_RequiredUpdateDetected = true; } ApplicationDeployment.CurrentDeployment.UpdateAsync(); } }

11. Add the following event handler for the UpdateCompleted event. C#
void OnUpdateCompleted(object sender, AsyncCompletedEventArgs e) { if (m_RequiredUpdateDetected) { MessageBox.Show("Required update downloaded, application will restart"); Application.Restart(); } else { DialogResult result = MessageBox.Show( "Application update downloaded. Would you like to restart?", "Global Bank", MessageBoxButtons.YesNo); if (result == DialogResult.Yes) Application.Restart(); } }

To test the update process 1. Publish an initial version of the Bank Branch client application with the on-demand update code in it using the procedure, "How to: Publish an Initial Version of a Composite UI Application Block Application." 2. Launch the initial version of the Bank Branch client application with the procedure, "How to: Deploy an Initial Version of a Composite UI Application Block Application."

3. Close the application so that it is not checking for updates while you are publishing the new version. 4. Make a simple, but visible, update to the Shell application. An easy example is to modify the title bar text (Text property) for the ShellForm form. 5. In the Shell application, click Property Pages on the View menu, and then click the Publish tab. 6. Under Publish Version, set the version to 1.1.0.0. 7. To publish the updated version, follow the procedure, "How to: Publish an Updated Version of a Composite UI Application Block Application." 8. Launch the client application through the Start menu. After about a minute, it should detect and download the update, and then prompt you to restart.

How to: Publish Different Versions of the Same Application for Two Different Groups
You may need to publish different versions of your application to target different audiences or groups. For example, you may have a production version of your application that most users need, but then a beta version that you want specific users to be trying out. Additionally, you probably require that a single user can run both versions side-by-side on a single computer. To address this scenario, you need to have two published versions on your computer. Each version will have its own deployment manifest and application manifest. The key thing that is required to support side-by-side execution of two versions of the same application on the same computer is to have a unique application identity in the deployment manifest. This piece of information is usually automatically populated when you publish your application from Visual Studio. By default, the identity is set to the name of the deployment manifest. You can modify this value after publishing using Mage or the Manifest Manager Utility. The application identity is different from the Product Name property that determines how the application appears on the Start menu and in Add or Remove Programs. If a product name is not set, it defaults to the name of the application executable. You should set the Product Name property in Publish Options to ensure that each installation gets a unique Start menu shortcut that is easy to identify. The default behavior if two applications are installed with the same application executable name is to add a number to the shortcut (for example, MyApp, MyApp -1, and MyApp -2). For more information, see "Automated: Publish Different Versions of the Same Application for Two Different Groups."

Automated: Publish Different Versions of the Same Application for Two Different Groups
Prerequisites
None.

Applies To
The procedures in this topic apply to any ClickOnce deployed application.

Steps
To clearly demonstrate this process, you will create a simple Windows-based application and simulate two published versions. To create a Windows-based application project 1. Open Visual Studio. 2. Create a new Windows-based application project named MyApp. 3. On the View menu, click Property Pages, and then click the Publish tab. 4. Click Options. 5. In the Product Name box, type MyApp - Beta. To publish the initial version 1. In Solution Explorer, right-click the project, and then click Publish. 2. In the Publish Wizard, click Finish to accept the default publishing options. To rename the deployment manifest for the first version 1. In Windows Explorer, open the publish folder (C:\Inetpub\wwwroot\MyApp). 2. Rename MyApp.application to MyApp-Beta.application. To modify the application to create a new version and re-publish 1. Change the BackColor property on the form to a visibly different color. 2. On the View menu, click Property Pages, and then click the Publish tab. 3. Click Options. 4. In the Product Name box, type MyApp Release. 5. In Solution Explorer, right-click the project, and then click Publish. 6. In the Publish Wizard, click Finish. To modify the application identity and deployment provider for the first version 1. Open Manifest Manager Utility. 2. In the publish folder, open the MyApp-Beta.application file. 3. In the Application Identity box, type MyApp-Beta.

4. In the Deployment Provider box, type http://localhost/MyApp/MyAppBeta.application. 5. Click Save. 6. Select the publisher certificate (.pfx) file used to sign both versions from the project folder (for example, C:\temp\MyApp\MyApp\MyApp_TemporaryKey.pfx). 7. Click Sign and Save. To test the side by side deployments 1. Open Internet Explorer. 2. In the Address box, type http://localhost/MyApp/MyApp-Beta.application, and then press ENTER. 3. In the Application Install - Security Warning dialog box, click Install. This prompts the first version of the application to run. 4. In Internet Explorer, type http://localhost/Myapp/MyApp.application in the Address box, and then press ENTER. 5. In the Application Install - Security Warning dialog box, click Install. This prompts the second version of the application to run. 6. Confirm that you can run both versions at the same time from the Start menu shortcuts labeled MyApp Beta and MyApp Release.

Outcome
You will have two published versions of an application that can each be launched by users based on the address to its unique deployment manifest. The versions can run side by side on the same computer because they each have a unique application identity. The unique product name set at publish time allows you to discriminate the different versions on the Start menu.

Related Guidance
None.

How to: Restrict Access to Different Versions Based On User Role


ClickOnce installs an application on the client computer by making a series of individual file requests. The following is the sequence of the requests: 1. Deployment manifest 2. Application manifest 3. Each application file listed in the application manifest The file requests made by ClickOnce will pass the identity of the logged-on user to the server if the requests are made on a Windows network. Using Windows access control lists, you can restrict access to the manifests and application files to prevent unauthorized users from deploying your applications. However, there is no practical way

to restrict access to ClickOnce applications if they are exposed through the Internet to users who do not have Windows accounts on your domain. To secure a ClickOnce publication to a specific set of users who have Windows accounts on your domain, you just need to define a Windows group, associate those users with the group, and then restrict access to the ClickOnce manifests and application files to that group. For more information about managing access control and logging application usage, see "Administering ClickOnce Deployments" on MSDN. For detailed steps to restrict access to a ClickOnce application, see "Manual: Restrict Access to Different Versions Based on User Role."

Manual: Restrict Access to Different Versions Based on User Role


Preparation
To perform this procedure, you need a ClickOnce application published that you want to secure. To publish two versions of the same application, see "How to: Publish Different Versions of the Same Application for Two Different Groups." After completing that procedure, use Add or Remove Programs to remove all installed versions of MyApp.

Summary of Steps
In this procedure, you will perform the following steps: 1. Define a Windows group named BetaTesters. 2. Restrict access to a published application to that group. 3. Try to launch the application to verify that you do not have access. 4. Add yourself to the BetaTesters group. 5. Log out of Windows and then log on again to have the group membership take effect. 6. Try to launch the application again to verify you now have access.

Outcome
You will have restricted access to an application to a specific set of users.

Related Guidance
For more information about managing access control and logging application usage, see "Administering ClickOnce Deployments" on MSDN.

Manual Steps
To create a Windows group

1. On the taskbar, click Start, right-click My Computer, and then click Manage. 2. In the Computer Management tree, expand Local Users and Groups. 3. Right-click Groups, and then click New Group. 4. Name the group BetaTesters. 5. Click Create. 6. Click Close. To restrict access to the MyApp application 1. In Windows Explorer, open the publish folder (C:\Inetpub\wwwroot\MyApp). 2. Right-click MyApp-Beta.application, and then click Properties. 3. Click the Security tab. 4. At the bottom of the dialog box, click Advanced. 5. Clear the Inherit from the parent the permission check box. 6. In the Security dialog box, click Remove. 7. Click OK to close the Advanced Security Settings dialog box. 8. In the middle of the Security tab, click Add to add users or groups. 9. In the Select Users or Groups dialog box, type BetaTesters under Enter the object names to select, and then click OK (see Figure 1).

Figure 1 Select Users or Groups dialog box You should now have the file configured for BetaTesters-only access, as shown in Figure 2.

Figure 2 Properties dialog box To try to launch the application 1. In Internet Explorer, type http://localhost/MyApp/MyApp-Beta.application in the Address box. 2. In the Cannot Start Application dialog box, click OK (see Figure 3).

Figure 3 Cannot Start Application dialog box To add yourself to the BetaTesters group 1. On the taskbar, click Start, right-click My Computer, and then click Manage. 2. Expand Local Users and Groups. 3. Click Groups. 4. In the right pane, right-click BetaTesters, and then click Add to Group. 5. Click Add. 6. In the Select Users dialog box, type your logon name, and then click OK. 7. Click OK to close the Add to Group dialog box. 8. Log out of Windows, and then log on again for the group change to take effect. 9. Try to launch the application again as described in the preceding procedure. You should now be able to launch the application.

How to: Apply New Module Updates at a Future Time in a Composite UI Application Block Application
ClickOnce always applies an update the next time an application is launched after the update is downloaded. The download can be automatically triggered when launching the application if using ClickOnce automatic updating, or it can be done by your own code using the on-demand API. It is difficult to determine when the update is actually available and applied on any particular client computer because it is affected by when the application is run, how big the update is, how busy the server is, and what bandwidth is available to download the update. As a result, there may be times when you want to get the update "staged" to the client computer ahead of time and then control when the application starts using it to apply the update at a future time. For example, if you have a large update that you need to roll out to users, you need to make sure that all users start using the new version of the application at the same time when they arrive at work on a particular day and start the application. However, you do not want them to have to wait for a long time to start because everyone is trying to download the update at the same time (using the default update policy for ClickOnce). If the updates that you are applying are new Composite UI Application Block modules, you can address this scenario through a combination of ClickOnce updating and by using the ProfileCatalogService Web service to determine when the deployed updates are actually put into use. You could publish an update to the deployment server when the updated files become available. You would then wait a sufficient amount of time to ensure that all or most users have had a chance to download the application. If the usage pattern for your application is that users start the application at the start of the workday and leave it running all day, you would have to wait at least one day for the update to be downloaded and applied through ClickOnce. You would then add the new modules to the list of modules in the profile catalog the night before putting the new modules in operations. When the users start their application the next day, the application files will have already been staged to their computers through ClickOnce and will be loaded with no delay on startup after the call to the ProfileCatalogService has been made to determine what modules to load. The basic approach to support this scenario consists of the following: Publish the updated version containing the new modules. Allow clients to download the updates based on ClickOnce updates. Have the updates automatically applied on the client computer side the next time the application starts for physically staging the files. Have the client application wait to start using the new modules by not adding them to the profile catalog until sufficient time has elapsed for all users to get the updates.

For detailed information about how to use this approach, see "Manual: Apply New Module Updates at a Future Time in a Composite UI Application Block Application."

Manual: Apply New Module Updates at a Future Time in a Composite UI Application Block Application
Preparation
To prepare for this procedure, you will need to do the following: In Add or Remove Programs, remove any previously installed versions of the GlobalBank.Shell application. Clear any previous publications of the Bank Branch client application by deleting all contents of the C:\Inetpub\wwwroot\GlobalBank.Shell folder. Build the BankBranchWorkbench solution. To get the first version of the application published, follow the steps in "How to: Publish an Initial Version of a Composite UI Application Block Application." To get the first version of the application deployed to the client computer, follow the steps in "How to: Deploy an Initial Version of a Composite UI Application Block Application."

Summary of Steps
In this procedure, you will perform the following steps: 1. Publish a required update to the application consisting of added modules. 2. Run the application to get that update staged to the client computer and applied from a ClickOnce perspective. 3. Update the ProfileCatalogService to get the application to load the new module.

Outcome
You will be able to apply an update at a time in the future while still using ClickOnce to perform the physical update of the application.

Related Guidance
For information about how to publish an application, see "How to: Publish an Updated Version of a Composite UI Application Block Application." For information about how to verify whether credit card module is present, see "Manual: Check for Credit Card Module Functionality."

Manual Steps
To publish a required update 1. In the Shell project, click Property Pages on the View menu, and then click the Publish tab.

2. Click Updates. 3. Select the Specify a minimum required version for this application check box. 4. Set the minimum required version to 1.1.0.0. 5. Click OK. 6. Under Publish Version, set the version to 1.1.0.0. 7. Clear the Automatically increment revision with each publish check box. 8. Click Publish Now. 9. After the status bar indicates that the publishing succeeded, open the Manifest Manager Utility. 10. In the publish folder (C:\Inetpub\wwwroot\GlobalBank.Shell), open the GlobalBank.Shell.application manifest. 11. Click Add Files. 12. Add the following files to the application from the build output folder (C:\Program Files\Microsoft SCSF\bin\Debug), placing them in the new version's application files folder (C:\Inetpub\wwwroot\GlobalBank.Shell\GlobalBank.Shell_1_0_0_0): BasicAccounts.ServiceProxies.dll GlobalBank.BasicAccounts.Interface.dll GlobalBank.BasicAccounts.Module.dll GlobalBank.BranchSystems.Interface.dll GlobalBank.BranchSystems.Layout.dll GlobalBank.BranchSystems.Module.dll GlobalBank.BranchSystems.ServiceProxies.dll GlobalBank.Infrastructure.Module.dll Microsoft.Practices.EnterpriseLibrary.Caching.dll GlobalBank.CreditCardAccounts.Interface.dll GlobalBank.CreditCardAccounts.Module.dll

13. Save the manifest and sign with the same publisher certificate .pfx file that was used for the initial version (C:\Program Files\Microsoft SCSF\BankTellerWorkbench\Source\Src\Infrastructure\Shell\Shell_TemporaryKey.pfx ). To run the application in the debugger to start the ASP.NET Development Servers 1. On the Debug menu, click Start Debugging to start a debug session. This starts the ASP.NET Development Server instances for the services that the application needs when it runs. 2. On the Debug menu, click Stop Debugging. Do not close Visual Studio. The ASP.NET Development Server instances continue to run until Visual Studio is closed. To run the application to update the files on the client computer On the taskbar, click Start, point to All Programs, look for a group named the same as the company that is set for your computer (the company shown in the splash screen when you start Visual Studio under your name), and then click GlobalBank.Shell.

The required update will be automatically downloaded and applied on the client computer. Note: This procedure uses automatic updating, which could cause a long wait for the user during startup when the update is being downloaded. To address this, you could combine on-demand background download of the update after start with delayed profile catalog update to apply the future update with less impact to the user. You could exercise the application at this point and verify that the credit card module functionality is still not available, even though the module files have been physically staged to the client. To enable the CreditCardModule in ProfileCatalogServices 1. In the Services solution folder, open the ProfileCatalog.xml file in the ProfileCatalogServices project. 2. At the bottom of the file for CreditCardModule, remove the code for the ModuleInfo element. C#
<ModuleInfo AssemblyFile="GlobalBank.CreditCardAccounts.Module.dll"> <Roles> <Role Allow="Officer"/> <Role Allow="BranchManager"/> </Roles> </ModuleInfo>

3. Save and close the file. To run the client again 1. On the taskbar, click Start, and then click the client application shortcut to start it. 2. Exercise the application and observe that the credit card module functionality is present.

How to: Share Application Files Across Multiple Application Versions


When you publish an application with Visual Studio or Mage, each application version gets a complete copy of all the files the application is composed of in that version's own subfolder. The advantage of this is that you only need to look in one folder to see all the files that are needed for deployment of that version. It has the disadvantage that if you are supporting more than one version of an application at a time, or if multiple applications use the same libraries, you will have multiple copies of some files that you have to keep synchronized if you make changes to those files. The application manifest contains the list of files that an application is composed of. That list contains the relative path for each file that is part of the application. However, that relative path must be within the same folder or be a subfolder of the folder where the application manifest resides. As a result, you are constrained in terms of the folder structure that you can use if you want to share files across multiple applications or versions. As an example, consider two applications, named AppA and AppB, that each have some files that are unique to that application, as well as some files that they share across both

applications. If you wanted to avoid duplicating the shared files in both applications' publish folders, you could use a folder structure like the one shown in Figure 1.

Figure 1 Sharing files across published applications In Figure 1, each application has its own subfolder for its unique files. There is a SharedFiles subfolder under the root publish folder that contains the files shared across both applications. In the root folder, you will have to place the deployment manifest, application manifest, and the .exe.deploy file for the entry point of the application (the shell application executable) because of path restrictions on where application files can reside relative to those files. To establish this kind of a folder structure, you will have to use the Manifest Manager Utility or another custom tool. Neither Visual Studio nor Mage support adding files from multiple folders. To share files across multiple versions of an application or across multiple applications 1. Publish the first version/application from Visual Studio to its own publish location. 2. Publish the second version/application from Visual Studio to its own publish location. 3. Copy the deployment manifests for both applications into a single common publish folder. 4. Copy the application manifests and entry point .exe.deploy files for each application into the common publish folder. 5. Create the subfolder where you want common files to reside. 6. Create the subfolders for each of the application's unique files. 7. For each application, update the application manifest file list to point to all the application's files where they now reside. 8. Save and sign the application manifests. 9. For each application, update the deployment manifest application reference to the new location of the application manifest, and then update the deployment provider URL to the new location of the deployment manifest. 10. Save and sign the deployment manifests.

ClickOnce isolates each installed application on a client computer. As a result, even if files come from a shared folder on the server, each installation on the client computer will get its own copy of the file by default. The only exception to this is if the shared files are managed assemblies and you strong name those assemblies. When you do so, ClickOnce places the files in a separate location in the ClickOnce cache under the user's profile and creates only a single copy of a strong named assembly that multiple applications can use. For more information about sharing files across applications, see Automated: Share Application Files Across Multiple Application Versions.

Automated: Share Application Files Across Multiple Application Versions


Prerequisites
None.

Applies To
The procedures in this topic apply to any ClickOnce deployed applications that share files and for which you do not want to maintain multiple copies on the server.

Steps
To demonstrate this procedure, you will need two applications that share a common library. You will also add a custom setting to the application so that each application has its own configuration file that gets deployed with it. To create the applications 1. Open Visual Studio and create a new class library project named SharedLibrary in a solution named SharedLibraryDemo. 2. Add the following method to Class1. C#
public static string SayHello() { return "Hello"; }

3. Add a new Windows Application project to the solution named AppA. 4. Add a reference to the SharedLibrary class library in the AppA project. 5. Add a button to Form1. 6. Add a button Click handler for the button with the following code: C#
private void button1_Click(object sender, EventArgs e) { MessageBox.Show(SharedLibrary.Class1.SayHello());

7. In Solution Explorer, right-click the project, and then click Properties. 8. Click the Settings tab. 9. Add a setting to the grid named TitleBar of type string, Application scope, with a value of Application A (see Figure 1).

Figure 1 Add custom setting 10. Click the Publish tab. 11. Set the Publish location to http://localhost/SharedLibraryDemo. 12. Add code to the constructor to set the title bar text based on the application setting. C#
public Form1() { InitializeComponent(); Text = Properties.Settings.Default.TitleBar; }

13. Repeat steps 312, naming the new project AppB and the TitleBar setting to Application B. To publish the applications from Visual Studio 1. In Solution Explorer, right-click AppA, and then click Publish. 2. On the first page of the Publish Wizard, confirm the publish location is set to http://localhost/SharedLibraryDemo. 3. Click Finish. 4. After you see "Publish Succeeded" in the Visual Studio status bar and the browser pops up, switch back to Visual Studio. 5. In Solution Explorer, right click AppB, and then click Publish. 6. In the first page of the Publish Wizard, confirm the publish location is set to http://localhost/SharedLibraryDemo. 7. Click Finish. To relocate files to establish desired folder structure

1. In Windows Explorer, open the publish folder (C:\Inetpub\wwwroot\SharedLibaryDemo). 2. Create a new subfolder named \SharedLibrary. 3. Copy SharedLibrary.dll.deploy from either \AppA_1_0_0_0 or \AppB_1_0_0_0 into \SharedLibrary. 4. Delete SharedLibrary.dll.deploy from both \AppA_1_0_0_0 and \AppB_1_0_0_0. 5. Move AppA.exe.deploy and AppA.exe.manifest from the \AppA_1_0_0_0 subfolder up into the publish root folder (C:\Inetpub\wwwroot\SharedLibraryDemo). 6. From the \AppB_1_0_0_0 subfolder, move AppB.exe.deploy and AppB.exe.manifest to the publish root folder. 7. You should now have a folder structure like the one illustrated in Figure 2. The \AppA_1_0_0_0 subfolder contains AppA.exe.config.deploy, \AppB_1_0_0_0 contains AppB.exe.config.deploy, and \SharedLibrary contains SharedLibrary.dll.deploy.

Figure 2 Relocated files To update the manifests 1. Open the Manifest Manager Utility. 2. Open AppA.application. 3. In the dialog box that states it cannot find the application manifest, click OK. 4. Click the Select button next to the Application Manifest text box. 5. In the root publish folder, click AppA.exe.manifest, and then click Open. 6. In the grid for SharedLibrary.dll, click in the Relative Path column, and then enter the value SharedLibrary. 7. In the grid for AppA.exe.config, click in the Relative Path column, and then enter the value AppA_1_0_0_0. At this point, the window should look like the one illustrated in Figure 3.

Figure 4 Updating application file paths in the Manifest Manager Utility 8. On the File menu, click Save. 9. Click the Browse button to select the publisher certificate used to sign the AppA manifests (for example, C:\temp\SharedLibraryDemo\AppA\AppA_TemporaryKey.pfx). 10. Click Sign and Save. 11. Repeat steps 211 for AppB. Test the applications by entering their deployment manifest URL in the browser (for example, http://localhost/SharedLibraryDemo/AppA.application).

Outcome
The published applications are ready to deploy using a shared library on the server.

Related Guidance
None.

How to: Implement a Custom ClickOnce Deployment Server File Repository


To implement a custom ClickOnce deployment server file repository, you need to have a custom request handler running on the deployment Web server that will intercept inbound file requests for .application, .manifest, and .deploy files. That handler has to retrieve the files from whatever repository you want to use as an alternative to the usual ClickOnce file storage and have them stream back to the client computer as the response to the file requests. The handler also has to set the appropriate MIME content type header so the responses are properly handled by the ClickOnce runtime on the client computer. You could write a handler that is hard-coded to retrieve the ClickOnce files from a particular location or in a particular way. However, it makes more sense to factor the

retrieval logic out from the handler into a provider that you can plug in multiple implementations of without having to update the handler. The following steps are required for this procedure: 1. Implement an HTTP handler that intercepts file requests for ClickOnce manifests and application files and retrieves them from a repository provider. 2. Implement a repository provider that retrieves the files from wherever you need to store them. 3. Configure the Web site in Internet Information Services (IIS) to route ClickOnce manifest file requests and application file requests to ASP.NET. 4. Configure the ASP.NET application to use the handler for incoming ClickOnce manifest file requests and application file requests. 5. Populate the repository with ClickOnce application files. 6. Configure the handler to use the repository provider to retrieve the files. For information about how to accomplish this task, see "Manual: Implement a Custom ClickOnce Deployment Server File Repository."

Manual: Implement a Custom ClickOnce Deployment Server File Repository


To create the Visual Studio solution 1. Open Visual Studio. 2. Create a new class library project with a name of DeploymentRepositoryProvider and a solution name of ClickOnceDeploymentRepository. 3. Add a new ASP.NET IIS Web Site (HTTP option) to the solution named DeploymentSite with the location http://localhost/DeploymentSite. 4. Add a new class library project to the solution named SqlRespositoryProviderLib. 5. Add a project reference from the DeploymentSite to both the DeploymentRespositoryProvider and SqlRespositoryProviderLib projects. 6. Add a project reference from the SqlRespositoryProviderLib project to the DeploymentRespositoryProvider library. To define the repository provider interface 1. In the DeploymentRepositoryProvider class library, delete Class1.cs. 2. Add an interface definition to the DeploymentRepositoryProvider class library (on the Add menu, point to New Item, and then click Interface) named IDeploymentRepository with the following code. C#
public interface IDeploymentRepository { byte[] GetFile(string filePath); }

To implement a deployment repository provider factory 1. In Solution Explorer, right-click DeploymentRepositoryProvider, click Properties, and then click the Settings tab. 2. Click the link to add a Settings file. 3. Add an application scoped setting of type string named DeploymentRepositoryProvider. 4. Set the value of the DeploymentRepositoryProvider to SampleProvider to create the appropriate schema in the class library project's App.config file. 5. Click Save to save the new setting. 6. Add a class to the class library named DeploymentRepositoryProviderFactory. 7. Add the following using statements to the top of the file. C#
using DeploymentRepositoryProvider.Properties; using System.Configuration; using System.Reflection;

8. Modify the DeploymentRepositoryProviderFactory class to match the following code. C#


public static class DeploymentRepositoryProviderFactory { public static IDeploymentRepository CreateInstance() { string assemblyName; string typeName; GetTypeInfo(Settings.Default.DeploymentRepositoryProvider, out assemblyName, out typeName); if (string.IsNullOrEmpty(assemblyName) || string.IsNullOrEmpty(typeName)) { throw new ConfigurationException( "Invalid type information in configuration for provider"); } // This code dynamically loads the assembly using normal // resolution. Assembly assem = Assembly.Load(assemblyName); if (assem == null) { throw new ConfigurationException( "Could not load assembly " + assemblyName); } // This code creates the dynamic instance. IDeploymentRepository instance = assem.CreateInstance(typeName) as IDeploymentRepository; return instance; }

// This code is the Helper method to extract the type // information from a string. It expects // the format Fully.Qualified.TypeName, AssemblyName private static void GetTypeInfo(string componentTypeInfo, out string assemblyName, out string typeName) { assemblyName = null; typeName = null; // Configuration entries should be split into // two parts and in the following form: // Fully.Qualified.TypeName, AssemblyName string[] typeInfo = componentTypeInfo.Split(','); if (typeInfo == null || typeInfo.Length < 2) { return; // invalid type info, ignore } assemblyName = typeInfo[1]; typeName = typeInfo[0]; if (string.IsNullOrEmpty(assemblyName) || string.IsNullOrEmpty(typeName)) { return; // invalid type info, ignore } assemblyName = assemblyName.Trim(); typeName = typeName.Trim(); } }

To implement a custom HTTP deployment repository handler 1. Add a reference to the System.Web assembly to the DeploymentRepositoryProvider project. 2. Add a class named DeploymentRepositoryHandler. 3. Add a using statement to the top of the class file for the System.Web and System.IO namespaces. C#
using System.Web; using System.IO;

4. Modify the class definition to match the following code. C#


public class DeploymentRepositoryHandler : IHttpHandler { public bool IsReusable { get { return true; } } public void ProcessRequest(HttpContext context) {

string requestPath = context.Request.Url.ToString(); string rootPath = context.Request.ApplicationPath; requestPath = requestPath.Substring( requestPath.IndexOf(rootPath) + rootPath.Length + 1); requestPath = requestPath.Replace('/', '\\'); IDeploymentRepository provider = DeploymentRepositoryProviderFactory.CreateInstance(); byte[] bits = provider.GetFile(requestPath); context.Response.OutputStream.Write(bits,0,bits.Length); if (Path.GetExtension(requestPath) == ".application" || Path.GetExtension(requestPath) == ".manifest") { context.Response.ContentType = "application/x-ms-application"; } else { context.Response.ContentType = "application/octet-stream"; } } }

To define a SQL Server file repository database 1. Execute the SQL script ClickOnceFileRepository.sql. This script adds a database with a Files table and stored procedures that wrap it to your database. The following command executes the script on the local SQL Server database. The command uses integrated security and assumes that you have permissions to update the SQL Server. If the SQL Server is not installed on the local computer, replace (local) with the name of the computer where SQL Server is installed. To do this, do one of the following: a. If you installed the AdventureWorks database in SQL Server 2005, execute the following command: OSQL -S (local) -E -i ClickOnceFileRepository.sql b. If you installed the AdventureWorks database in SQL Server 2005 Express Edition, execute the following command: OSQL -S (local\SQLEXPRESS) -E -i ClickOnceFileRepository.sql 2. After you install the ClickOnceFileRepository database, you must perform the following steps: a. Add the ASPNET user account as a valid logon for SQL Server 2005. b. Grant the ASPNET user account db_owner permission. To add a typed data set data access layer to the SQL file repository provider 1. Add a typed data set definition to the SqlRepositoryProviderLib project (on the Add menu, point to New Item, and then click DataSet) with the name FileRepositoryDataSet. 2. Open Server Explorer. 3. Add a data connection to the ClickOnceFileRepository database. 4. Expand ClickOnceFileRepository. 5. Expand Stored Procedures.

6. Drag the SelectFiles stored procedure onto the design surface. 7. Select the name in the title bar of the SelectFiles data table definition in the designer, and then change the name to Files. 8. At the bottom of the table definition, right-click FilesTableAdapter, and then click Add Query. 9. In the TableAdapter Query Configuration Wizard, click Use existing stored procedure, and then click Next (see Figure 1).

Figure 1 First page of the TableAdapter Query Configuration Wizard 10. On the next page of the wizard, click GetFileBitsByPath in the Select the stored procedure to call drop-down list box, and then click Next (see Figure 2).

Figure 2 Selecting the existing stored procedure 11. On the next page of the wizard, click A single value, and then click Next (see Figure 3). This option results in determining whether the data access method generated should return a data table, a single value, or no return value.

Figure 3 Select the shape of the stored procedure return data 12. On the last page of the wizard, accept the default name for the generated data access method, and then click Finish (see Figure 4).

Figure 4 Specifying the generated method name To implement the SQL file repository provider 1. In the SqlFileRepositoryProviderLib class library project, change the file name of Class1.cs to SqlFileRepositoryProvider.cs. When the prompt to rename the class appears, accept it. 2. Change the class definition to match the following code. C#
public class SQLFileRepositoryProvider : IDeploymentRepository { byte[] IDeploymentRepository.GetFile(string filePath) { FilesTableAdapter adapter = new FilesTableAdapter(); return adapter.GetFileBitsByPath(filePath) as byte[];

} }

To configure the Web site to host the handler and provider 1. Add a Web configuration file to the Web site (on the Add menu, point to New Item, and then click Web Configuration File). 2. In the DeploymentRepositoryProvider class library project, open the App.config file. 3. Add all the configuration elements from the App.config file in the DeploymentRepositoryProvider class library to the Web.config file just under the configuration root element. C#
<configSections> <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" > <section name="DeploymentRepositoryProvider.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> </sectionGroup> </configSections> <applicationSettings> <DeploymentRepositoryProvider.Properties.Settings> <setting name="DeploymentRepositoryProvider" serializeAs="String"> <value>SampleProvider</value> </setting> </DeploymentRepositoryProvider.Properties.Settings> </applicationSettings>

4. In the value tag, change SampleProvider to SqlRepositoryProviderLib.SQLFileRepositoryProvider, SqlRepositoryProviderLib. 5. Under the System.web element, add the following element. C#
<httpHandlers> <add path="*.application" type="DeploymentRepositoryProvider.DeploymentRepositoryHandler, DeploymentRepositoryProvider" verb="*"/> <add path="*.manifest" type="DeploymentRepositoryProvider.DeploymentRepositoryHandler, DeploymentRepositoryProvider" verb="*"/> <add path="*.deploy" type="DeploymentRepositoryProvider.DeploymentRepositoryHandler, DeploymentRepositoryProvider" verb="*"/> </httpHandlers>

6. In the Web.config file, replace the <connectionStrings /> element with the one from the SqlRepositoryProvider App.config file. C#
<connectionStrings> <add name="SqlRespositoryProviderLib.Properties.Settings.ClickOnceFileRepositor yConnectionString" connectionString="Data Source=.;Initial Catalog=ClickOnceFileRepository;Integrated Security=True" providerName="System.Data.SqlClient" /> </connectionStrings>

To configure IIS to route ClickOnce manifest and application file requests to ASP.NET 1. In Control Panel, click Administrative Tools, and then click IIS Manager. 2. Expand the tree, and then click the DeploymentSite virtual directory. 3. Right-click DeploymentSite, and then click Properties. 4. On the Directory tab, click Configuration (see Figure 5).

Figure 5 DeploymentSite Properties dialog box 5. In the Application Configuration dialog box, click .ascx (see Figure 6), and then click Edit.

Figure 6 Application Configuration dialog box 6. In the Executable box, select the entire path to the ASP.NET ISAPI DLL, copy it to the Clipboard, and then click Cancel. 7. Click Add. 8. In the Executable box, paste the path you copied in step 6, set the file name extension to .application, clear the Check that file exists check box, and then click OK (see Figure 7).

Figure 7 Add/Edit Application Extension Mapping dialog box 9. Repeat step 7 and step 8 for the file name extensions .manifest and .deploy. 10. Click OK to close the Application Configuration dialog box. 11. Click OK to close the Properties dialog box. To create a utility to populate the database table with ClickOnce application files 1. Add a new Windows-based application project to the solution named SqlRepositoryAdmin. 2. Add a typed data set to the project (on the Add menu, point to New Item, and then click DataSet) named FileRepositoryDataSet. 3. Open Server Explorer. 4. Expand the ClickOnceFileRepository database down to the Files table. 5. Drag the Files table onto the data set designer. 6. Open the Data Sources window (on the Data menu, click Show Data Sources).

7. Drag the Files table onto the form to add a data bound grid. 8. Click the small triangle in the upper right of the grid to view the smart tag (see Figure 8).

Figure 8 DataGridView smart tag 9. Click the Dock in Parent Container link. 10. Clear the Enable Adding check box. 11. Click the Edit Columns link. 12. Remove the FileBits, Modified, and OriginalPath columns. 13. Set the AutoSizeMode property of the FilePath column to Fill. 14. Click OK to close the column editor. 15. In the non-visual components tray at the bottom of the designer, delete filesBindingNavigator. 16. In the Toolbox, double-click ToolStrip to add one to the form. 17. Use the drop-down menu to add a button to the ToolStrip (see Figure 9).

Figure 9 ToolStrip add menu 18. Set the DisplayStyle property to Text. 19. Set the Text property to Add File. 20. Add another button with the DisplayStyle property set to Text, and the Text property set to Save. 21. Double-click the Add File ToolStrip button to add a Click event handler for it. 22. Add the following code to the Add File event handler.

C#
private void toolStripButton1_Click(object sender, EventArgs e) { // Prompt for the file path OpenFileDialog ofd = new OpenFileDialog(); ofd.Filter = "All Files(*.*)|*.*"; if (ofd.ShowDialog() == DialogResult.OK) { string fileName = ofd.FileName; FileRepositoryDataSet.FilesRow newRow = fileRepositoryDataSet.Files.NewFilesRow(); newRow.FilePath = Path.GetFileName(ofd.FileName); newRow.OriginalPath = ofd.FileName; newRow.Modified = DateTime.Now; byte[] bits; using (FileStream fstream = File.OpenRead(ofd.FileName)) { bits = new byte[fstream.Length]; fstream.Read(bits, 0, (int)fstream.Length); } newRow.FileBits = bits; fileRepositoryDataSet.Files.AddFilesRow(newRow); } }

23. Switch to Design view, and then double-click the Save button to add a Click handler for it. 24. Add the following code to the Save event handler. C#
private void toolStripButton2_Click(object sender, EventArgs e) { Validate(); filesBindingSource.EndEdit(); filesTableAdapter.Update(fileRepositoryDataSet.Files); }

To create a Windows-based application to deploy 1. Create a Windows-based application project named SomeClickOnceApp. 2. Right-click the project, and then click Publish. 3. Click Finish to publish the application to the default location. To update the deployment provider URL to the URL that will be used to launch the application 1. Launch the Manifest Manager Utility. 2. Click Open. 3. Locate the deployment manifest for the SomeClickOnceApp application (C:\Inetpub\wwwroot\SomeClickOnceApp\SomeClickOnceApp.application), and then click it.

4. In the Deployment Provider box, type http://<yourmachinename>/DeploymentSite/SomeClickOnceApp.application. 5. Click Save. 6. In the Sign and Save dialog box, click Browse. 7. Find the .pfx file in the SomeClickOnceApp Visual Studio project folder and select it. 8. Click Sign and Save. To read the published files into the database using the administrative application 1. Run the SqlRepositoryAdmin application. 2. Click Add File. 3. Navigate to C:\inetpub\wwwroot\ SomeClickOnceApp\SomeClickOnceApp.application, click it, and then click Open. 4. Click Add File again. 5. Navigate to C:\inetpub\wwwroot\ SomeClickOnceApp\SomeClickOnceApp_1_0_0_0\SomeClickOnceApp.exe.man ifest, click it, and then click Open. 6. Edit the File Path for that file in the grid and update it to SomeClickOnceApp_1_0_0_0\SomeClickOnceApp.exe.manifest. 7. Click Add File again. 8. Navigate to C:\inetpub\wwwroot\ SomeClickOnceApp\SomeClickOnceApp_1_0_0_0\SomeClickOnceApp.exe.depl oy, click it, and then click Open. 9. Edit the File Path for that file in the grid and update it to SomeClickOnceApp_1_0_0_0\SomeClickOnceApp.exe.deploy. 10. Click Save. 11. The files should have paths as shown in Figure 10.

Figure 10 Administrative tool with path edits To test the deployment Open a browser instance, and then type the following address into the Address box: http://localhost/DeploymentSite/SomeClickOnceApp.application.

Summary
Deploying client applications with ClickOnce requires a lot of procedural steps to accomplish, and there are many variations in the way development organizations want to manage their deployments. This ClickOnce Community Resource Kit contains over 70 pages of written guidance and How-to topics that lead you through common scenarios. Accompanying the written guidance is a Manifest Manager Utility sample that will make it easier to accomplish those steps through a custom tool. This tool also provides sample code for how to program against the ClickOnce manifest APIs to create other custom tools for manipulating manifests beyond what Visual Studio and the SDK tools support. There is also guidance and a sample implementation for putting a custom server repository source for your ClickOnce application files using SQL Server. This material, written by IDesign architect Brian Noyes, author of Smart Client Deployment with ClickOnce (http://www.softinsight.com/clickoncebook), will help get you up and running with ClickOnce deployment quickly. You can contact Brian at brian.noyes@idesign.net.

You might also like