Thoughts about setup and deployment issues, WiX, XNA, the .NET Framework and Visual Studio
All postings are provided AS IS
with no warranties, and confer no rights. Additionally, views expressed
herein are my own and not those of my employer, Microsoft.
Hey all, I just got a mail from my "sister" team saying that updated embedded evaluation kits with Windows CE 5.0 are now available at http://msdn.microsoft.com/embedded/getstart/evaluate/. Get em while they're hot!
I was looking at some blog items that were posted about Microsoft products last night, and I stumbled upon this one on Michael Teper's blog. The question he raised is one that I've run into a lot within Microsoft, particularly from C++ developers that have to install Visual Studio .NET 2003 to do their day-to-day coding work - why do I have to install the Visual J# redistributable package 1.1 before I can starting installing VS, even if I'm not going to be doing any J# coding? (of course, in the mails from internal devs I have to remove the expletives from the question also..... :-) )
Since I was on the VS setup team at the time that we added J# to the suite of tools/languages and I know why this is the case, I thought I would try to explain this design. It helps to start by looking at the background and planning of the VS 2003 product. When VS 2002 finally shipped it was nearly 4 years after VS6 had been released, and we wanted to make sure that the next release of VS was not going to require 4 more years of bake time, partially because a lot of customers will wait for Microsoft to release a service pack or 2 before they will jump in and start using a v1.0 product (which is essentially what VS 2002 was in comparison to VS6, and it is exactly what the .NET Framework 1.0 was). So, VS 2003 was originally planned to be a 6-month project that would essentially be a 1.1 release for VS 2002 and would contain only bug fixes to existing features. The only new features would be the new J# programming language and smart device project support in the IDE for C# and VB .NET. In fact, some of the early plans for VS 2003 had proposed to ship it as a service pack that would install on top of VS 2002.
Anyway, with the mandate that we would be shipping in 6 months, the setup team planned very limited work for VS 2003 - some deployment improvements for the .NET Framework redist package, the OCM package that would be used to deliver the .NET Framework 1.1 to Windows Server 2003, and the addition of the J# language tools and J# redistributable package that was required for J# applications to work correctly. We considered putting the J# redist functionality into the .NET Framework 1.1, but rejected that for several reasons. Then we considered including it in the main VS setup tree, but also rejected that because it is needed at runtime in addition to design time and we couldn't tell people to install a part of VS on their clients' machines in order to enable J# applications to work correctly. We also tried to propose that the J# redist installation package be installed if the user chooses the J# programming language in the VS tree, and then the IDE could install it on demand or provide UI to guide the user to install it themselves if they really needed it. This presented usability issues, caused an additional barrier to entry for J#, and also caused problems with administrative deployment scenarios where the end user was not an administrator when they were using the IDE and could therefore not install products themselves.
That left us with the option of including it as a distinct component in the Visual Studio Windows Component Update (renamed to be Visual Studio Prerequisites in VS 2003). The obvious drawbacks of this decision are that people who don't intend to ever develop a J# application are forced to install something they do not need, and worse yet, are blocked from installing Visual Studio if this thing they don't need fails to install. In an ideal world with infinite time and resources, we would have added logic to our setup to be able to associate a component in the VS Prerequisites part of setup with the features in the main VS feature tree. Given a 6 month milestone, that was not feasible because it is non-trivial to artificially introduce a feature-level dependency within one MSI on a component that is not also in that MSI, and we did not support nested MSIs.
As we now know, the VS 2003 product cycle extended from the original 6 month target to something like 15 months (in order to better incorporate customer feedback we started getting for VS 2002 as well as to increase the overall quality and stability of the product we wanted to ship). By the time that became evident, we had already passed the window of opportunity for coding up a new bit of dependency logic to give a better experience for installing the J# redist. Unfortunately we have heard lots of feedback since then from customers and also from Microsoft developers who only want to install VS to code in C++ and don't want anything J# related, etc. The good news is that this type of setup logic is now in place and will start being used in the VS 2005 beta2 timeframe.
In the meantime, I can offer a couple of workarounds for folks who don't want the J# redist on their machine:
Hopefully this gives some insight into how Visual Studio .NET 2003 setup behavior came to be and what we're doing about it in the future. Let me know if you have any comments, concerns or follow-up questions....
I ran across a relatively new blog that is being maintained by the release team for Visual Studio and the .NET Framework. I used to work closely with most of them in my former role on the setup team and now I meet up and play basketball with some of them before work on Tuesdays and Thursdays when I can drag myself out of bed in time. Check it out at http://blogs.msdn.com/release_team, it gives interesting insights into some of the logistics behind shipping products at Microsoft.
In response to a post from Mike Hall about funny/sad/crazy UI messages (see his original post here), I want to submit a screenshot I took back in my early days working on Visual Studio setup. Back in the day, the product was not yet .NET'ized and it was still known as Visual Studio 7.0, and our setup team was working through a lot of bugs and new features. We had one particular problem where we were calculating the time remaining based on some information we received back from some Windows Installer API calls, and the info was ridiculously overestimating the time remaining. After I logged a bug on this, the development team and I decided to have a contest to see who could get a screenshot with the longest time remaining. I ended up winning with this screenshot. When you do the math it comes out to something a little more than 67 years. I know that Visual Studio setup takes a long time, but that is a little bit excessive......My favorite part of this screenshot is the additional 2 minutes that it lists because we all know that after waiting 67 years it is important to be accurate up to the minute.....
As a side note, back then Visual Studio was one of the first Windows Installer setups within Microsoft to try to implement an external UI handler, and in fact I think it is still one of the few to do so (not counting other setups produced by our same team like the new .NET Framework UI in version 2.0). We had a lot of growing pains while implementing that setup. It was always funny to me when I would send questions to the Windows Installer internal support email alias and they would answer by saying "I think the Visual Studio setup team is doing something like that" and then I would have to reply and tell them that I am on the Visual Studio setup team......
There is a known issue with the QFE we released in December 2003 to include the .NET Framework 1.1 for XP Embedded. It creates 2 shortcuts on the start menu that are in Japanese (which may show up as square boxes if you do not have the full set of Japanese fonts and settings included in your embedded image). This will be fixed in the upcoming XP Embedded SP2 release, but in the meantime you can work around this issue by doing the following prior to building your XP Embedded image:
If you have built your image but not yet had FBA run on it, you can go to the \Windows\Inf directory and locate the file netfxocm.inf and make the same change described above.
I posted this item a while back in the newsgroups but I wanted to put it in my blog also because I think it may have gotten a little buried amongst all the posts there. We have seen many reports of bugs related to calling into performance counter APIs on XP Embedded. These have shown up most commonly when using the System.Diagnostic.Process class in the .NET Framework but can also be seen when using certain native APIs. The underlying issue is a registry key that is incorrectly populated when creating an XP Embedded image. This issue will be fixed in the upcoming XP Embedded SP2 release, but I also wanted to provide a couple of workarounds that can be applied in the meantime.
If you have not yet built your XP Embedded runtime, you can do the following:
If you have already built your runtime, you can delete the registry key named HKLM\Software\Microsoft\Windows NT\CurrentVersion\Perflib\009\ and then reboot your machine to fix this issue.
Hey all, thanks to your posted comments, I realized that the exclusion list I posted here originally was not in the correct syntax for the InCtrl5 tool to understand it.
There is not a way to exclude files in the InCtrl5 tool, so you will need to look at the exclusion list at http://www.winisp.net/astebner/bin/inctrl5_exclusion.txt and manually exclude them after running the tool for the setup you are trying to model.
For registry keys, I have created a new file in the correct format at http://www.winisp.net/astebner/bin/inctrl5_registry.txt. You can download this file, rename it to InCtrl5.ini, and copy it to \Program Files\InCtrl5 on the machine that you have installed InCtrl5. This will cause the tool to ignore this set of registry keys/values when analyzing a setup.
Hope this helps....
Hey all, I'm happy to report that we figured out the root cause of the really strange rollback behavior we saw in the .NET Framework setup (described in a post earlier this week) and I wanted to pass on what we found in case any of you hit this issue with a Windows Installer-based setup in the future. Here is a rough outline of the issue and the underlying problem:
The only thing we are not sure about is why the RBS file was orphaned in the registry and on the user's machine to begin with, so we'll have to keep digging into that if we get any additional repro machines and see if we can figure it out. We are going to look into making the next version of Windows Installer smarter about which RBS files it will run when it is removing backup files to try to help avoid this scenario in the future, but in the meantime if you encounter this behavior in any of your scenarios, start by taking a look at that registry value and see if there is any orphaned data that may be causing your setup to rollback.
Hope this helps......
I found this really cool article this morning about a project at Cornell University where they're building an unmanned aircraft with onboard embedded control systems that are running XP Embedded - check it out at http://research.microsoft.com/displayArticle.aspx?id=685
My colleague, former manager and friend Michele Coady is currently an international test lead on the Visual Studio and .NET Framework localization team. She sent me a really interesting link today that I wanted to pass on for anyone who may be writing world-ready applications. Colors have different meanings and cultural implications depending on the audience, and it is very important to keep the connotations in mind when writing applications for worldwide audiences. Anyone writing worldwide applications should take a look at this article, and even if you're not, this is an interesting read - http://www.colorconnection.xerox.com/wwwco578/html/en/tips/international.html
I saw a very odd rollback behavior in the .NET Framework setup yesterday that I thought I should post in case anyone else runs into something similar. This was the 2nd time I saw it, but the first time in a scenario from a non-Microsoft internal machine. When it first happened I had written it off as a one-off caused by daily builds of the OS, the .NET Framework or something like that. But apparently it is possible to get the machine into this state through released products (possibly beta bits, but still valid in my opinion)
Essentially what happened was the .NET Framework setup proceeded all of the way through installation and then initiated a full rollback. I couldn't find any evidence in the verbose MSI log file that any kind of error had triggered the rollback, and the last section of the log told me that the return code was 0 and that the .NET Framework installation completed successfully. I had to use filemon and regmon (from http://www.sysinternals.com) to diagnose that there was a file in the folder c:\config.msi named *.rbs that was being executed, and then finally I traced it back to the following registry value on the machine:
I wasn't able to determine how that value got set, and searching for information about this registry hive in msi.chm and on the internet didn't yield any conclusive information. The closest I came to a possible explanation is in the section named Active (Incomplete) Installations at http://www.microsoft.com/resources/documentation/WindowsServ/2003/all/techref/en-us/Default.asp?url=/resources/documentation/windowsServ/2003/all/techref/en-us/msizap_remarks.asp
What I think may have happened is some other Windows Installer setup (more than likely the .NET Framework itself) got orphaned before it completed, and then this script was left behind in the registry and inadvertantly got launched by future installations. Normally when a Windows Installer setup gets orphaned and you try to run another MSI, it will say that an installation is currently in progress and is suspended and asks if you want to rollback before you continue with the new setup, but for whatever reason we didn't see that in these 2 instances. I'm still hoping to get a more thorough explanation from the Windows Installer team about what is really going on here, and I'll post my findings back here.....
Hey, I'm slowly but surely getting other folks on my team to create blogs. Neil Marlowe is a program manager who I work closely with - some of you may have met him and attended one of his talks at Embedded DevCon. His primary focus is the Embedded Enabling Features (EEFs) like me, plus he's got some expertise on embedded security and servicing scenarios. Take a look at his blog at http://blogs.msdn.com/neilmarlowe/ if you have a chance, he's planning to post some good how-to documentation in the near future about using the ICF utility to protect embedded devices....
Hey all, as I promised a while back, I wanted to walk through some examples of how I approach reverse engineering a setup package to learn how it works, make any necessary changes, figure out command line switches, etc. I apologize for not posting anything in a while, I was spending some time with my family who was in town from Texas and then I managed to get sick right after they left. But I'm back now :-)
I'm going to start with a relatively straight-forward reverse engineering example - the .NET Framework 1.1 package. I chose this first because that setup is very simple - no setup data files, no configurable setup UI options, etc. Yet it is complicated enough to be interesting and it is a setup that a lot of people want to include in their setup packages and/or have had issues trying to install. I'm going to try to approach this from the perspective of someone who is familiar with different types of setup technologies in a broad sense, but who has not yet seen this particular setup before (I may get a little off track on this part because I'm so familiar with this setup from my previous work, but I'll try.....)
Step 1 - figure out what packaging technology is being used
When I download the .NET Framework 1.1 I see that it is a single EXE named dotnetfx.exe. When I double-click on it, setup asks me if I want to install and when I say Yes it proceeds to extract files to the %temp% folder on my machine. Then a EULA appears. When I go to %temp% after the EULA appears, I see a folder named ixp000.tmp. This tells me that the package in question is an IExpress self-extracting EXE. Since I know it is IExpress, I can now use some well-known IExpress command lines to extract the package to a folder of my choosing. I will run dotnetfx.exe /t:c:\aaron /c to create a folder named c:\aaron on my machine and unpack the .NET Framework files to this folder. The /t flag specifies the folder to extract to, and the /c flag specifies that I want to extract the files only and not run the setup after extraction.
Side note for setup developers - I found some IExpress docs on the web here, and you can also find iexpress.exe in %windir%\system32 on an XP Professional machine. It is a useful tool for packaging up multiple files into a single package but it is also a fairly old technology and has some limitations that may not make it practical to use, depending on your scenario.
Step 2 - figure out what setup/installation technology is being used
Now that I have extracted the files, I will go to the c:\aaron folder that I created above.
Step 3 - figure out the basics of how the setup works
After I look at all of this, I go ahead and step through the UI and install the .NET Framework 1.1, and then re-open the log file dotnetfx.log. I see that it lists the command line that is passed to the MSIInstallProduct function - and I know that this is an API call for an application to install a product using Windows Installer. Then I see a return code for that API call - fortunately it is 0 in this case to tell me that the .NET Framework 1.1 installed correctly. Then I see another call to StopDarwinService, so this install.exe application is stopping the Windows Installer service again after installation is complete - kind of strange.
Step 4 - figure out details about how the setup works
Now that I have a basic understanding of how the .NET Framework 1.1 setup works, I'm going to use my Windows Installer expertise to dig a little deeper. The first thing I will do is install Orca, then right-click on netfx.msi and choose Edit with Orca to view the contents of the MSI. There is a ton of data to wade through in an MSI and it is overwhelming at first, so I will only look at a few key things here:
There are many more things that we could look at in an MSI, but the above are good starting points. Often for other setups you will see items in tables that will lead you on trails through other tables. Most commonly, if there are launch conditions that depend on the existence of other applications, you will be led to the AppSearch table to figure out exactly what file or registry data the setup is looking for when deciding whether or not to block.
Step 5 - install with verbose logging and look at the MSI log file
Reading an MSI log file is more of an art than a science but can often be useful when reverse engineering a setup. For the .NET Framework 1.1, we know that because it is an MSI we can set the verbose logging flags before running setup - HKLM\Software\Policies\Microsoft\Windows\Installer, Debug (REG_DWORD = 7) and Logging (REG_SZ = voicewarmup!). These will give us a verbose log named msi*.log in %temp% where * is a randomly generated set of characters.
I also noticed when running install.exe /? it says that if you pass a /l flag it will generate netfx.log in %temp%. Since I also noticed that the log created by running install.exe was named dotnetfx.log and not netfx.log, I might be curious what the difference is and run install.exe /l from c:\aaron to see what it does. When I install this way I see that the resulting file %temp%\netfx.log is essentially the equivalent of a Windows Installer verbose log file without needing those registry keys to be set. So now I can take a look at netfx.log (or msi*.log if I choose) and view the step-by-step process of this setup.
With that, the process of reverse engineering the .NET Framework 1.1 setup is done for the common cases. There is of course more detail that may be needed depending on your scenarios, but much of that will require more in-depth analysis of the MSI tables and/or the verbose MSI log files. I will leave that for a later lesson.
Side note for the curious - the reason that the .NET Framework 1.1 setup stops the Windows Installer service is because Windows Installer uses pieces of the .NET Framework to install assemblies to the GAC (the MSIAssembly and MSIAssemblyName tables in the MSI) in Windows Installer 2.0 and higher. This creates a classic chicken-n-egg problem - Windows Installer is going to install the .NET Framework but Windows Installer needs the .NET Framework in order to do so. Because of that, Windows Installer has some special logic to bootstrap the part of the .NET Framework it needs to install assemblies, but since Windows Installer is run as a service, it could already be running from a previous setup and we want to stop the service to unload any older versions of the .NET Framework from memory so that the most recent version will be used.
I hope this post is at least a little bit useful to give some insight into how I approach the process of taking apart a setup and figuring out how it works. I will post more later with a more complicated example of a setup that uses information from data files, etc. Let me know via comments or emails if you have any questions about any of the above.....
My colleague Alaks Sevugan created a pretty comprehensive list of file and registry exclusions that can be used with the InCtrl5 tool to eliminate noise when trying to convert an application installer to an XP Embedded component. Click on the link below to download it and try it out....
A lot of you probably know this already, but I wanted to list these steps for the record. If you are debugging an application issue or just want to make a quick change to your image and redeploy it without needing to open Target Designer and rebuilding your image, you can do the following:
After following these steps, you can deploy your image and any registry changes you made will take effect in your embedded OS. Hope this helps.....
While searching for orca.msi earlier today to try to determine whether or not it is available outside of the Platform SDK, I stumbled upon a really cool list of MSI tips, tricks and tools. There is one tool in there that rates the complexity of an MSI, I'm going to have to run that against the Visual Studio MSI when I have some time tomorrow, I'm really curious to know what that will come back as. I would think it has to be more complex than the Office setup package :-)
As a side note - I've gotten a couple of mails from internal folks about posting orca.msi and I'm not quite sure if it is intended to be posted outside of the Platform SDK so I may have to take it down. I can't think of a reason why we wouldn't make such a critical MSI debugging tool harder to obtain than it needs to be so hopefully I can convince the right people that we should be making it available for direct download. But we'll see.....
Stephane Rodriguez posted an interesting comment that I hadn't thought of - it isn't the easiest thing in the world to download Orca. You have to go through the Platform SDK web-based installer tool and also install a bunch of pieces of the core SDK to get orca.msi which lets you install Orca. I have a copy of it that I downloaded and posted at http://cid-27e6a35d1a492af7.skydrive.live.com/self.aspx/Blog%5E_Tools/orca.zip for easier access. I hope this makes things easier for you as you debug your setup packages.
<update date="4/9/2010"> Fixed broken link to orca.zip. </update>
While I was on the Visual Studio and .NET Framework setup team, a colleague and I took a trip to visit 2 universities - MIT and USC - to validate the plans and designs we were working on to add support to our setup UI to generate transforms for Active Directory deployment for the Whidbey version. During this trip, I was struck by the level of MSI knowledge that the system administrators at both of these schools possess, and also by how willing they were to reverse engineer setups to do any/all of the following:
The universities that we visited and many others that I've talked to who are in charge of software deployment simply need to roll out standard OS images with specific applications, and too few app developers understand the implications of their setup development decisions on things like admin deployment.
Then, when I joined the Windows Embedded team, I found a common theme among embedded customers - they need to install drivers and applications onto their embedded images, but they do not ship components that can be used by Target Designer and the embedded tools. This leaves the following options
It really struck me to think about the similarities in the problem spaces between the 2 teams that I have worked on at Microsoft. It also got me thinking because I have been working with and studying setup technologies for the 5 years I've been working at Microsoft, and over that time I've learned to think the way a setup developer thinks so that I can take apart a setup and figure out what it does. However, despite all of this experience, I still haven't seen any 2 setups that behave in exactly the same way.
I have come up with some tricks that can be useful to take apart a setup and figure out what it does, debug issues, and reassemble it in new ways. I'll list out some of the MSI-specific tips and tricks I've seen and used, and then some more general ideas:
Reverse Engineering MSI-based Setups
Random Tricks for Packaging and Reverse Engineering
It seems like I have more tricks that I've used but I can't seem to remember them all right now. I'm getting tired tonight, but I think tomorrow I'll take Visual Studio and .NET Framework setup packages and walk through some of the inner workings and show how I use some of the above tricks.
I have no idea if anyone but me is really interested in the theories and technologies behind setup creation, but if you made it this far and have comments/suggestions/questions/etc please send me an email or post a comment. Thanks!
Hey all, it looks like the Visual Studio setup team has heard all of the feedback because they have posted manual installation instructions for the Express SKUs. Here is a compilation of all of the useful links:
Manual Install Instructions
Direct Download Links
If you are on a very slow connection or have a pay-by-the-megabyte connection or something like that, you can use this link to order CDs - http://lab.msdn.microsoft.com/vs2005/get/order/. You will only be charged the cost of manufacturing the CDs and shipping them to you.
The setup team would like to ask you to please try the downloader application before linking to the packages directly because this is a beta and they are looking for all of the feedback and bug reports they can get for this new feature. Please report any issues you find while installing or using the products at the product feedback site - http://lab.msdn.microsoft.com/productfeedback
If you download the packages, you can use the instructions I posted at http://blogs.msdn.com/astebner/archive/2004/07/05/173639.aspx to create an installable layout and optionally burn it to a CD. These steps will give you the same layout of files as the CDs that you can order from the link above.
Let me know if you have any comments or questions, hope this helps....
A couple of folks who attended the session and/or the hands-on lab I presented at Embedded DevCon last week regarding remote debugging had specific questions about whether or not the strategies I presented would work on a minlogon image.
I followed the steps in Mike Hall's debugging tip sheet at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnembedded/html/embedded06072004.asp?frame=true using a minlogon image and found that native remote debugging worked fine for me on this configuration.
So I encourage those of you who are interested to try it out and send me email or post feedback here if you run into any issues or have any questions.
There is a new version of DUAScriptGen now available at http://www.winisp.net/scrat/DUAScriptGen/DUAScriptGen.zip
It contains the following fixes:
As always, please let Mike Hall and/or me know if you see any bugs or have any feature suggestions. Thanks!
Hey all, one of the feedback forms from the hands-on lab I presented about remote debugging indicated that you'd like to hear more information about how to use the Microsoft Loopback Adapter that I used to mimic a LAN connection within the local machine to connect the development OS to the virtual machine. Here are the steps I used to setup the loopback adapter. I am going to see about creating a more formal tip article for this and post it somewhere on MSDN's embedded site also. Please send me any feedback about whether or not this set of steps ends up working for you.....
Installing Microsoft Loopback Adapter
Now that you have installed the Microsoft Loopback Adapter, you need to configure an IP address for it.
Configuring Microsoft Loopback Adapter
Now you can disable your current LAN connection and enable your Microsoft Loopback Adapter connection by right-clicking on each connection in the Network Connections control panel and choosing Enable or Disable.
Earlier, I posted some random thoughts and notes that I took at the first XP Embedded Ask the Experts session at last week's DevCon (see the post at http://blogs.msdn.com/astebner/archive/2004/06/30/170582.aspx). I also want to post some stuff that I wrote down from the 2nd Ask the Experts session (last Thursday at lunch). I'm sorry it has taken me this long to post this stuff.....I'm going to be working with my team in the next couple of weeks to come up with plans to address all the great feedback and ideas we heard last week at DevCon and I'm really excited to get moving on some of this stuff....
I'll keep everyone posted on progress in these areas as we make it.....thanks again to everyone who attended DevCon and provided us with your valuable input into what we're doing well and more importantly where we're not doing so well.....
I've seen numerous issues and comments related to using the customized download manager to control downloads of the Visual Studio Express SKUs and their prerequisites and optional addins such as SQL and MSDN. Here are a couple of options that you can use to directly download the packages and then run from your local machine to install the beta bits:
If you want, you can also assemble the equivalent of a CD layout on your local hard drive. To do this, use these steps:
If anyone tries this and hits any problems please email me or drop me a comment and I'll help wherever I can. Thanks!
<update date="11/16/2005"> Updated the URL to be http://go.microsoft.com instead of http://www.microsoft.com </update>
My former group (Visual Studio and .NET Framework) has signed off on the beta1 bits for the new 8.0/2.0 versions, codenamed Whidbey. One of the last big setup projects I worked on was the download logic for the Express SKUs - these are replacements for the “standard” versions of Visual Basic, C#, J#, C++, along with an additional SKU named Visual Web Developer (think of VID 6.0 with all the cool stuff that goes with ASP.NET and without all of the annoyances of VID).
The coolest thing of all is that you can use the downloader to get yourself a free copy of any of the 5 beta express SKUs and you don't even officially have to be a part of the Visual Studio beta program. Just go to the site at http://lab.msdn.microsoft.com/express/ and choose the version(s) you want, and off you go.
I'd be really curious to hear what you think about the experience of downloading and installing Visual Studio directly from the web, so if you try it, drop me a comment. If you're not a part of the Whidbey beta program and you have any bugs to report and/or suggestions for ways to make the experience better I will fill out a bug report for you so your voice will be heard by the Visual Studio team.....