Tuesday, March 13, 2007
Thursday, December 28, 2006
Friday, December 1, 2006
Tuesday, November 21, 2006
ClickOnce Publisher Certificate Renewals and Updating Your Application
A fairly messy little detail of ClickOnce has surfaced that I wanted to get some word out about regarding publisher certificate renewals and how they affect ClickOnce.
ClickOnce only allows you to perform an update to an application if the updated version manifests are signed by the same publisher certificate as was used to originally sign the application.
When ClickOnce was designed, the product team understanding was that certificate issuers such as Verisign and thawte would renew certificates without re-issuing a new certificate (with a new private/public key pair). Unfortunately, that understanding was incorrect. Certificate issuers do in fact issue a whole new cert, just one that has the same CN (Common Name) when they do a renewal.
The result of this is that if you have a ClickOnce application in production and your publisher cert expires, you will no longer be able to issue updates to your application with your new cert. You will have to have users uninstall the previous version and install the new version as a fresh install.
To combat this for the near term, you may want to consider buying a cert that lasts longer than a year.
Microsoft is looking into a fix for this in the Orcas release, but the details of what that fix will look like and how it will affect the update process is yet to be determined.
Tuesday, November 21, 2006 9:35:16 PM (GMT Standard Time, UTC+00:00)
Friday, November 17, 2006
IDesign Advanced .NET Master Class Seat Giveaway
If you want to win a free seat for our Advanced .NET 2.0 Master Class, being held 4-8 Dec 2006 in Reston, VA, be the first one to email me at brian.noyesATidesign.net with the answer to the following question:
What is the name of the class that you use to sign a ClickOnce manifest after making modifications to it and writing it out with the manifest utility APIs?
Race is on!
Friday, November 17, 2006 7:16:47 PM (GMT Standard Time, UTC+00:00)
Friday, November 10, 2006
DevConnections Vegas Slides and Demos
Another great conference complete. Around 5000 showed up and we had great feedback from the crowd that it was a good show. If you haven't been to connections before, you really should check it out.
I gave three talks this week. You can get the slides and demos for each below.
Real World ClickOnce: Slides Demos
Workflow Driven Windows Applications: Slides Demos
Implement a Data Layer with the VS 2005 DataSet Designer: Slides Demos
Sunday, November 5, 2006
ClickOnce Publishing from Visual Studio on Windows Vista
If you haven't experienced Windows Vista yet, it is a very cool operating system, but there are a lot of lessons to learn in getting up to speed in working in the new environment.
The biggest thing to get used to if you haven't been running a non-admin account on your XP machine is that there are probably a hundred things or more that you get away with that you don't even know that the reason you get away with it is that you are an admin.
In Vista, even when logged in with an administrator account, you are still not allowed to do administrator things without a privilege elevation through a mechanism called User Access Control (UAC). UAC will seem like a living hell at first because all kinds of things will stop working for you. For example, if you are only getting to some files because you are an admin, and an app such as Quicken tries to run and access those files, you will just get whatever kind of error the app vendor decided to surface for a file I/O error. However, the best way to approach it is to treat it as a learning experience to figure out how to avoid running things as admin unless you really need to (i.e. give your user account permissions to the directories you really need, don't rely on Admin privilege to give you access).
Another example is when publishing with ClickOnce. When you publish from Visual Studio to an http address, VS uses Frontpage Server Extensions (FPE) to create the virtual directory and copy the files to it. First step on Windows Vista is that you need to have IIS 6 Compatibility enabled (it is not on by default, nor is IIS installed by default like XP). Once you do that, IIS 7 knows how to look like a Frontpage Server Extension endpoint. The other thing is that you can only access the web server through FPE if you are accessing as an admin from VS.
Even when logged in as an admin, VS will not be running with admin privilege by default. As a result, when you try to publish a ClickOnce app you will get an obscure error that says that FPE is not installed on the server. Specifically:
"Failed to connect to 'http://localhost/WindowsApplication3/' with the following error: Unable to create the Web 'http://localhost/WindowsApplication3/'. The Web server does not appear to have the FrontPage server extensions installed."
The solution is quite simple: you need to run VS as an admin. To do this, you can right click on the shortcut to VS from the start menu and select Run as Administrator.
If you want to always run VS as admin, do the following:
- Go to devenv.exe in the C:\Program Files\Microsoft Visual Studio 8\Common7\IDE directory.
- Right click and go to properties.
- Select the Compatibility tab.
- Check the box at the bottom that says Run this program as an administrator (see below).
The new security protections of UAC are there for a reason. You could just turn it off and you wouldn't have problems like this in the first place. I'd encourage you not to do that. Use it as a tool to teach you how to get your work done without admin privilege to the extent possible. So in this case I prefer to only run VS as an admin when I need to by doing the right click - Run as Administrator option instead of always enabling it, but you will have to make these productivity vs security decisions for yourself.
Sunday, November 5, 2006 7:27:21 PM (GMT Standard Time, UTC+00:00)
Friday, November 3, 2006
ClickOnce Deployment Application Identity
One scenario people want to support is to have multiple versions of the same application installed to a single machine/user's account. The guidance I put together for patterns and practices has a walkthrough of setting this up. For example, say you have a version 184.108.40.206 of an application that is your production version, and you publish a new beta version (220.127.116.11) that you want a limited set of users to access, but those same users need to be able to run both production and beta side by side through ClickOnce on their machines (perhaps for feature comparison testing).
The first step is that you will need to have different deployment manifests for the multiple versions you want a single user to run. You direct the user to launch from each URL to the different deployment manifests and they will get a separate installation on their machine... or will they? The answer depends on a hidden aspect of the ClickOnce runtime regarding what the runtime considers a unique identity for an installed application.
If you are not familiar with the things that ClickOnce does under the covers to install an application on a client machine, it downloads and caches the deployment manifest, the application manifest, and all of the application files. Those manifests have to be signed by a publisher certificate that is cryptographically unique. Additionally, the installed application has a product name that gets embedded in the deployment manifest.
You might be tempted, as I was, to think that a unique product name, combined with a separate deployment manifest would be sufficient to make the client machine treat those installs as separate and distinct (such as setting the product names to "MyApp" and "MyApp - Beta"). Unfortunately you would be wrong, as I was.
There is actually a separate piece of information that the ClickOnce runtime uses to distinguish one application from another - the application identity is set by an identity set for the deployment manifest itself. This identity is normally created by Visual Studio when publishing and is set to the deployment manifest name (i.e. WindowsApplication1.application). You do not have control from Visual Studio to set this to anything else. Through the mageui.exe SDK tool, or better yet my Manifest Manager Utility included with the patterns and practices guidance, you can set this application identity to any string that you like to uniquely identify multiple published versions of a single application.
So to address the scenario presented earlier, you can simply set the application identity to MyApp for one version and MyApp-Beta for the other version, and you will be able to side-by-side install those two copies of the app on the same machine.
Friday, November 3, 2006 8:30:14 PM (GMT Standard Time, UTC+00:00)
Thursday, November 2, 2006
SCSF ClickOnce Guidance Available
I recently put together a bunch of guidance topics for Microsoft Patterns and Practices for doing ClickOnce deployments of CAB-based applications. This guidance and the sample code is now available as a Community Resource Kit and will eventually be incorporated into a future release of SCSF.
The resource kit also includes something a lot of people have been asking for - an example of programming against the manifest APIs in the Microsoft.Build.Tasks.Deployment.ManifestUtilities namespace. I wrote a Manifest Manager Utility as part of that effort and included in the download code that makes common tasks such as updating application files a lot easier. It takes care of signing both manifests at one to make sure they are in sync, updates the deployment manifest reference to the app manifest and other things like that. If you need to go beyond what it does, then you now have sample code available to show you how to work with the APIs.
Another thing included in the kit is an example server side deployment repository provider that allows you to take over the process of serving up manifests and application files on the deployment server so that you could retrieve them from anywhere or even generate some of the files on the fly.
Get it here!
Monday, October 23, 2006
Thursday, October 5, 2006
Wednesday, September 6, 2006
Smart Client Deployment with ClickOnce - Final Manuscript Complete!
I'm very pleased to announce that my ClickOnce book is done. I still have to go through the production cycle, which involves reviewing and responding to changes and recommendations by the copy editors. But the content is done, tech reviewed, and ready to go other than that. The cover has been designed and is looking pretty sweet:
It was actually the publisher's idea to incorporate an aircraft on the cover, which I of course loved with my background flying F-14's. It actually makes a lot of sense if you know much about the mission of naval aviation. Our job was to deploy - deploy on the carrier to bring the military might of the US to wherever it was needed, and to deploy weapons on target. ClickOnce is about deploying a different kind of weapon (the smart client app you write) on target (the client desktop). But the metaphor fits in my mind.
The book should be up on Rough Cuts (http://my.safaribooksonline.com/roughcuts) in the very near future in case you want to get your hands on it sooner than when it comes out in print (probably January by the time we get through production).
There is nothing quite like the feeling of finishing a book after many months of having it hanging over your head as that thing you gotta find time for. Now I can tend to the many projects I have sidelined while trying to wrap this book up while maintaining a full consulting load. My wife Robin will be quite glad that I don't have "the book" as an excuse any more. :)
Saturday, June 24, 2006
Managing ClickOnce publisher certificate files
I've had several people ask questions surrounding how to get a pfx file to use for ClickOnce manifest signing when you have purchased a real certificate from a provider like Verisign or Comodo (www.instantssl.com - a great, cheaper alternative that has its root issuer already installed as a trusted root certification authority).
Usually when you purchase a certificate, the process involves going to the provider's site, such as instantssl.com, providing your contact information online and entering payment information. The certificate issuer must then verify your identity through some means (corporate DUNS number, business license, bank statement, utility bill, etc.). Once they have done that, they will allow you to download and install your certificate through your browser. They should also provide you with a separate download or generation of a .pvk (private key) file that will contain the private key portion of your certificate. They may or may not provide you a download of a .spc or .cer file that just contains the public key portion of your certificate. If they do not provide a download of the .spc file, you may have to export it from your certificate store after the browser installs it as described later in this post.
Step 1: Download and install pvkimprt.exe
If you have a .spc or .cer file and a .pvk file, then you have the pieces you need to create a .pfx file. You will need to download,expand, and install the pfximprt tool, which you can get here:
Generate an install a public/private key pair certificate in your store
To generate a pfx file from an spc/cer and pvk file, do the following:
1. Open a command prompt and run pvkimprt, passing the spc and pvk file:
C:\>"C:\Program Files\Pvkimprt\pvkimprt.exe" softinsight_comodo.spc softinsight_comodo.pvk
2. You will be prompted for a password for the pvk file as shown in Figure 1. The password is the one you provided when you ordered the certificate or when the pvk file was issued to you.
3. After entering your password and clicking OK, the certificate import wizard will launch as shown in Figure 2.
4. Click Next, and you will be prompted as shown in Figure 3 for selecting the store. Just allow it to automatically select the store (the default) and click Next.
5. You will then just see the summary as shown in Figure 4, click Finish.
6. You should now have a publisher certificate installed into your personal certificate store that contains both the public and private keys for the same certificate. Now you need to export it to a .pfx file that you can back up and use on other machines. Open certmgr by running certmgr.exe from a Visual Studio 2005 command prompt (see Figure 5).
7. Find the certificate you just imported (by publisher name) in the list in the Personal tab (selected by default). Press the Export button.
8. The first step of the export wizard will be presented (see Figure 6). Press Next.
9. The next step asks whether you want to export the private key. If you are generating a pfx file for ClickOnce deployment, the answer here must be yes, which is not selected by default (see Figure 7). Press Next.
10. The next step asks what export file format you want, the default is fine (see Figure 8). Press Next.
11. The next step asks for a password to protect the pfx file that will be output, use a secure password and be careful who you give it to because this is the last line of defense if someone is able to get their hands on your physical pfx file to prevent them from being able to use it. Enter a password twice and click Next (see Figure 9)
12. The next step has you enter the path to the output file. You can press the browse button and navigate to the desired folder and select the file format from the file type drop down, or you can just type in a path (see Figure 10). Press Next.
13. You will see the summary screen, press Finish to generate the file (see Figure 11).
14. You will see a message box showing that the export was successful (see Figure 12).
At this point you now have a pfx file that you can point to with your Visual Studio project Signing tab properties to sign your ClickOnce manifests. You can share that file with other trusted members of your team and they can use it to sign your applications to put them into production.
Just realize that anyone who gets their hands on that file and knows or can guess the password will be able to sign and publish applications that look like they come from you, so you need to treat those files (particularly the pfx and pvk) very carefully.
Monday, June 19, 2006
Another TechEd Complete - Slides and Demos
It was a crazy week at TechEd last week. So crazy, no time to write or consume blogs. I gave two breakout sessions (Real World ClickOnce and Windows Forms: Build Enterprise Ready Forms Applications) and a Birds of Feather session (Windows Workflow Foundation).
You can get the slides and demos from the sessions here:
Real World ClickOnce: Slides Demos
Windows Forms: Build Enterprise Ready Forms Applications: Slides Demos
Monday, May 29, 2006
ClickOnce Trust Model - What Should and Shouldn't You Be Able To Do Through a ClickOnce Install
Julie Lerman has a nice post about creating a desktop icon as part of a ClickOnce install - a fairly common question / request, and very representative of the kinds of "custom" things people would like to be able to do as part of a ClickOnce installation.
There were specific discussions about the option to create a desktop icon in some design reviews in Redmond I took part in several years ago. If I remember correctly, that one was dismissed mostly because it is discouraged to add desktop shortcuts as part of an install, especially without prompting the user to let them choose.
But part of this kind of desire really comes back to understanding the trust model of ClickOnce in general.
The trust issues of ClickOnce are twofold:
1. ClickOnce should not make any modifications to the local machine at install time that could affect other applications or data on the machine.
2. ClickOnce should provide runtime protections to avoid allowing the application to do harm to the local machine.
For #1, this means that you cannot install things to the GAC, add things to the registry, put things in specific places in the file system, etc. Any of those things could affect other apps and users on the machine, which means that administrators are not going to trust low-privilege users to perform ClickOnce installs. As a result, the model will not get adopted in enterprise environments, which is the primary target environment for ClickOnce - to replace those darn intranet web apps that companies create for ease of maintenance with smart client apps that give the user a better experience but are just as easy to maintain because of ClickOnce.
So the bottom line for #1 is that the only forms of customization you have available to you directly through ClickOnce is specifying:
- Whether the app is available offline (meaning you get a Start menu item and an Add or Remove Programs item)
- When updates checks will occur
- What the publisher name is - which sets what the program group in the Start menu is
- What the application name is - which sets the name of the program in the Start menu and Add or Remove Programs
- What the application icon is - through the Visual Studio application settings, and used for the icon in the Start menu item and Add or Remove Programs
There are a number of other assorted options you can set through the Publish tab, but they all really affect how the publication and deployment occurs, but none are in the form of explicit control over what goes where.
For #2 - You specify what runtime permissions the application will have as part of its publish settings (through the Security tab in VS), which end up as a list of required permissions in the application manifest. If those permissions exceed what the application would be granted by Code Access Security at runtime based on the zone of the launch URL (Internet, LocalIntranet, MyComputer, TrustedSites, or RestrictedSites), then the permissions have to be elevated either through user prompting (the default, ClickTwice experience) or through the trusted publishers capability of ClickOnce.
The fact is that you can overcome or workaround any limitations caused by #1 by exploiting #2. If you request full trust for your application, code in your application can do whatever you want it to do when your application first starts up. However, this requires one big assumption - you are also assuming the user who is running your application has sufficient privilege to do whatever it is that your code will try to do. This violates one of the goals of ClickOnce - to provide a deployment mechanism that can be used by low privilege users. So if you write some custom code in your app that tries to create a registry key - your app will have to have Registry permission through ClickOnce, and the user will have to have permission to create a key wherever your app is trying to create it.
As Julie points out, to create the Desktop icon with your own code, the user doesn't need any special permissions because anyone can add a shortcut to their own desktop, but you will need several high trust permissions including unmanaged code execution, which basically means most people will just elevate the application to full trust to get it done. Elevating to full trust is definitely something to avoid if you can.
The recommended way of addressing a lot of scenarios that would require high-privilege custom startup code is to create those things through the Bootstrapper as a prerequisite. A desktop icon is not really a good candidate for that, but pre-deploying something like GAC components is. Making something a prerequisite may allow you to avoid requiring full trust for your application.
However, the dirty little truth about Full Trust is that even though you should always try to avoid jumping all the way to full trust, there are many things that you will likely need to do in any meaningful ClickOnce app that will require you to go to full trust. Examples include:
- Using the ClickOnce API ApplicationDeployment class for just about anything, such as checking if this is the first run of a given version to execute your custom code, or to perform on demand updates.
- Using WCF for remote communications
- Using Windows Workflow in your Windows Forms application
One way to add protections back into your application even if you do have to request full trust for the application as a whole is to have sections of code where you restrict permissions below that level. You can do this through Code Access Security IStackWalk modifiers to Deny certain permissions or PermitOnly certain permissions. You can do this to bracket out a section of code (for example where you call out to some third party component to make sure that they are not doing something like reading/writing from your disk or sending information over the web for data /intelligence collection purposes). The details for doing this are too involved for this post, but I do cover it in my upcoming ClickOnce book and the underpinnings from a CAS perspective are covered well in my colleague Juval Lowy's Programming .NET Components, Second Edition.
Friday, May 26, 2006
CAPICOM Build Error on ClickOnce Publishing
I was working with Paul Sheriff of PDSA this week to ClickOnce deploy a reporting tool we use for the Regional Directors program. We ran into a problem where we got the following error when we tried to publish:
The resolution was to obtain the correct version of the CAPICOM.dll, drop it into the \SDK\bin directory where the SignTool.exe lives (C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin with a default VS install), and then register the library with Regsvr32.exe). Since it is a COM library for the CryptoAPI, it can actually live anywhere on your machine once it is registered.
Not sure how this was not there on the machine in question, it normally gets installed and registered when you install VS according to the ClickOnce product team folks.
Saturday, May 20, 2006
Manually Putting a ClickOnce Application into Production
Slides and Demos from SDC Netherlands
A common question with respect to ClickOnce is how to take an application that you have published and tested on your local machine or a local development server and move that application into production. The steps involved are not particularly complex, but do involve using some other tools to get it done and are not easy to figure out on your own unless you have a solid understanding of ClickOnce manifests, signing, and how they relate to the launch mechanisms of ClickOnce.
A key pre-requisite for doing this is that the administrator who will be placing the application on the target machine will need to have the publisher certificate that will be used to sign the production application available. Usually in large organizations the developers will not have access to the company's real certificate to do their development anyway, it will be up to the IT Administrator to get that certificate and do the final signing of the applications anyway.
Step 1: Move your application files to the target machine.
Assuming you have published your application with Visual Studio to your local machine or another test server in your development environment, the application files are contained in the virtual directory or folder that you specified as the Publish Location within Visual Studio. The deployment manifest, Bootstrapper setup.exe, publish.htm deployment page, and version specific deployment manifests are located in the root folder. For each version you published to that location, there is a subfolder that contains the application manifest and application files for that version. You might do this by zipping up the appropriate files and folders and just giving the zip file to the administrator who will put it into production.
To move the current version into production, you will need to copy the deployment manifest, setup.exe, version-specific manifest and sub-folder for the version you want to publish to the target machine deployment folder. You only need to include the publish.htm file if you intend to use that test page directly to expose the application to end users. But if you are going to put a link to the deployment manifest in some other page or send a link via email, you don't need to include the publish.htm page.
Step 2 (Optional): Make needed changes to application files
If you need to change something in the application files, such as changing a setting in the application configuration file or updating some graphics files, you will need to update the application manifest after modifying the application files themselves. So make the modifications needed in your application files.
Step 3: (Only needed if you did step 2): Update the application manifest file list
If you made any changes to any application files, you will need to refresh the list of files contained in the application manifest. This is because the manifest contains the hash for each file that provides a unique representation of the contents of the file. If you changed the application file, the hash for that file that is in the application manifest is no longer valid and needs to be updated.
- Open the application manifest (.manifest file in the application files folder for the version you are publishing) with mageui.exe.
- Select the Files category in the list on the left side of the window.
- Enter the path to the application files folder for the deployment on the right side.
- You can press the ellipses (...) button to browse to the folder.
This step does not have to be done on the target machine because only relative paths are stored in the manifest from the location of the manifest, but the manifest and the application files need to be located with the same relative folder path as they will be on the target machine (usually the same directory).
- After you have entered the path to the folder, press the Populate button.
-You will be prompted with a warning dialog about the fact that the files will be renamed with a .deploy extension.
- Click Yes in this dialog.
Step 4: Sign the application manifest
If you make any changes to the application files and update the application manifest as described in step 3, or if you just need to re-sign the application manifest with a production certificate that is different than the one that was used in development, then you will need to sign the manifest with Mage. To do so:
- Open the .manifest file with mageui.exe if not already open from step 3.
- Press the Save button in the toolbar, and you will be presented with the signing dialog shown below.
- Provide the path to the certificate file and the certificate password at the top of the dialog, or select the certificate from your personal certificate store at the bottom of the dialog.
- Click OK to sign the manifest with the selected certificate.
Step 5: Update the application manifest reference in the deployment manifest
If you performed step 4 and signed with a different certificate than the one used to
originally generate the deployment manifest, you now need to update the application reference in the deployment manifest. The application reference is a strong reference to the application manifest from the deployment manifest, including path information as well as the public key token from the digital signature in the application manifest. That signature is generated using the publisher certificate, so if you change the certificate, you have to update the application reference.
To update the application reference, do the following:
- Open the deployment manifest (.application file) in mageui.exe
- Select Application Reference from the list of categories on the left of the window
- Press the Select Manifest... button and navigate to the application manifest (.manifest file) for the version that you are deploying.
Step 6: Update the Deployment Provider
If you are moving the application to a different server than the one where you first published the application from Visual Studio, you will need to update the deployment provider URL that is embedded in the deployment manifest. To do so, perform the following steps:
- Open the deployment manifest in mageui.exe if it is not already opened from step 5.
- Select Deployment Options from the list of categories on the left side of the window.
- Change the URL labeled Start Location to reflect the URL users will use to launch the application from the client machine. This setting is saved as the deployment provider in the deployment manifest.
Step 7: Sign the deployment manifest
- Click the Save button in the toolbar.
- Enter the path and password for the publisher certificate file at the top of the signing dialog, or select the certificate from the list of certificates at the bottom. This should be the same certificate used to sign the application manifest.
- Click OK to re-sign the manifest.
At this point, your application should be ready to go from the client.
I gave four talks at the Software Developers Conference in Netherlands this week. This is a very fun and interesting conference that is put on by a large user group organization called Software Developers Network, run by Remi Caron and Joop Pecht.
This conference is one of the most enjoyable conferences I get to do anywhere in the world. It is amazing how professional and well run this conference is, especially when you consider that it is being put on by a user group organization and it is better run than many U.S. conferences put on by companies that are supposed to specialize in this kind of event. All of the user group members that run the conference are volunteers, and yet the quality and professionalism that comes out of that is outstanding.
The attendees are hard core, ask great questions, and make the event fun for the speakers as well. For those of you who attended and find your way to this post for the slides and demos - thanks!
You can grab the slides and demos here:
Build Smart Client Data Apps with Windows Forms 2.0: Slides Demos
Build Custom Data Bound Objects and Collections: Slides Demos
Present Rich Tabular Data with the DataGridView Control: Slides Demos
Drive Application Behavior with Application and User Settings: Slides Demos
Saturday, May 13, 2006
DevTeach Slides and Demos
I spoke at DevTeach in Montreal Tue-Thu of this week and had a great time as always. If you haven't checked out this conference, you should plan on signing up next year. Great location, great speakers, very well done conference with lots of hard core sessions.
If you attended one of my sessions and want to get the slides and demos, here you go:
NET371 - Drive App Behavior with Application and User Settings: Slides Demos
NET391 - Custom Bound Objects and Collections: Slides Demos
NET463 - Advanced ClickOnce: Slides Demos
MusicLibrary Database Creation Script: Script
Saturday, April 15, 2006
Process Identity and Working Directory for Partial Trust ClickOnce Apps
People always ask me "How can you write a whole book on ClickOnce?" because they envision the standard 5 minute demo of what ClickOnce is and does and think that is all there is to it. The fact is there is just a plethora of variations, hidden behaviors, specialized scenarios, and things people want to do with ClickOnce that are far more than 5 minute answers. The book keeps growing the more I get into it.
One of these things that snuck up and bit me recently (unfortunately in a live demo at VS Connections) due to a gap in my knowledge was the way partial trust apps run on the client machine.
First some background on ClickOnce and application files. Any file you add to your project and set the file Build Action property to Content will be added to the Application Files (under the Publish tab in project properties) with a Publish Status of Include, depending on the file type. MDF files (SQL Express), mdb, and XML files will get marked as Data Files instead of Include. Include means the file will be deployed to the application client cache folder under the user profile (C:\Documents and Settings\<username>\Local Settings\Apps\<obfuscated goo>\), and Data File means it will be deployed to a separate data folder associated with that app, also buried in the obfuscated goo under the user profile. The data files are treated differently for updates (beyond the scope of this post) and the folder is accessible through the ApplicationDeployment.DataDirectory property.
If you deploy an app with ClickOnce, and the app manifest requests Full Trust, then when the app runs it simply gets launched by the runtime directly - the app executable is the executable process that runs. It runs from the deployed client cache directory. As a result, with a full trust app, you can access files that you deploy with your app, marked with a Publish Status of Include, with a relative path such as ".\MyImage.jpg". The current working directory when your executable starts is the folder it was launched from, and so everything works out.
Then you decide that you want to be more security concious, and switch your ClickOnce security settings to only require partial trust (lets say LocalIntranet zone). Suddenly your app stops working complaining that it can't find the file.
So what's going on there??
The problem is that the executable process is actually different when you run a ClickOnce app under partial trust. When you configure a ClickOnce deployed app to request less than full trust, the process that actually launches is AppLaunch.exe. This process loads your executable assembly into an AppDomain which it has cranked down the CAS security on to your requested permissions, and your app runs from that appdomain under partial trust. This is similar to what Visual Studio 2005 does to enable partial trust debugging with the <appname>.vshost.exe that is the debug process by default.
So how does that screw up your paths? AppLaunch.exe is running from the .NET directory under C:\WINDOWS\Microsoft.Net\Framework\v2.0.50727\, and so the current working directory for your app loaded into that host process is that folder. Naturally your application files have not been deployed there, so your relative paths for locating the files fail.
OK, so next thought is "there's gotta be an API that I can call to say 'give me my app's deployed directory'". Unfortunately, that thought would be incorrect.
So what's the solution? Simple - don't ever deploy a file to the application directory (Publish Status = Include) that you need to access explicitly through a path (i.e. to load that file as a bitmap, xml file, etc.). If you need to do that, you should mark it as a Data File, and access it by adding the file name to the ApplicationDeployment.DataDirectory path. You can also use Application.UserAppDataPath property, results in the same thing when you are ClickOnce deployed.
Just wish I had known that before doing that demo on the fly in a way I had not done it before in front of a live audience... :)
Tuesday, April 11, 2006
Friday, February 24, 2006
.NET Rocks and DNRtv episodes up
I recorded a DNR and DNRtv last week in New London and they are already up on the site.
You can download/listen to the .NET Rocks! epsidode here: http://www.dotnetrocks.com
And the DNRtv here: http://www.dnrtv.com
In the DNR episode, we talk about data binding, ClickOnce and a few other related topics.
This DNRtv shows how to do some of the data binding stuff in the designer. Keep your eyes out for another episode in a week or so on ClickOnce deployment.
Monday, February 20, 2006
Wednesday, November 30, 2005
Launching unmanaged applications with ClickOnce
Demos from ClickOnce MSDN Webcast
The question came up from several attendees at my MSDN Webcast on ClickOnce yesterday:
"Can I launch a XXX application using ClickOnce?" (fill in XXX with VB6, MFC, etc. - non-.NET applications)
The answer is yes, you will just have to employ a little trick.
What you need is a simple little launcher application that IS a Windows .NET application. So do the following:
- Create a new Windows Application project with VS 2005.
- Delete the Form1 from the project.
- Add the unmanaged EXE and any supporting files to the VS 2005 project, which makes them part of this application from a ClickOnce perspective. As a result, they will get deployed with this application to its cache folder and can be executed by this launcher app.
- Edit the Program.cs file Main method and delete the current method body (which launches the application and the form) and replace it with code to launch the unmanaged executable. This just requires a single line of code: Process.Start("MyUnamangedApp.exe");
Note: You will need to give the launcher app full trust in the ClickOnce security settings.
Note2: If the unmanaged app relies on ActiveX or COM objects, those need to be added to the project as well, and you will need to add a reference to the COM DLL's to the project to get their reg-free COM information added to the manifest. See this article for more details.
You can download a sample implementation here.
For those who attended or are interested, here are the demos from my MSDN Webcast on ClickOnce yesterday.
You can find the webcast link for on-demand viewing here.
For the demo that went awry demonstrating on-demand updates, the little mistake I made was that I said that if you turn off automatic updates (Check for updates option at top of Updates dialog), then you need to put in an Update location, which is true. But what I was doing was fully qualifying the path to the deployment manifest, which is incorrect. What you need to put is just the URL to the root folder where the deployment manifest resides. VS will automatically append the deployment manifest file name. So when I was putting in:
I should have just been putting
Another little tidbit I didn't mention is that you will need Full Trust for on-demand updates, which is unfortunate because it means the app has to request full trust even though it may not be doing anything privileged beyond on-demand updates.
Friday, November 11, 2005
Secure ClickOnce Demployment Talk at DevConnections yesterday
My second session of the day yesterday at DevConnections was on ClickOnce deployments, and specifically the various security protections and options that ClickOnce offers for preventing unauthorized applications from being able to run through a ClickOnce launch.
You can grab the slides and demos here: Slides Demos
Some of the key takeaways from this session were the following:
If you want to prevent the user from ever being prompted and only allow applications from trusted publishers to be launched through ClickOnce (a good idea in an enterprise environment), then you should create the registry key discussed in the slides from the session and set the string values to Disabled for all the zones.
- ClickOnce provides a simple, powerful, and easy to use mechanism for deploying smart client applications with minimal maintenance effort and IT Admin involvement
- ClickOnce provides runtime security protections through the Code Access Security (CAS) infrastructure of .NET to prevent applications launched from ClickOnce from being granted permissions to perform any operations or access any resources that the application was not specifically allowed to do.
- ClickOnce app default permissions are determined by the launch URL and how it maps to built-in CAS location-based code groups (MyComputer, LocalIntranet, Internet, TrustedSites, UntrustedSites).
- If the application manifest requests permissions greater than those that would be granted based on the CAS location-based code groups, permission elevation needs to occur.
- By default, permissions can be elevated in one of two ways: user prompting or trusted publishers.
- If an application is launched through a link to a deployment manifest that is signed by a publisher certificate that is not in the Trusted Publishers certificate store on the client machine, the user will be prompted by default and can accept or reject the application. If they accept it, the permissions for that application will be elevated to whatever permissions the application manifest has requested.
- If an application is launched that was signed with a publisher certificate that is in the client machine's Trusted Publishers certificate store, then no user prompting will occur and the application permissions will be automatically elevated to whatever the application manifest requests because it is coming from a trusted source identified implicitly by IT admin when they installed the publisher certificate in the Trusted Publishers store.
Wednesday, November 9, 2005
Monday, October 24, 2005
Upcoming DevConnections Talks
Two Upcoming MSDN Webcasts: Part of the "Best Of" Series
I'll be speaking at Visual Studio Connections (part of DevConnections) in Las Vegas from 5-8 November. This is a great and growing conference that happens twice annually in the US, usually Orlando in the spring and Las Vegas in the fall, that I have been privileged to speak at for the last couple years. If you haven't been to one yet, you ought to be hammering your boss for permisson/funding to attend for the following reasons:
- It will rapidly and time-effectively expose you to new solution technologies you might not get a chance to explore on your own
- You will get concentrated advanced training in current and future technologies, getting you up to speed on them in far less time than you can achieve on your own
- You will get presentations from the top speakers in the business
- You will get a chance to network with peers in the industry, learn from others experiences employing .NET technologies, which will make you more effective at employing them yourself
- You will have a lot of fun (OK, maybe don't tell your boss this...)
You can learn a lot peripherally from the conference too by reading the DevConnections blog here. There are posts from other speakers as they develop their talks and their own observations and experiences at the conference.
I'll be presenting the following sessions:
VSM356: Build Custom Data Bound Business Objects and Collections
VSM351: Secure Smart Client ClickOnce Deployments
VID306: Build Event-Driven Applications with Indigo
VID309: Connect Smart Client Applications with Indigo
If you make it to the show (and you should!!), stop by and say hi!
I've got two MSDN Webcasts coming up at the end of November, both part of the "Best Of" series that they are doing surrounding the launch of VS 2005 for those Webcasts focused on .NET 2.0 and VS 2005 that got the highest scores in the last year.
You can click through here to get to the webcasts:
The two I am giving will both be on 29 November:
Presenting Rich Rich Tabular Data with the DataGridView Control
Tuesday, November 29, 2005
10:00 A.M.–11:00 A.M. Pacific Time
Deploy Smart Client Applications with ClickOnce
Tuesday, November 29, 2005
1:00 P.M.–2:00 P.M. Pacific Time
Check them out!!
Thursday, September 29, 2005
On-Demand Updates with ClickOnce
Smart Client Deployment with ClickOnce talks in St. Louis and KC
ClickOnce supports both automatic updating and on-demand updates. The default model checks for updates automatically at application launch (when connected), and applies those updates immediately. There are a number of options available for installed applications (available online and offline), including whether to check automatically at all, whether to do it on a background thread, whether to do it on a timed interval, and other options.
However, sometimes you may want to do updates on demand, either as the only update model, or in combination with automatic updating in the background on a periodic interval. To do that, you will need to use the ClickOnce API defined in the System.Deployment framework assembly.
The main class you will use to support on-demand updates is the ApplicationDeployment class defined in the System.Deployment.Application. You will typically add code in response to a user action (such as selecting a Check For Updates menu item) that goes out and checks to see if updates are available, and if so retrieves them. You will then need to restart the application to have those changes applied.
A simple but common pattern to accomplish this is something like the following:
// First check to see if we are running in a ClickOnce context
// Get an instance of the deployment
ApplicationDeployment deployment = ApplicationDeployment.CurrentDeployment;
// Check to see if updates are available
DialogResult res = MessageBox.Show("A new version of the
application is available, do you want to update?",
"Application Updater", MessageBoxButtons.YesNo);
if (res == DialogResult.Yes)
// Do the update
DialogResult res2 = MessageBox.Show("Update complete, do you
want to restart the application to apply the update?",
"Application Updater", MessageBoxButtons.YesNo);
if (res2 == DialogResult.Yes)
// Restart the application to apply the update
MessageBox.Show("No updates available.", "Application Updater");
MessageBox.Show("Updates not allowed unless you are launched through ClickOnce.");
There are of course asynchronous versions of the CheckForUpdate and Update methods if you want to avoid blocking your UI while this happens.
The project settings you will need may not be completely apparent. The first important setting is that you need to change the update behavior of the ClickOnce deployment to stop automatically checking for updates if you are doing only on-demand updates. You do this through the Publish tab of the project properties settings, Updates button, shown in Figure 1.
Figure 1: ClickOnce Update Behavior Settings access
When you click that button, the dialog in Figure 2 will show with default settings selected as shown.
Figure 2: ClickOnce Update Settings Dialog
What you will want to do for a pure on-demand updates application is to uncheck the box that says the application should check for updates at the top. The other trick that is not apparent but required is that you have to specify an Update location at the bottom or you will get an obscure error message when you try to launch the application on the client. So you should set up the update settings like shown in Figure 3.
Figure 3: ClickOnce On-Demand Update Settings
With those settings in place, when you publish your application out and the client launches it, they can invoke the code shown earlier to check for and apply updates on-demand.
If you wanted to combine on-demand updates with periodic background checking for updates, you can do that by leaving updates enabled, but you will need to select the option to check for updates after the application starts. You will then want to configure the frequency of checking using the options in the middle of the dialog.
I gave a talk on ClickOnce in both St. Louis and Kansas City Monday and Tuesday evening this week and had a really good time. After the St. Louis talk I was able to go out for a beer with Bill Evjan, Scott Spradlin, and some of the other group members, which is always a great chance to network while I am there. KC was more of a quick strike since I had to fly out first thing in the morning to head to the MVP summit in Seattle.
The code samples and slides can be downloaded here.
Tuesday, August 30, 2005
Data Binding in Windows Forms 2.0 - Final Manuscript Done!
Phew! After a year and a half of trying to keep pace with the changing betas and writing the book on top of a full schedule of consulting, training, and speaking at conferences and user groups, I am finally done. I submitted the final manuscript to production on Friday. Now I just have to respond to any questions and reviews during the production phase, convert the code samples to VB for download, and I can call this one a wrap.
You can order the book here (available January 2006):
We will have a teaser chapter out at PDC that will also be available for download as a PDF containing part of the chapter on the DataGridView control. I'll put up a link to that as soon as it is available.
Now I am start devoting my attention to my next book, Smart Client Deployment with ClickOnce, also part of the Addison Wesley .NET Development series. I hope to knock this one out in the next 6 months, so it should hit the shelves mid 2006.
|June, 2013 (1)
|May, 2013 (2)
|April, 2013 (2)
|March, 2013 (2)
|February, 2013 (2)
|January, 2013 (2)
|December, 2012 (3)
|November, 2012 (1)
|October, 2012 (1)
|August, 2012 (2)
|June, 2012 (2)
|May, 2012 (3)
|April, 2012 (1)
|March, 2012 (2)
|February, 2012 (2)
|January, 2012 (1)
|November, 2011 (4)
|October, 2011 (1)
|September, 2011 (2)
|August, 2011 (1)
|July, 2011 (1)
|May, 2011 (5)
|March, 2011 (4)
|February, 2011 (2)
|January, 2011 (3)
|November, 2010 (4)
|October, 2010 (1)
|September, 2010 (5)
|August, 2010 (5)
|July, 2010 (6)
|June, 2010 (8)
|May, 2010 (2)
|April, 2010 (2)
|January, 2010 (1)
|December, 2009 (3)
|November, 2009 (2)
|October, 2009 (3)
|September, 2009 (3)
|August, 2009 (2)
|July, 2009 (3)
|May, 2009 (3)
|April, 2009 (2)
|March, 2009 (1)
|February, 2009 (2)
|January, 2009 (2)
|December, 2008 (1)
|November, 2008 (2)
|October, 2008 (5)
|September, 2008 (4)
|August, 2008 (2)
|July, 2008 (1)
|June, 2008 (2)
|May, 2008 (2)
|April, 2008 (3)
|February, 2008 (6)
|January, 2008 (3)
|December, 2007 (1)
|November, 2007 (1)
|October, 2007 (5)
|September, 2007 (1)
|July, 2007 (3)
|June, 2007 (8)
|April, 2007 (2)
|March, 2007 (4)
|February, 2007 (1)
|December, 2006 (2)
|November, 2006 (9)
|October, 2006 (5)
|September, 2006 (3)
|August, 2006 (2)
|July, 2006 (4)
|June, 2006 (5)
|May, 2006 (10)
|April, 2006 (4)
|March, 2006 (2)
|February, 2006 (12)
|January, 2006 (7)
|December, 2005 (2)
|November, 2005 (15)
|October, 2005 (6)
|September, 2005 (7)
|August, 2005 (3)
|July, 2005 (10)
|June, 2005 (11)
|May, 2005 (7)
|April, 2005 (8)
|March, 2005 (6)
|February, 2005 (2)
|January, 2005 (6)
|December, 2004 (3)
|November, 2004 (5)
|October, 2004 (2)
|September, 2004 (5)
|August, 2004 (13)
|July, 2004 (6)
|June, 2004 (14)
|May, 2004 (17)
|April, 2004 (12)
|March, 2004 (8)
|February, 2004 (10)
|January, 2004 (14)
|December, 2003 (9)
|November, 2003 (13)
|October, 2003 (3)