Now that I've released a version of DUAScriptGen that can be used to create DUA scripts directly from Windows hotfixes, I thought it might be useful to illustrate the process of creating a script using this new functionality.

Downloading hotfixes and DUAScriptGen

The first part of this process is to download the hotfix you want to install as well as the DUAScriptGen tool. Here are the steps:

Extract the contents of the hotfix to a folder on your local computer. Most Windows hotfixes can be extracted by running <name of hotfix setup executable> /x:<local folder>

Download a copy of DUAScriptGen that contains INF parsing functionality. Currently you can get a beta version of DUAScriptGen with this functionality here. The "official" version of DUAScriptGen (located here) will eventually be updated to include this functionality as well once beta testing is completed and any necessary bug fixes are made.

Using DUAScriptGen in UI mode

Now that you have downloaded the hotfix and DUAScriptGen tool, you are ready to create your DUA script. If you prefer to use the DUAScriptGen UI you can use the following steps:

Run DUAScriptGen.exe, configure your DUA settings preferences (if this is the first time you have run DUAScriptGen on your computer), and then click the Convert INF to DUA button

Browse to the folder that you extracted the Windows hotfix to in step 3 above, then navigate to the Update subfolder. Choose the file named update_SP2QFE.inf and click Open to load it into the DUAScriptGen UI

Verify that all of the file and registry settings are correct and click Generate Script to create a DUA script (DUS) file

Click Execute Compiler to compile the DUS file into a DUP file

Test deploying this DUP file on your devices

Using DUAScriptGen in silent mode

If you prefer to script creation of the DUS file and not interact with the DUAScriptGen UI, you can use the following steps:

Open a cmd prompt

Run DUAScriptGen.exe /i <local folder>\update\update_SP2QFE.inf /o <path to DUS file> (where <local folder> is the same folder that you extracted the Windows hotfix to in step 3 above)

Compile the DUS file by running c:\Program Files\Windows Embedded\bin\dusc.exe <path to DUS file> <path to DUP file> (where <path to DUS file> is the same file you used for the /o parameter for DUAScriptGen in step 2 above)

I've gotten some email questions from customers about setup failures that they've seen on their computers. Some of them are 1935 errors that match some of the previous blog posts I've written, some are .NET Framework errors, and some are general problems getting some program installed.

I cannot guarantee that I will be able to help solve all setup-related problems you may encounter, but I can guarantee that I will take a look and try to help if I can. In order to do so I would like to ask that you try to gather some detailed information and send it to me if you contact me via email to aid in troubleshooting and debugging:

As much detail about the error message as possible, including the full text of any error messages.

Any troubleshooting steps that you have already tried, including links to any of my other blog posts that you've already tried.

Most importantly - log files from the setup if at all possible. You can zip and upload log files to a file server of your choice and include a link to the log files when you contact me. My preference is http://skydrive.live.com because it is free, gives you a lot of storage space, and doesn't contain annoying ads to try to get you to pay for "premium" services like faster download speeds.

Most setups are Windows Installer MSIs. For those products, you can enable verbose logging by setting a couple of registry values and then reproducing the problem. Here are a set of steps you can use to gather a Windows Installer verbose log file:

Important note - some MSI-based setups, including the .NET Framework 2.0, 3.0, 3.5 and higher, will not create log files named %temp%\msi*.log even if using the instructions listed below. Please see this blog post for more details about why that is the case and also for a list of some products that I know of that use different log file creation logic and the locations of the log files that they create.

If you are running Windows XP or older: Click on the Start menu, choose Run, type cmd and click OK

If you are running Windows Vista or newer: Click on the Start menu, choose All Programs, then Accessories, then right-click on the item named Command prompt and choose Run as administrator

<update date="2/27/2008"> Added a link to a new blog post with information about some products that create their own verbose log files and therefore do not create %temp%\msi*.log, even when the verbose logging policy is enabled on the system. </update>

<update date="11/17/2011"> Added clarifications to steps 2 and 3 to indicate that the commands need to be run separately, not as a single command. Also added a note about running as administrator on Windows Vista or later. </update>

Hey all, some of you probably saw that I released a beta version of DUAScriptGen v1.1 a couple of weeks ago with a new feature allowing you to parse and import Windows hotfix INF files to create DUA script files from. I have added an additional feature that enables command line parameters so you can call DUAScriptGen silently from build scripts to generate DUS files without having to interact with the UI. To use this feature you need to run DUAScriptGen.exe with the following command line parameters:

For example, you can run the following to parse c:\dua\update.inf and create c:\dua\update.dus:

DUAScriptGen.exe /i c:\dua\update.inf /o c:\dua\update.dus

I have posted an updated downloadable package here. Please give it a try if you get a chance and send me any feedback you have about these new features, or any bugs or suggestions you have for other features as well.

Hey all, I found a couple of documents that were posted this past Monday March 21 that give more details about migrating to Visual Studio 2005 and specifically to the new VS 2005 Team System for enterprise-level development lifecycle management, project management, architecture and testing. You can go to this site to look at a set of pricing options the various versions of Visual Studio 2005 that will be available. You can also go to this site to look at various MSDN subscription options that will allow you to upgrade to VS 2005 Team System products.

You can also go here to see more details about the various components that will be a part of the VS 2005 Team System. I'm especially excited to see that we're creating tools targeted specifically towards testers in this version of VS. When I first switched from the Visual Studio setup team over to Windows Embedded, I got invited to participate in a usability study for some of the test tools. I guess they thought that I was less biased since I wasn't working on the Visual Studio team anymore, or something like that. At any rate, even back then when a lot of the features hadn't yet been implemented it was impressive to see the tight integration of the experiences of writing code and writing, scheduling and running unit tests for that code. I haven't had a chance to try out the features since that usability study, but with beta 2 getting pretty close to releasing I will definitely have to check it out again and see how far things have come since last year.

One of the coolest new embedded enabling features we introduced in XP Embedded SP2 is hibernate once resume many (HORM). It provides the ability to more rapidly boot an embedded system as long as the system is protected by enhanced write filter (EWF). Since SP2 shipped we have gotten a lot of questions from customers about HORM and EWF. In particular, many folks have wanted to know if it is possible to use HORM without the limitation that EWF is enabled for all partitions on a system. This would be useful, for example, if you have a jukebox device and want to store your music and playlists on a separate data volume and not necessarily protect that volume with EWF.

Our team has written a really good in-depth document about how to programatically dismount volumes in EWF and HORM scenarios so that you will not have to protect all volumes with EWF. It even includes some sample code to show how to dismount volumes in C. You can check it out by clicking here.

Hopefully this will be useful in your scenarios. If you try this strategy out please let us know how it works for you and also contact us via my blog or the embedded team blog if you run into any issues.

My manager (Andy Allred) has created a blog that the Windows Embedded team as a whole will use in the future to communicate with customers of Windows XP Embedded and eventually Longhorn Embedded. You can check out the blog here. We're still working out the logistics of how we'll share ownership of the blog and postings and things like that, but be on the lookout for more in-depth, embedded-specific content there in the near future. Of course, I'll also continue to maintain my own blog, but I'll likely post the more detailed embedded items (like this and this) on the new site in the future and just provide a cross-link from my page so we can keep the technical embedded content in a centralized location.

I found an interesting press release from KUKA Controls announcing support for XP Embedded with SP2 and specifically hibernate once, resume many (HORM) in the next version of their VxWin product. You can check out the press release here.

I have been working on an update to DUAScriptGen to support a new scenario - downloading a Windows hotfix package, parsing the INF file and converting it into a DUA script (DUS) file. I have had this work item on my list for a long time but just hadn't gotten time to look at it. Then as I was working through the steps required to install the .NET Framework hotfix MS05-004 on an embedded device, I realized how useful it would be to have this feature. I have done the initial development and some testing of this feature on my own, but I would also like to open it up to anyone who is currently using DUAScriptGen or would like to evaluate using it in the future.

You can find a beta version of the updated DUAScriptGen v1.1 by clicking on this link. I have included all of the files you will need in the package, including an updated User's Guide.

Please try it out and let me know if you run into any problems or have any additional feature suggestions for DUAScriptGen.

I want to caveat everything I am about to say by explaining that in general, I think managed code is great and not just because I work at Microsoft :-) It offers developers the power of modern object-oriented languages while allowing for rapid development for small and large scale projects. In fact, I have basically spent my entire career trying to make it as easy as possible for everyone to deploy the .NET Framework as part of OEM-manufactured machines or managed applications - and yes I know there is still a lot of work for us to do in this space.

But I also believe that managed code is not the best choice for certain types of development, and setup is one of those places. The biggest concern I have with managed code being used in custom action code is the additional dependency that it introduces to setup. If the underlying .NET Framework runtime is damaged it can lead to unpredictable results in a setup that would not occur if the custom actions were written as a native code DLL (or better yet, were eliminated in favor of standard Windows Installer actions).

I have also seen setup issues related to .NET Framework runtime migration policy. The policy of migrating managed apps to use the latest version of the .NET Framework on the machine (which is on by default in .NET 1.1 and 2.0) can cause your custom actions to run on top of a different version of the .NET Framework than you originally tested and shipped with.

We used some managed executables during setup in previous versions of the .NET Framework. Then in future versions of the .NET Framework we decided to set the default runtime migration policy so that any managed code running on the system would use the most recent version of the .NET Framework by default. In general, the .NET Framework is side-by-side compatible and apps written against one version will continue to run correctly against future versions. However, for specific functionality such as parsing configuration files or calling APIs that have had breaking changes introduced for security reasons, this may not hold true. It is possible to include a config file with a managed app to lock it in so it will require a specific version of the .NET Framework to run correctly. However, if you neglect to include a config file (like we have done in the past) that can potentially cause issues if/when your managed code is migrated to run on top of a later version of the runtime. Also, if you author a managed DLL custom action you leave your fate in the hands of Windows Installer, because it will use the latest version of the .NET Framework on the machine in all cases (as opposed to a custom action that calls an installed EXE which can also have a config file installed next to it).

As a side note here, if you install the .NET Framework 1.1 you will notice a couple of files installed to the v1.0.3705 folder instead of the v1.1.4322 folder. A couple of those files are intended to fix policy migration issues like the ones I just described. You will also see the .NET Framework 2.0 setup install a few files to the v1.0.3705 and the v1.1.4322 folder for the same reason.

So, in summary, I strongly encourage you to not use managed code in your product setup. I realize that some teams do this here at Microsoft, but please don't use our bad (in my opinion) examples to justify doing so in your own setup....

One important thing to keep in mind here is that the setup wrapper package for this Visual Studio .NET 2002 service pack is the same wrapper that is used for .NET Framework service packs. So it is susceptible to the same class of problems that customers have been seeing installing .NET Framework service packs and hotfixes. A couple of my previous blog posts give more information and troubleshooting tips in case you run into any issues (click here or here to go directly to them).

As always let me know if you run into any issues installing this Visual Studio service pack or have any comments/questions.

I posted an item on my blog last week with some details about how Windows Installer custom actions work behind the scenes. Some of the feedback I got back after posting this item asked some good questions about debugging strategies for custom actions. Based on that, I wanted to share a wrapper DLL written by Jungwook Bae, a developer on the Visual Studio and .NET Framework setup team. His tool makes the process of implementing and debugging DLL custom actions much simpler. You can download the tool itself by clicking here. The following is more information about the wrapper DLL and how to use it:

CATest - a tool that will help developing custom action DLLs

One of the biggest pains when writing custom actions is whenever you modify the DLL, you have to stream the new DLL into the MSI and restart setup. Deferred custom actions are the most difficult because you have to wait until all the files are copied and registry values are written again, which can take a very long time for large products.

To get around this problem, you can use catest.dll as a wrapper for the custom action DLL you are writing. You can test your custom action DLL without streaming it into your MSI, and you can run it as many times you want without restarting setup.

How to use CATest:

Add catest.dll to the binary table of your MSI (by using Orca or some other tool)

Share out your build folder so that your DLL and PDBs are accessible from a test machine

Modify catest.ini to match your custom action name, path to DLL and EntryPoint. You can debug the following 4 types of custom actions: Immediate, Deferred, Rollback, and Commit. You do not need to include all 4 sections in catest.ini; instead you can include only the ones you want to test.

Copy modified catest.ini to %windir% on the machine we are testing.

Modify the custom action records in the CustomAction table of your MSI to point to catest for each of the custom actions you want to debug. Each custom action you want to be able to debug should have "catest" as the Source value and the Target value, and should match the custom actions that you list in catest.ini.

Now you are ready to go, so run the setup. When prompted to attach a debugger, you can attach your favorite debugger and click OK. Then, you can load your symbols and open source files to step through the code. When the custom action finishes, a dialog will ask if you want to retry the custom action. You can update your code and rebuild the DLL, then choose to retry the custom action and debug it again within the same installation session. Note: you will have to reload your symbols if you rebuild and rerun the custom action.

I have heard from a couple of customers who are trying to create a Windows Installer administrative install point that contains the .NET Framework with a service pack and the latest hotfix (MS05-004). I originally posted instructions about how to create an admin install point for the .NET Framework 1.0 or 1.1 and a service pack, but there are a couple of extra steps and tricks needed to also include a hotfix, so I wanted to post updated instructions. Here are a set of steps that I used to create an administrative install point on my machine and install the .NET Framework 1.0 or 1.1 and a service pack and a hotfix as a single package:

Extract the service pack MSP package to a folder by running <name of service pack>.exe /Xp:c:\dotnet\netfxsp.msp

Run msiexec.exe /a c:\dotnet\netfx.msi /p c:\dotnet\netfxsp.msp

Locate the .NET Framework hotfix you want to install by going to the Microsoft download center and searching for the keyword security_patch and filtering based on the .NET product family. When I tried this recently, it gave me this results page

Download the correct version of the .NET Framework hotfix you want to install. Every .NET Framework hotfix ships with a separate version that will only install if you have a specific .NET Framework service pack installed. So you will need to download the hotfix that matches the service pack you downloaded in step 3 above

Extract the hotfix MSP package to a folder by running <name of hotfix>.exe /Xp:c:\dotnet\netfxhotfix.msp

Run msiexec.exe /a c:\dotnet\netfx.msi /p c:\dotnet\netfxhotfix.msp

Following these steps will create a Windows Installer administrative install point in the folder c:\dotnet that can be used to install the .NET Framework plus a service pack and a hotfix as a single unit. Now you can share out the folder for network installations or install directly from there in order to install the .NET Framework, the service pack and the hotfix at the same time.

As future hotfixes are released for the .NET Framework 1.0 or 1.1, you can repeat steps 6-9 above to apply them to your administrative install point.

<update date="6/15/2010"> Fixed broken HTML causing numbering problems for the steps in this post. Also clarified that these steps work for the .NET Framework 1.0 and 1.1 but not 2.0 or higher. </update>

As I'm sure some of you have already noticed, it is proving a bit difficult to install .NET Framework hotfixes (such as the recently released MS05-004 ASP.NET hotfix) on Windows XP Embedded devices. On my previous team, two of the setup packages I worked on were the .NET Framework 1.0 and 1.1 components for XP Embedded, so fortunately I have some background that I could use to figure out exactly how to get this to work. I used the following steps to patch some embedded runtimes on my office test machines and I wanted to share it with everyone:

Figure out the exact version of the .NET Framework you have (major and minor version plus service pack). If you are using the .NET Framework 1.0 component we shipped, it will be 1.0 SP2. If you are using the .NET Framework 1.1 component we shipped (either the original QFE version or the one that comes with XPE SP2), it will be 1.1. If you are using the .NET Framework 1.1 with SP1 component in the value-add folder of XPE SP2, it will be 1.1 SP1

Download the setup package for the hotfix that matches the version of the .NET Framework that you have in your embedded image (make sure you choose the "save" option instead of the "run" option because you need a copy of the exe on your local hard drive). You will notice that these packages say that they are for Tablet/Media Center or Windows Server 2003. That is OK and expected because the underlying setup technology we use to install the .NET Framework in our embedded components is the same as on those operating systems.

Extract the exe to a local folder by running <name of exe> /x:<folder>

Go to the folder that you extracted the .NET Framework hotfix to in the previous step and open each of the files named update*.inf in the update subfolder. There is a [Version] section at the top that you will need to change the following values for:

The values of MinNtServicePackVersion, MaxNtServicePackVersion and ThisServicePackVersion should match the data in the registry on your embedded device for the CSDVersion value at HKLM\System\CurrentControlSet \Control\Windows. For example, on Windows XP Embedded SP2 this value should be 512. This value represents the OS service pack level and each service pack is a multiple of 256.

If you have 1.0 SP2 or 1.1 SP1 installed in your embedded image you will need to add an additional registry value that the hotfix update package is checking for as a prerequisite (so if you have the 1.1 component you can skip this). You need to add a registry key named HKLM\Software\Microsoft\Updates \.NETFramework\1.0\SP2 or HKLM\Software\Microsoft\Updates \.NETFramework\1.1\SP1 and a REG_DWORD value named Installed with a value of 1 under this key.

Now you can run update.exe from the update subfolder on your embedded device assuming that your embedded device includes the dependencies update.exe needs to run correctly

As you can see, this process is fairly complicated so I am going to work on a way to generate a DUA script to install these hotfixes automatically. I am hoping to add support for this scenario to DuaScriptGen in the near future.

As always, please let me know if you have any questions about any of this or run into any trouble getting the steps to work.

I received a couple of interesting questions about custom actions in response to one of my previous blog entries. So I wanted to explain a little bit more about what is going on behind the scenes. I'm sure many of you have noticed that when a setup is in progress, there are multiple msiexec processes running on your system. You can use a process viewer such as tlist.exe or tasklist.exe to list the msiexec processes that are running on the system along with their command line parameters. Here are the various types of msiexec processes along with example command lines to help you distinguish between them:

msiexec /i <product>.msi /l*v install.log - this is the main MSI client process for an installation when it is in progress

msiexec.exe /V - this is the Windows Installer service process; the service name is msiserver; in general, the msiserver service will start when an installation begins, and the service will stay running for 10 minutes after the installation completes as an optimization so that the overhead of unloading and reloading the service data does not happen if setups are run one after another

msiexec.exe -Embedding <GUID> - this is the custom action server (indicated by the -Embedding switch)

It can be useful to know which msiexec process is which in case you have a custom action that is not working correctly and you want to kill the custom action process but not the overall setup process.

In addition, here are some documents that have been published on MSDN about writing, securing and debugging custom actions that may be useful:

I hope that this info is useful to those of you interesting in writing and debugging setup packages. Please let me know if you have additional questions about how Windows Installer works behind the scenes and I will try to answer them in future blog posts.

A friend of mine was investigating a strange bug this past week that exposed an interesting bug in fusion (the piece of the .NET Framework that is used to manage the Global Assembly Cache aka the GAC). In this particular bug someone was trying to install the .NET Framework 1.1 on a Windows XP Media Center machine, and the .NET 1.1 setup ended up hanging.

The underlying reason for the hang was that this machine had a set of orphaned empty directories under %windir%\assembly\GAC (named like <assembly name>\<assembly version_strong name>) and the fusion code to install assemblies to the GAC had a bug where it would check for the existence of the directory that the file is expected to exist in within the GAC rather than checking that the file itself actually exists in that directory. For each of the assemblies that we tried to install as part of the .NET Framework 1.1 setup, there was an entry like this in the verbose MSI log:

Then when .NET Framework 1.1 setup tried to run ngen.exe at the end of setup to generate native images, it would hang because the underlying assembly actually was not present in the GAC (which in itself is another bug - it should gracefully fail with an informative error instead of hanging).

My friend and his team are still trying to figure out why the orphaned directories exist on the machine in the first place. It appears to be caused by performing an OS installation to a partition that previously had an OS installed to it without first performing a full format of that partition.

When my friend was telling me about this bug, it rang a bell for me from my past experience, so I dug through my email archive. I ended up finding a problem that I helped an internal customer solve that had the exact same symptoms and that exposed the same bug in fusion. So I wanted to go ahead and blog about this in case there are any setup developers or testers out there who are seeing odd behavior when trying to install assemblies to the GAC.