Aaron Stebner's WebLog

Thoughts about setup and deployment issues, WiX, XNA, the .NET Framework and Visual Studio

  • Aaron Stebner's WebLog

    Scenarios where .NET Framework 3.5 setup tries to connect to the Internet and how to avoid them

    • 30 Comments

    The setup program for the .NET Framework 3.5 and the Visual Studio 2008 Express Editions contains logic that will cause it to attempt to connect to the Internet to download files in some scenarios.  I've heard from several folks who have asked me why this happens and how to prevent it in case they need to install in a fully offline scenario where the system has no Internet connectivity.  This post will describe the cases I know of where .NET Framework 3.5 and VS 2008 Express Edition setup will attempt to download files from the Internet and how they can be avoided if necessary.

    Case 1 - Missing setup packages

    .NET Framework 3.5 and Visual Studio 2008 Express Edition setup both have logic to search in relative paths next to setup.exe for packages that need to be installed during the setup process.  If any of the packages are not found in those relative paths, setup will use URL values constructed from information in the setup data file named baseline.dat to attempt to download the packages from the Internet instead.  If setup cannot connect to the Internet or the download fails for any reason, then setup will fail and report an error.

    In order to avoid requiring Internet access in this scenario, you need to make sure to construct an install point for the .NET Framework 3.5 or the Visual Studio 2008 Express Editions that include all packages that could need to be installed in your environments.  You can find more information about how to do this in the following blog posts:

    If you are interested, you can find more information about how this automatic download functionality works in .NET Framework 3.5 setup here and here.  The VS 2008 Express Edition setup packages use the same setup.exe code as the .NET Framework 3.5 setup, so the behind-the-scenes logic is similar for those packages.

    Case 2 - Installing the .NET Framework 3.5 on a non-English OS

    The .NET Framework 3.5 setup contains logic to check the language of the OS that it is being installed on and attempt to install a language pack that matches the OS language if one is available.  However, the "full install" setup package for the .NET Framework 3.5 does not include any language packs, so setup will attempt to connect to the Internet when this package is run on many non-English language OS's.

    In order to avoid requiring Internet access in this scenario, you can use one of the following techniques:

    • Download the .NET Framework 3.5 language packs that could be needed in your environments and copy them into your installable .NET Framework 3.5 layout.  You can find download locations for the .NET Framework 3.5 language packs in this blog post and instructions regarding where to copy them in your .NET Framework 3.5 installable layout in item 2 in this blog post.
    • Run .NET Framework 3.5 setup with the /lang switch and pass in the value ENU to prevent it from attempting to install any language packs.  This is described in item 1 in this blog post.

    Note - .NET Framework 3.5 setup is configured to report warnings as opposed to failures if it is unable to download or install language packs.  That means that the above steps are not required in order to allow setup to succeed in offline scenarios, but these steps are required if you want to avoid any attempts to connect to the Internet during .NET Framework 3.5 setup on non-English operating systems.

    Case 3 - Checking for a new version of setup

    The setup programs for the .NET Framework 3.5 and the Visual Studio 2008 Express Editions contain logic to cause them to connect to the Internet to search for an updated version of the setup program.  This will only happen if setup is run with the /web command line switch.  The .NET Framework 3.5 setup program (dotnetfx35setup.exe) and the web download bootstrapper packages for the Visual Studio 2008 Express Editions (vbsetup.exe, vcsetup.exe, vcssetup.exe and vnssetup.exe) are self-extracting packages that are configured to unpack and then run the setup.exe contained within the package with the /web switch.

    In order to avoid having .NET Framework 3.5 setup connect to the Internet to search for an updated version of itself, you must do the following:

    1. Create an installable layout using the steps in this blog post
    2. Go to the folder that you extracted the .NET Framework 3.5 setup files to, find the file named dotnetfx35setup.exe and run dotnetfx35setup.exe /x to unpack it
    3. When prompted, choose to unpack it to the same folder it is currently located in
    4. Instead of using the file dotnetfx35setup.exe to start installing the .NET Framework 3.5, use the file setup.exe in the unpacked location.  This will cause setup to run without the /web switch and skip the step of connecting to the Internet to search for a new copy of setup.  The setup.exe file takes the same command line parameters as dotnetfx35setup.exe (such as the /q and /norestart switches for silent installation).

    For the Visual Studio 2008 Express Editions, only the web download bootstrapper packages available from this download page are configured to use the /web switch.  If you use the instructions for creating an installable layout in this blog post, you will end up unpacking the package that has the /web switch built into it, and running from the layout you create will not end up searching for a new instance of itself during setup.

    Note - .NET Framework 3.5 and VS 2008 Express Edition setups are configured to not fail if they are unable to connect to the Internet to check for a new instance of setup.  That means that the above steps are not required in order to allow setup to succeed in offline scenarios, but these steps are required if you want to avoid any attempts to connect to the Internet during .NET Framework 3.5 setup.

  • Aaron Stebner's WebLog

    Possible cause of 1935 error with HRESULT 0x8002802F

    • 27 Comments

    A while back, I posted an article describing causes of many types of 1935 errors that have been seen in the past.  I wanted to talk about one specific type of 1935 error in a little more detail and provide information about a possible root cause that I did not describe in that previous article.

    A 1935 error in an MSI-based installations code is a catch-all for most of the possible assembly installation errors. In order to diagnose the problem in more detail, it is usually necessary to look at the verbose MSI log file.  In some cases, you will see an error like the following:

    Error 1935. An error occurred during the installation of assembly '<myAssembly>'. Please refer to Help and Support for more information. HRESULT: 0x8002802F. assembly interface: , function: CreateAssemblyNameObject, component: {A7A9D92E-C67F-4E96-BB90-5A4147DAEF6B}

    The key information needed to diagnose the exact root cause of a 1935 error is usually the HRESULT value listed in the verbose MSI log file.

    The HRESULT value listed above is 0x8002802F (-2147319761), and it means "function not defined in specified DLL." There are a few possible root causes of this issue. The most common cause is that the file %windir%\system32\mscoree.dll is missing, corrupt or an incorrect version. In most cases, repairing the highest version of the .NET Framework on the system will correct any problems related to mscoree.dll and will resolve the problem if this is the case.

    In a few less common cases, the file %windir%\system32\mscoree.dll is present, but registry values used by the .NET Framework to find and load specific versions of the .NET Framework are missing. The following values are required by mscoree.dll in order to load each version of the .NET Framework:

    For the .NET Framework 2.0 (on an x86 version of Windows):

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework]
    InstallRoot = C:\Windows\Microsoft.NET\Framework\

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\Policy\Upgrades]
    2.0.50727 = 1.0.0-2.0.50727

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\Policy\v2.0]
    50727 = 50727-50727

    For the .NET Framework 2.0 (on an x64 version of Windows):

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework]
    InstallRoot = C:\Windows\Microsoft.NET\Framework64\

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\Policy\Upgrades]
    2.0.50727 = 1.0.0-2.0.50727

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\Policy\v2.0]
    50727 = 50727-50727

    [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework]
    InstallRoot = C:\Windows\Microsoft.NET\Framework\

    [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432NodeMicrosoft\.NETFramework\Policy\Upgrades]
    2.0.50727 = 1.0.0-2.0.50727

    [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\Policy\v2.0]
    50727 = 50727-50727

    For the .NET Framework 1.1:

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework]
    InstallRoot = C:\Windows\Microsoft.NET\Framework\

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\Policy\Upgrades]
    1.1.4322 = 1.0.0.0 - 1.1.4322

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\Policy\v1.1]
    4322 = 3706-4322

    For the .NET Framework 1.0:

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework]
    InstallRoot = C:\Windows\Microsoft.NET\Framework\

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\Policy\v1.0]
    3705 = 3321-3705

    If any of the above registry values are missing on your system, you will need to manually add them in order to resolve 1935 errors with HRESULT value 0x8002802F.  Note that the InstallRoot value must be set to the exact location of the %windir% folder on your system, so you may need to adjust that value from the one listed above if your %windir% is not located at c:\Windows.

    <update date="2/4/2008"> One of the values for the .NET Framework 1.0 was incorrect, so I fixed it </update>

    <update date="12/16/2009"> Added 64-bit registry information for the .NET Framework 2.0. </update>

     

  • Aaron Stebner's WebLog

    How to fix compatibility mode error that can appear when installing Windows Phone Developer Tools or Visual Studio 2010

    • 53 Comments

    I have heard from a few people who tried to install the final release of the Windows Phone Developer Tools but get an installation error like the following:

    Visual Studio setup cannot run in compatibility mode.
    For more information see the 'Installing' section in the Visual Studio readme at http://go.microsoft.com/fwlink/?LinkID=143397.

    The link in the error message points to the Visual Studio 2010 readme because this issue can affect all editions of Visual Studio 2010, including WPDT.  Item 2.1.10 in that readme provides a workaround for this issue.  In my past experience, that workaround has proven to be incomplete though, so here are some updated steps that usually help solve this type of error:

    1. Click on the start menu, choose Run, type regedit and click OK.
    2. Browse to each of the following keys and delete any value that refers to the WPDT setup program (named vm_web.exe):

      HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Compatibility Assistant\Persisted
      HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers
      HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Compatibility Assistant\Persisted
      HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers

    If the above doesn’t help, then you can also try to save vm_web.exe to your computer and run it from there.  When compatibility mode is triggered by Windows, it is based on a full path to the setup executable, so if you save it to a different location than you previously tried to run it from and then run it again, that can help avoid triggering compatibility mode.

  • Aaron Stebner's WebLog

    Example WiX-based setup that can be used to build both 32-bit and 64-bit MSIs

    • 20 Comments

    I previously posted an example that allows you to build a WiX-based MSI that will install a Windows Vista Media Center application and create a custom start menu strip.  However, there is a limitation in this example (that was pointed out in this post on the Media Center Sandbox discussion forum) that affects the ability to install the application on 64-bit operating systems.  This blog post describes the limitations in my previous sample and presents a modified version of that sample that will allow you to build both 32-bit and 64-bit MSIs in order to work around the limitations.

    Description of the problem with my previous example

    As this forum post describes, you have to directly set registry entries in order to add custom strips to the Media Center start menu (which means that you have to author RegistryKey and RegistryValue elements in WiX).  However, if you create a 32-bit MSI and then try to install it on a 64-bit OS, the registry entries will get written to the WOW64 hive (HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft).  The 64-bit version of Windows Vista Media Center looks in the 64-bit registry hive and not the WOW64 registry hive when looking for custom start menu strips to load.  Therefore, the custom start menu strip will not appear in the Media Center start menu on a 64-bit OS in my previous example.

    Example that can be used to solve this problem

    To solve this issue, it is necessary to create separate 32-bit and 64-bit installers.  It is a little bit tricky to configure all of the settings and attributes that are necessary to create a 64-bit MSI just by reading through WiX and Windows Installer documentation, so I decided to create a WiX 3.0-based example that can be used to build 32-bit and 64-bit MSIs from the same WiX source (WXS) file.

    You can download this example from http://cid-27e6a35d1a492af7.skydrive.live.com/self.aspx/Blog%7C_Tools/start%7C_menu%7C_strip%7C_setup%7C_example%7C_with%7C_64bit.zip.  I started from my previous 32-bit-only example, and added 64-bit build support.  While this sample happens to install a Windows Vista Media Center application, it is intended to help demonstrate the general concepts required to create 64-bit MSIs in WiX.

    Changes made in this example to enable 64-bit builds

    The new sample includes a single WXS file that is processed twice in order to build 2 different MSIs (one 32-bit and one 64-bit).  In order to create a single WXS file that can build both types of MSI, I introduced a WiX pre-processor variable to pass in the name of the processor architecture, and then I added some if/then/else blocks to conditionally set some of the necessary MSI attributes based on whether the MSI being created will be 32-bit or 64-bit.

    If you look in the setup.wxs file in the example I posted, you can see all of the changes that I made to enable building a 64-bit MSI by looking for sections of the file that are enclosed in if statements such as the following:

    <?if $(var.ProcessorArchitecture)=x64 ?>
        <Package Description="!(loc.Package_Description)" Comments="!(loc.Package_Comments)" InstallerVersion="200" Compressed="yes" Platforms="x64" />
    <?else ?>
        <Package Description="!(loc.Package_Description)" Comments="!(loc.Package_Comments)" InstallerVersion="200" Compressed="yes" />
    <?endif ?>

    In order to set the ProcessorArchitecture variable, I added the following command line parameter when calling candle.exe to compile the WXS file:

    "%WIX_BUILD_LOCATION%\candle.exe" setup.wxs -dProcessorArchitecture=%PROCARCH% -out "setup_%PROCARCH%.wixobj"

    In addition, I added a second set of commands to call candle.exe and light.exe twice - one with the ProcessorArchitecture value set to x86 and the other with the ProcessorArchitecture value set to x64.

    Specific differences between a 32-bit MSI and a 64-bit MSI

    The following are the changes that I made in order to be able to create both 32-bit and 64-bit MSIs in WiX:

    • I created a unique product code for the x64 MSI that is different from the x86 MSI
    • In the Package element, the Platforms attribute must be set to the proper 64-bit operating system so that Windows Installer will recognize it as a 64-bit MSI.  In my example, I am creating an x64 MSI, so I set the Platforms value to "x64" for the 64-bit MSI, and left it blank (the default value) for the 32-bit MSI
    • I created a different default directory structure for each processor architecture.  The 64-bit MSI will install under the ProgramFiles64Folder and the 32-bit MSI will install under the ProgramFilesFolder by default.  This is necessary because Windows Installer requires 64-bit components to install under a 64-bit directory by default
    • I created a unique set of 64-bit components by copying the original set of 32-bit components, updating the Id values to be different than the 32-bit Id values, creating unique Guid values and adding the element Win64="yes" to indicate that these components are 64-bit.  A component must be marked as Win64="yes" in order to cause registry entries to be written under the 64-bit registry hive instead of the WOW64 registry hive
    • In order to prevent the 32-bit MSI from installing on a 64-bit OS (which will work by default, but that we do not want to work once we have a specific 64-bit MSI to install on a 64-bit OS), I added a custom action to the 32-bit MSI and scheduled it in the InstallExecuteSequence and InstallUiSequence tables.  The custom action checks to see if the Windows Installer 64-bit property is set (which indicates that the MSI is being invoked on a 64-bit system), and if that is set, it will block the MSI from installing

    Where to read more about 64-bit issues related to Windows Installer

    When working on this example, I relied heavily on the information in this post on Heath Stewart's blog and the links to Windows Installer MSDN topics that are included in it.  If you are looking for more detailed information about how Windows Installer works behind the scenes in 64-bit scenarios, I encourage you to check out this blog post and also the other topics in Heath's 64-bit blog category.

    <update date="3/23/2009"> Fixed broken link to sample download location. </update>

     

  • Aaron Stebner's WebLog

    How to manually reset Digital Rights Management (DRM) in Windows Vista

    • 7 Comments

    Question:

    I have a system with Windows Vista and have been using Media Center to watch DRM-protected content for a while.  Recently, I upgraded some hardware on my system, and now I can no longer view any DRM-protected content in Media Center.  After some web searches, I found one of your old blog posts that describes a similar type of error message in Update Rollup 2 for Windows XP Media Center Edition 2005.  However, that post and the knowledge base article it refers to appear to be specific to older versions of Windows.

    I have read that some types of hardware upgrades can cause DRM to stop working in Windows, and I suspect that is what is happening to me.  How can I reset DRM on my system so that I can view protected content inside of Windows Vista Media Center again?

    Answer:

    The knowledge base article linked in that old blog post (located at http://support.microsoft.com/?kbid=891664) contains information that is applicable to Windows Vista as well as older versions of Windows, but it does not specifically state that it applies to Windows Vista.

    According to this knowledge base article, you can reset DRM by deleting the files in the DRM folder on your system (but make sure to not delete the DRM folder itself because that can cause other problems on your system).

    The default location of the DRM folder in Windows Vista is c:\ProgramData\Microsoft\Windows\DRM, but it might not be in the same location on every system.  To reliably determine the location of the DRM folder on your system, you can look up the data in one of the following registry values:

    For 32-bit versions of Windows Vista:

    [HKEY_LOCAL_MACHINE\Software\Microsoft\DRM]
    DataPath

    For 64-bit versions of Windows Vista:

    [HKEY_LOCAL_MACHINE\Software\WOW6432Node\Microsoft\DRM]
    DataPath

    Note - the DataPath value is in binary format, so you will have to double-click on the DataPath value in regedit.exe and look at the right-hand column of the Edit Binary Value dialog box that appears to see the plain text version of the path.

  • Aaron Stebner's WebLog

    Mailbag: How to detect the presence of the Visual C++ 9.0 runtime redistributable package

    • 33 Comments

    Question:

    I saw a couple of previous blog posts that you wrote about how to detect the presence of the Visual C++ 2005 runtime files and the Visual C++ 2005 SP1 runtime files.  I am creating an installer that requires the Visual C++ 2008 runtime files.  How can I detect the presence of the Visual C++ 2008 and 2008 SP1 runtime files?

    Answer:

    Like in the Visual C++ 2005 runtime files, there is not a specific detection mechanism designed and built into the Visual C++ 2008 runtime files installers.  You can use an algorithm like the one I described in my previous blog posts to detect the presence of the Visual C++ 2008 runtime files products on a system:

    1. Call the MsiQueryProductState API
    2. Pass in the product code for the package that you want to detect based on the list below
    3. Check the return value of this API.  If it is anything other than INSTALLSTATE_DEFAULT, the package is not yet installed

    Visual C++ 2008 runtime files

    Visual C++ 2008 SP1 runtime files

    Visual C++ 2008 SP1 ATL Security Update runtime files

    Visual C++ 2008 SP1 MFC Security Update runtime files

    <update date="11/19/2009"> Added information about the Visual C++ 2008 SP1 ATL Security Update product codes. </update>

    <update date="11/7/2011"> Added information about the Visual C++ 2008 SP1 MFC Security Update product codes. </update>

  • Aaron Stebner's WebLog

    Why does Windows Installer start installing some other product when I try to install or use a different MSI-based product?

    • 17 Comments
    I received a question in response to my blog entry about reverse engineering setup - basically the .NET Framework setup is being triggered while trying to install an unrelated product (in this case Drive Image 7).  The details of this particular interation may not be interesting to everyone, but I think the underlying issue of why Windows Installer would start installing some other product when you try to install or use an unrelated product would make an interesting topic for discussion.  I'm going to try to explain the underlying issue and also touch on some specific points related to the .NET Framework setup and how to fix it in particular.
     
    Background
     
    This is a feature of Windows Installer called resiliency.  Basically, what happens is that in various type of install or product usage scenarios, Windows Installer will query some or all of the products installed on the machine to determine if the features are correctly installed.  If these queries return any kind of error code, Windows Installer will try to trigger a repair for the feature and product in question.  This will appear as a small installation dialog with the name of the product in the title bar, and normally the text of the dialog will say something like "Configuring <product name>.  Please wait...." and it will contain a progress bar and a cancel button.
     
    In some resiliency repair scenarios, you will never be prompted for a source location.  Windows Installer caches the original location that a product is installed from, and if it can be accessed during a repair it will seamlessly connect to that location and use the files from there.  However, when this type of repair is triggered for the .NET Framework, another dialog will appear stating that Windows Installer could not find the original installation location and asks you to browse to the location of netfx.msi.  This is because it is an IExpress setup package (explained further here), the original source location is no longer valid because IExpress creates a temporary folder in the %temp% folder on a machine, installs from there, and then deletes that folder.  When any repair is triggered by Windows Installer, you will be prompted for the source location of the .NET Framework installation package (netfx.msi).
     
    Locating Netfx.MSI
     
    If you are prompted for the location of netfx.msi, you can extract it from dotnetfx.exe and then browse to that location.  To do this, download dotnetfx.exe or locate it on your local hard drive or a CD.  Then, from a cmd prompt run the following:  dotnetfx.exe /t:c:\temp /c.  You can substitute any folder you want for the "c:\temp" parameter.  Once the extraction is complete, browse to the folder you provided for the /t argument and .NET Framework repair should complete with no further issues.
     
    Identifying the Root Cause
     
    Locating netfx.msi can help get you past the browse dialog that appears, but it does not really help answer the more important question - why is the repair being triggered in the first place?  I have seen many cases where an incorrectly authored MSI setup package has inadvertantly triggered a repair for a product already installed on the machine.  In order to diagnose the root cause of the repair request, I usually do the following:
    1. Go to the Start menu and run eventvwr.exe
    2. Locate the Application event log and click on it to list the events
    3. For each repair that was triggered, there will be an entry in this log with a source named MsiInstaller
    4. Using the GUID of the component or feature that is being repaired, it is usually possible to look at the MSI for the product in question using Orca and determine why Windows Installer thinks it needs to perform a repair
    In most cases, you will need to have a pretty solid level of Windows Installer expertise to track down a root cause based on the application event log entries.  It is also possible to export the application event log and send it to someone else (such as a Product Support specialist) for help diagnosing the problem.  To do this, simply right-click on the application event log and choose Save Log File As... in the menu that appears.  Then you can save the file as *.evt, and someone else can import it and view it using eventvwr.exe
     
    Hope this helps explain things a little bit.  Let me know if I got any of the above wrong or if you have any specific questions/comments....
  • Aaron Stebner's WebLog

    How to modify the default install path in an MSI-based setup based on a registry value

    • 6 Comments

    I got a question from a customer this week asking how they could modify the default installation path in their MSI-based setup package based on a value they wanted to retrieve from the registry.  Typically this kind of modification is desired if your setup shares files/components with another MSI, and that other MSI can be installed to non-default locations by another setup package.  The steps to accomplish this are roughly the following.  Please note that I am basing this algorithm on how we accomplish this inside of Visual Studio setup (I also described what happens behind the scenes in VS setup in more detail here).  There may be alternative ways to accomplish the same result.

    1. Create a new entry in the AppSearch table that contains the Signature_ you want to search for and a specific Property name that will store the data you retrieve
    2. Create an entry in the RegLocator table that has a Signature_ column name that matches the Signature_ column name you added to the AppSearch table in step 1 above and that contains the key/value you want to retrieve and use if it exists on the user's system
    3. Create an entry in the CustomAction table that has a Target value that matches the Property column name you added to the AppSearch table in step 1 above (and is in square brackets since this is an MSI property and it needs to be referenced in square brackets to resolve correctly here), and has a Source name that matches the name of the directory in the Directory table that you want to change the default installation path for
    4. Add an entry to the InstallExecuteSequence table that has an Action column name that matches the name of the custom action added in step 3 above and has a Condition column name that matches the Property column name you added to the AppSearch table in step 1 above.  This will ensure that you will only try to change the installation directory if the registry value you are searching for exists on the user's system, and your MSI will use the default installation directory if the registry value is missing.

     

  • Aaron Stebner's WebLog

    Available command line switches for .NET Framework 2.0 setup

    • 39 Comments

    With the release of VS 2005 and the .NET Framework 2.0, we began to use a new Windows Installer external UI handler to manage installation of several of the setups that are part of the VS 2005 family, including the .NET Framework 2.0 redistributable and SDK, J# redistributable, VS Tools for Office redistributable, language packs .NET, J# and VS Tools for Office, etc.

    This new external UI handler is named install.exe, and you will find an INI file named install.ini included with each product that uses install.exe.  Install.ini expresses many configuration options for the setup in question.  I have described many of the settings used for the .NET Framework 2.0 redistributable in this blog post.

    In addition to the INI file, install.exe can be configured using several command line switches.  The following list provides information about all of the command line switches that are supported by the install.exe external UI handler in the VS 2005 and .NET Framework 2.0 family of products:

    • /a - Launches setup in administrative mode.  This mode is used to create a Windows Installer administrative install point that can then be used to install or deploy the product from.  Administrative mode presents UI that allows you to choose the location to stage the files to
    • /l <log file> - Causes setup to create a verbose log in a non-default path.  Setting this value will override the value of the VerboseLog entry in the install.ini file.  If the /l switch is passed, the log file name is required.  If it is provided, it will override the LogFilePrefix entry in install.ini.  If you choose to pass a log file name and there is a space in the path, you will need to enclose the name in quotes.  Leaving this parameter off will allow setup to create a verbose log file in the %temp% directory that has a name beginning with the LogFilePrefix entry in install.ini and ending with a randomly generated character sequence.
    • /lang #### - Specifies the 4-digit language code for the language in which to display the setup UI.  This setting overrides the OS language check and the language specified in the install.ini file.  Setup looks for a file named install.res.####.dll in the same path as install.exe and attempts to load strings from that DLL.  If the DLL with the numerical value passed in via this command line parameter does not exist, install.exe falls back to English strings (located in install.res.1033.dll).  If install.res.1033.dll also does not exist, setup will display an error dialog and exit
    • /msipassthru MSI_PROP_BEGIN"<properties with quotes here>"MSI_PROP_END - Specifies additional property/value pairs that will be passed to the Windows Installer MsiInstallProduct API (or msiexec.exe). This switch also requires that a token be used to prefix/postfix the actual command line arguments.  For example: /msipassthru MSI_PROP_BEGIN"PROPERTY1=Value1 PROPERTY2=Value2"MSI_PROP_END
    • /msipassthru MSI_ARGS_FILENAME_BEGIN<path to file with properties>MSI_ARGS_FILENAME_END - Specifies the full path to a file that contains additional property/value pairs that will be passed to the Windows Installer MsiInstallProduct API (or msiexec.exe)
    • /q - Specifies quiet install mode. Suppresses the display of all setup UI during installation
    • /qb - Specifies basic UI mode for installation.  This will cause install.exe to only show a small Windows Installer progress dialog with no other user interaction required.  This is the equivalent of the msiexec.exe /qb command line switch
    • /qb! - Extends the /qb switch by hiding the cancel button on the progress dialog during installation.  This is the equivalent of the msiexec.exe /qb! command line switch
    • /qu - Specifies quiet uninstall mode.  Suppresses the display of all setup UI during uninstallation
    • /skip_all_checks - Causes install.exe to skip all prerequisites checks that are specified in install.ini.  This may result in setup failing elsewhere because some of the checks are also specified in the MSI itself.  However, this can be useful as a troubleshooting tool if you know the state of the machine(s) that you are installing on very well
    • /watsonsilent - Causes all Watson reports generated by setup in the case of failure to be silently sent to Microsoft instead of displaying a dialog.  This command line switch is only applicable if one of the /q flags is also used
    • /watsonui - Causes all Watson reports generated by setup in the case of failure to display UI informing the user of the issue
    • /? - Displays a help dialog with information about supported command line parameters.  As I was writing this article I noticed that many of the switches that are supported by install.exe are not actually listed in this dialog.  I'll be reporting a bug to the setup team so that hopefully this will be cleaned up in a future release to present more useful information to the user

    <update date="12/7/2005"> Added a note to the /l log file switch indicating that you need to put quotes around the file name if there are spaces in the name </update>

     

  • Aaron Stebner's WebLog

    Disabling services with MSConfig to work around setup failures

    • 12 Comments

    I was talking recently with a colleague who works on the .NET Framework setup and Windows Installer technical support team here at Microsoft.  He told me about a set of steps that his team typically has customers try when they call in to report failed installations.  I wanted to post these steps here in case they are helpful to anyone else struggling to get an application installed.

    This set of steps allows you to easily find all services that are installed on your system and temporarily disable them so they cannot interfere with installation processes.  It also allows you to identify and temporarily disable programs that are scheduled to start every time the system reboots.  The System Configuration tool (also known as MSConfig) allows you to manage these and other settings.

    I recommend trying the following steps in cases where a product fails to install on your system and you've already tried other workarounds posted on my blog and elsewhere to attempt to resolve the issue:

    1. Click on the Start menu, choose Run, type msconfig and click OK
    2. In the System Configuration tool, click on the Services tab
    3. Check the box labeled Hide all Microsoft services
    4. Click the Disable All button to disable all non-Microsoft services
    5. In the System Configuration tool, click on the General tab
    6. Click the Selective startup radio button
    7. Uncheck the box labeled Load startup items
    8. Click OK to accept all changes in the System Configuration tool
    9. Reboot for the changes to take effect
    10. Attempt to install the application that previously failed
    11. Re-run the System Configuration tool and re-enable the services that you disabled in step 4 above

    In many cases, the above steps will allow a previously failing setup package to install successfully.  Hopefully they will be useful to you as well if you find yourself in this situation.

  • Aaron Stebner's WebLog

    Windows Installer custom action tutorial

    • 1 Comments

    Steven Bone posted the first of a series of articles about how Windows Installer custom actions work and how to create and debug them.  You can click on the link to read Part 1 - Custom Action Types and Sequences.

    This article describes how to configure the columns of the custom action table in an MSI, when to use immediate and deferred custom action types, how to handle rollback, and when to use the various custom action flags, options and conditions.

    When using Windows Installer to create a setup, you can author most necessary actions using the standard MSI tables.  However, there are some types of actions that are not supported using native MSI tables (such as the list I posted a while back).  Because of this, using custom actions in your MSI will sometimes be necessary.  Building a setup package is an integral part of the software development process, and the same level of care should be put into planning and designing the setup and deployment for your software.

    Therefore, I strongly encourage you to read through this article (and the follow-up articles he will be posting in the future about writing custom action code) if you do any kind of setup development or testing work.

    I also wanted to point out that there is a set of commonly needed custom actions that are published with the WiX toolset, and they can be easily incorporated into a setup package without needing to write any additional code.  If you are writing an MSI-based setup I encourage you to take a look at WiX as well.

     

  • Aaron Stebner's WebLog

    Hibernate once, resume many (HORM) in a nutshell

    • 32 Comments

    I wanted to take a minute to spotlight one of the big new embedded enabling features that is new to Windows XP Embedded SP2.  It is called hibernate once, resume many.  We have taken to abbreviating this to HORM internally, so if you see this new acronym floating around in documents or newsgroups about XP Embedded that is likely what it means.

    HORM provides the ability to resume an EWF-protected system from a hibernation file (hiberfil.sys) each time a machine is restarted instead of performing a full OS boot.  This greatly improves the cold-boot startup time of machines.  Here are a few key points about HORM:

    • You must protect all partitions on your volume with EWF in order for HORM to work correctly
    • You must use EWF RAM or RAM Reg overlay types in conjunction with HORM
    • Ordinarily, NTLDR will check the header/signature of hiberfil.sys when the system begins the boot process in order to protect against a stale orphaned hiberfil.sys being booted.  If a stale hiberfil.sys is detected, NTLDR will show a menu asking if you want to continue to resume or discard the hiberfil.sys and perform a full boot.  You can create a file named resmany.dat (any size, any format) on the root of the boot partition (typically c:) to suppress this check and allow your device to resume without any user interaction.
    • You must make sure to use the EWF NTLDR with HORM.  EWF NTLDR is the only boot loader that has the logic to search for resmany.dat and skip the hiberfil.sys header check.
    • There are useful help docs describing how to implement HORM on your device, you can check them out here.
    • One thing not covered in the documentation is how to enable HORM directly from Target Designer.  You can create an additional file resource that will copy resmany.dat to the root of your image partition or simply add it to the image after you do a build inside of Target Designer.  Then, assuming you have enabled hibernation in your power management component and configured EWF to run on startup, you will be able to immediately create your hiberfil.sys after your image finishes running through first-boot agent (FBA).
    • If you are using Winlogon and include the settings in the UI Core component you will be able to hibernate via the start menu.  If not, you can include the XPE Power Management tool (xpepm.exe) and run xpepm -hibernate from a cmd prompt to create your hiberfil.sys after you launch the apps that you want to run each time you resume.

    I encourage you all to take a look at HORM as you start exploring XPE SP2.  Please let us know if you run into any problems or have any questions.

     

  • Aaron Stebner's WebLog

    New simplified silent install switches are available for Visual Studio 2008 setup

    • 25 Comments

    Visual Studio 2002, 2003 and 2005 setups include a silent deployment mode that requires multiple steps (creating an INI file on the matching OS version and language, then running VS setup and passing it the INI file to perform the installation).  Those of you who have automated the installation of these versions of Visual Studio can attest to the difficulties that this multi-step, OS version-specific process has introduced.

    In order to make the most commonly needed automated installation scenarios easier to achieve, the following command line switches have been added to Visual Studio 2008 setup:

    • setup.exe /q - this will perform a silent default installation of VS 2008. This is the equivalent of running VS 2008 setup using setup UI and selecting the Default install type radio button.
    • setup.exe /q /full - this will perform a silent full installation of VS 2008. This is the equivalent of running VS 2008 setup using setup UI and selecting the Full install type radio button.

    Note - if you need to pass in a product key when running setup using these new silent switches, you will need to use the syntax described in this blog post.

    There are some important notes to keep in mind for these new silent install options:

    • When using these command line switches, you must make sure that you pass them to the setup.exe in the Setup subdirectory, and not to the setup.exe at the root of the VS 2008 installation disc.  Only the setup.exe in the Setup subdirectory understands these command line parameters.
    • If you run setup.exe /q on a system that already has that edition of VS 2008 installed, it will invoke a silent repair instead of a silent installation.
    • If you need to perform a silent non-default installation of VS 2008 (as opposed to a default or a full installation), then your best bet will be to use the INI creation mode that has existed in previous versions of VS 2008.
    • It is also possible to gather a list of feature names that you want to install by running VS 2008 setup once in UI mode, selecting the features you want to install in the setup UI feature tree, then looking at the verbose MSI log file that is created during installation to figure out the exact list of feature names to pass in during silent installation.  However, that option is more complicated and error-prone than INI creation mode, so I don't recommend using this method unless absolutely necessary.
    • If you want to be able to control reboots, you can also pass in the /norestart switch.  This will prevent setup from forcing a reboot during installation if one of the components it is installing requests one.  It does not, however, postpone the reboot until the end of setup.  In some cases, the setup team determined that it is not safe to defer reboot requests for a component, and have set a flag in a setup data file to indicate that (specifically, the flag RebootLaterOk=0 in baseline.dat).  If one of these components returns 3010, and you pass in the /norestart switch, then setup will exit but will not reboot.  It is up to the process running the silent install to reboot the system and re-start setup after the reboot in order to allow setup to continue.
    • To avoid reboots, you can configure your systems with any prerequisite packages that tend to cause reboot requests prior to deploying VS 2008.  Doing this will cause VS 2008 setup to skip installing those prerequisites because setup will detect that they are already present on the system.

    <update date="9/20/2007"> Added more details about how the /norestart switch works </update>

    <update date="12/17/2008"> Added a link to a separate blog post I wrote about how to pass a product key into setup when using the /q switch. </update>

     

  • Aaron Stebner's WebLog

    How to fix 5.1 analog surround sound in Media Center 2005 Update Rollup 2

    • 29 Comments

    There is a known issue in Update Rollup 2 for Media Center 2005 that causes 5.1 analog surround sound to revert to 2 channel mode.  The underlying issue is that a registry setting is being overwritten by Media Center.  You can use the following steps to add the registry value needed to fix this issue:

    1. Close Media Center
    2. Click on the Start menu, choose Run and type cmd
    3. Run the command reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Media Center\Service\Video" /v AudioOutputFormat /d {696E1D31-548F-4036-825F-7026C60011BD} /f

    Note that if you re-run the Speaker Setup portion of Media Center Setup, this registry value will be reset again and you will need to re-run the above command to fix the underlying issue once more.

    This issue was previously described on this NVidia support page, but I wanted to list it here as well in case anyone reading my blog runs into it as well.

     

  • Aaron Stebner's WebLog

    Issue installing the .NET Framework 3.5 or 3.5 SP1 on checked or pre-release builds of Windows Vista or Windows Server 2008

    • 53 Comments

    I have heard from a couple of customers who ran into issues installing the .NET Framework 3.5 and/or the .NET Framework 3.5 SP1 on one of the following OS types:

    • Checked (also known as debug) builds of Windows Vista and/or Windows Server 2008
    • Pre-release builds of Windows Vista and/or Windows Server 2008

    One of these customer reports can be found in this forum post.  I wanted to describe this scenario in more detail in case anyone else runs into a similar issue in the future.

    Description of the issue

    The .NET Framework 3.5 and 3.5 SP1 install service packs for the .NET Framework 2.0 and the .NET Framework 3.0 behind the scenes.  On Windows Vista and Windows Server 2008, the .NET Framework 2.0 and 3.0 service packs are installed as OS updates.  These OS updates are marked to only install on the final release versions of Windows Vista and Windows Server 2008.  That means that they will not allow you to install them on checked builds of these OS's, and they will also not allow you to install them on pre-release versions of these OS's.

    Here is the exact list of .NET Framework 3.5 installation scenarios that will fail on checked builds of the OS or pre-release builds of the OS:

    • Installing the .NET Framework 3.5 on the original release of Windows Vista (but not Windows Vista SP1 or later)
    • Installing the .NET Framework 3.5 SP1 on the original release of Windows Vista or Windows Vista SP1
    • Installing the .NET Framework 3.5 SP1 on Windows Server 2008

    However, installing the original release of the .NET Framework 3.5 on Windows Vista SP1 or Windows Server 2008 will not fail due to this issue.  This is because Windows Vista SP1 and Windows Server 2008 already include the .NET Framework 2.0 SP1 and 3.0 SP1 as OS components, so .NET Framework 3.5 setup does not need to install any OS updates on those systems.

    How to work around the issue

    Unfortunately, there is not a workaround that will allow you to install on a checked build or a pre-release build of Windows Vista or Windows Server 2008.  Instead, you will need to install a final release build of Windows Vista or Windows Server 2008, then re-run .NET Framework 3.5 or 3.5 SP1 setup.

    How to diagnose the issue

    If you try to install in one of the above configurations, you will see the following error in the .NET Framework 3.5 or 3.5 SP1 log file named %temp%\dd_dotnetfx35install.txt:

    [08/08/08,11:11:11] Microsoft .NET Framework 2.0SP1 (CBS): ***ERRORLOG EVENT*** : Error: Installation failed for component Microsoft .NET Framework 2.0SP1 (CBS). MSI returned error code 1.

    Error code 1 for Windows Vista or Windows Server 2008 OS update packages means that the package is not applicable on the current OS.

    Important note about error code 1 during .NET Framework 3.5 or 3.5 SP1 setup

    Please note that this blog post only describes one possible cause of error code 1 during .NET Framework 3.5 or 3.5 SP1 installation.  If you are not running a checked build of Windows or a pre-release version of Windows, then the issue described here is not the cause of the installation failure on your system.

    If you are running into error code 1 but are not running a checked or pre-release build of Windows, then it typically helps to review the .NET Framework 3.5 log files to try to learn more about the root cause of the issue.  You can find more information about what log files are produced by .NET Framework 3.5 setup in this blog post, and there is information in this blog post that describes options for reporting installation failures back to Microsoft for additional investigation.

    The logs that are typically the most useful in diagnosing error code 1 are the following:

    • %temp%\dd_dotnetfx35install.txt
    • %windir%\logs\cbs\cbs.log
    • %windir%\WindowsUpdate.log
  • Aaron Stebner's WebLog

    How to fix .NET Framework 1.1 setup failure on Windows Vista build 5456

    • 19 Comments

    Important note: The issue described in this blog post only affects pre-RC1 builds of Windows Vista.  If you are running Windows Vista RTM and have problems installing the .NET Framework, do not try this workaround because it does not apply to the RTM build and will not help.  Please see http://blogs.msdn.com/astebner/articles/454956.aspx instead of this blog post if you have problems installing the .NET Framework 1.1 on Windows Vista RTM.....

    The .NET Framework setup team recently discovered a compatibility bug that will prevent the .NET Framework 1.1 from installing on the most recent build of Windows Vista that was released to the Windows Vista beta program members (build 5456). 

    The underlying problem is that one of the type libraries registered by .NET Framework 1.1 setup is attempting to write to a registry sub-key that is incorrectly marked read-only in this build of Windows Vista.  In order to workaround this issue, you will need to change owners and modify permissions on a registry sub-key on your system.

    You can perform the following steps before installing the .NET Framework 1.1 to workaround this issue on Windows Vista build 5456:

    1. Click on the Start menu, choose All Programs, then Accessories
    2. Right-click on Command Prompt and choose Run as administrator
    3. From the command prompt, type regedit
    4. Navigate to HKEY_LOCAL_MACHINE and then Software\Classes\Interface\{65074F7F-63C0-304E-AF0A-D51741CB4A8D}\TypeLib
    5. Right-click on the TypeLib sub-key and choose Permissions
    6. Click the Advanced button
    7. Click on the Owner tab
    8. Select the Administrators group in the Change owner to: list and click Apply to change the owner of this sub-key
    9. Click on the Permissions tab, highlight SYSTEM and click the Edit button
    10. Check the Full Control check box and click OK to change the permissions on this sub-key for the SYSTEM account
    11. Close regedit

    After performing the above steps, you should be able to re-run .NET Framework 1.1 setup and install successfully.

    <update date="4/4/2007"> Added note at the top of this blog post to try to let users know that this workaround will not help in the final RTM release of Windows Vista.  </update>

     

  • Aaron Stebner's WebLog

    Don't use vbscript/jscript to write your custom actions!

    • 16 Comments

    Rob Mensching wrote a blog entry a while back that explains some reasons why you should not use script-based custom actions in your setup.  I encourage you all to read it if you haven't yet, and I also strongly encourage you to heed his recommendations if at all possible.

    I can personally relate to one of his explanations as well.  Reason #3 on his list talks about anti-virus programs.  When we shipped Visual Studio .NET 2002 we started getting reports of seemingly random failures during setup from our product support team.  After some detailed analysis we found that many of these failures were being caused by overly aggressive anti-virus programs that were blocking scripts from running even as part of custom actions during VS setup.  We scrubbed our custom actions before shipping Visual Studio .NET 2003 to re-write or eliminate the script-based custom actions to avoid these failures, and we were able to eliminate a fairly high support call generator.

     

  • Aaron Stebner's WebLog

    Updated sample .NET Framework detection code that does more in-depth checking

    • 20 Comments

    I previously posted some sample code to detect the version(s) and service pack levels of the .NET Framework that are installed on a computer (here and here).  The original version of the sample code that I wrote queries the officially documented registry values that are used to detect the presence of each specific version of the .NET Framework.

    Since I posted this sample code, I have heard feedback from some customers who are including the .NET Framework as part of their setup packages.  They indicated that sometimes this code reports false positives - in other words, the sample returns true for a specific version of the .NET Framework but it isn't actually installed on the system.  I have seen this a couple of times in the past as well, and the root cause was that some of the registry entries used to detect the .NET Framework were orphaned on the system after an uninstall or OS reinstall scenario.

    In order to help address this type of issue, I've created a new version of the sample code that adds some new checks to help guard against orphaned registry values.  The logic it uses is to query the registry values like the previous sample used to, and then to supplement that with an additional check that loads mscoree.dll and uses some of its APIs to query for the presence of specific versions of the .NET Framework.  The underlying algorithm for this mscoree.dll-based check came from Junfeng Zhang and from a sample published on MSDN.

    This algorithm should prove more reliable in detecting whether or not a specific version of the .NET Framework is installed on the system because it does not rely solely on the registry.  In addition, it provides the side benefit of performing a quick health check for the .NET Framework itself because it attempts to invoke some APIs in the runtime.

    The new sample code contains the following specific changes from the previous version that I published:

    • Added the CheckNetfxVersionUsingMscoree and GetProcessorArchitectureFlag functions
    • Added logic in WinMain to call CheckNetfxVersionUsingMscoree in addition to the original calls to check .NET Framework registry data
    • Updated the code to use strsafe.h functions for string manipulations

    You will need the following in order to compile this sample:

    Please let me know if you have any trouble building or running this sample or incorporating it into your product setup logic.

    <update date="5/29/2009"> Fixed broken link to the sample code. </update>

     

  • Aaron Stebner's WebLog

    Instructions for chaining installation of Visual Studio 2005 and MSDN

    • 44 Comments

    I got a question from a customer who found this blog post describing how to chain silent installation of VS .NET 2003 prerequisites, VS .NET 2003 and MSDN.  They wanted to know what the equivalent set of steps would be for chaining silent installation of VS 2005.  There have been some modifications to how setup works behind the scenes in VS 2005, most notably the elimination of the separate step that used to be required to install prerequisite components for VS, so happily I can say these steps are much simpler than in the past.  Here are the steps for VS 2005 (using the same format as my previous post).

    To start with you should stage Visual Studio bits to a network share so that you can use this as your installation source later on.  You can accomplish that with the following steps (also described in the VS readme located in the file adminreadme.htm in the Setup subdirectory on VS Disk 1):

    1. Create a folder on your server, such as \\server\vs2005
    2. Create subfolders named \\server\vs2005\vs and \\server\vs2005\msdn
    3. Copy the contents of all CDs labeled Visual Studio 2005 to \\server\vs2005\vs.  If prompted, choose yes to overwrite existing files.
    4. Copy the contents from all the CDs labeled MSDN Library for Visual Studio 2005 to \\server\vs2005\msdn.  If prompted, choose yes to overwrite existing files.
      NOTE: You can substitute a different MSDN Quarterly Library for the version of MSDN that shipped with Visual Studio 2005 if you choose

    Now that you have a network image, you can create the unattended INI file to install VS 2005 and MSDN using the following steps:

    1. Locate a test computer that has the same operating system that you want to deploy Visual Studio to in your network, and make sure that it does not already have Visual Studio 2005 installed
    2. Install .NET Framework 2.0 on your test computer (because this is required for creating an unattend file for Visual Studio in the next step)
    3. Run \\server\vs2005\vs\setup\setup.exe /createunattend \\server\vs2005\datafiles\vs.ini /vsupdate=\\server\vs2005\MSDN\setup.exe /vsupdateargs="qn"
    4. Open \\server\vs2005\datafiles\vs.ini, go to the [PostSetupLaunchList] section and change """qn""" to /qn
    5. Go to a clean computer without Visual Studio 2005 installed and run \\server\vs2005\vs\setup\setup.exe /unattendfile \\server\vs2005\datafiles\vs.ini to test the unattended installation process

    There are a couple of gotchas that I have seen that you should keep an eye out for when following these instructions:

    • Make sure to note the extra \setup\ directory for the Visual Studio setup.exe in the steps above.  Unattended installation will not work correctly if you run the setup.exe in the root of the \\server\vs2005\vs folder; you must use \\server\vs2005\vs\setup\setup.exe.
    • Make sure that you have write permission for the location that you create your data file at in step 3 (in this example I used \\server\vs2005\datafiles).  You will get an error if you try to create the data files on a share that you do not have write permissions for.
    • Make sure that you create the INI file on a computer that does NOT already have Visual Studio 2005 installed.  If you have VS installed, you will end up creating an INI file for a maintenance mode update instead of an initial install of VS.
    • The INI file for VS is unique to each version of VS (such as Pro, Standard, Team System), and also unique to the OS that you want to install on (Windows 2000, Windows XP, etc).  Make sure that you create INI files on computers that match what you will eventually be deploying to.

    There is an advanced trick that you can use when creating this unattend script as well:

    • If you want to perform a full install of MSDN to the local hard drive instead of a default installation, you can read the steps at this blog post to learn how to update your vs.ini file to call MSDN setup with the correct parameters to accomplish this.

    In the VS 2003 instructions there was an additional advanced trick regarding waiting for the setup process to exit and checking the return code.  The workaround I listed in my previous post is not necessary in VS 2005 because setup now has specific logic to not copy itself to the %tmep% folder and start a new process if it detects it is being run in administrative installation mode.

     

  • Aaron Stebner's WebLog

    How to configure post-build events for setup/deployment projects in Visual Studio 2005

    • 7 Comments

    While researching a previous blog post, I discovered a way to configure post-build events for setup/deployment projects in Visual Studio 2005.  I had not realized that previous versions of Visual Studio did not support configurable post-build events for setup projects, but Visual Studio 2005 does.  In addition, the way to access the UI needed to configure this setting for a setup project is different than for other project types in the Visual Studio 2005 IDE.

    The following steps can be used to add a post-build step to your setup/deployment project:

    1. Open or create a setup/deployment project in Visual Studio 2005
    2. Press F4 to display the Properties window
    3. Click on the name of your setup/deployment project in the Solution Explorer
    4. Click on the PostBuildEvent item in the Properties window to cause a button labeled "..." to appear
    5. Click on the "..." button to display the Post-build Event Command Line dialog
    6. Add a command line of your choice in the Post-build event command line text box
    7. Build your project in Visual Studio and verify that the post-build event is executed after the main MSI build

    You can also configure a pre-build event in a similar manner - there is also an item in the Properties window named PreBuildEvent.

    As I described in this previous blog post, it can be useful to run a script as a post-build event if you want to automatically modify the MSI that is built as a part of your project to include settings that are not available as part of the setup/deployment project options in the Visual Studio IDE UI.

     

  • Aaron Stebner's WebLog

    Where to find .NET Framework 2.0 SP1, 2.0 SP2, 3.0 SP1, 3.0 SP2, 3.5 and 3.5 SP1 setup log files

    • 18 Comments

    A while back, I posted a list of possible log files for .NET Framework 3.5 and Visual Studio 2008 setup.  Since then, I've realized that there are some sets of log files missing from that list, so I decided to create a separate blog post with information about setup log files that are specific to the .NET Framework 3.5 family of products.  This family includes the following:

    • .NET Framework 2.0 SP1 and SP2
    • .NET Framework 2.0 SP1 and SP2 language packs
    • .NET Framework 3.0 SP1 and SP2
    • .NET Framework 3.0 SP1 and SP2 language packs
    • .NET Framework 3.5 and 3.5 SP1
    • .NET Framework 3.5 and 3.5 SP1 language packs

    The following is a list of log files that can be produced by all of the above setup packages.  In all of the cases below, the logs are created by default, and you do not need to specify any verbose logging settings or registry values to cause the logs to be produced.  Also, you can find the %temp% directory by clicking on the Windows start menu, typing %temp% and pressing Enter.

    .NET Framework 2.0 SP1 and SP2 setup log files

    The following is a complete list of log files that can be produced during .NET Framework 2.0 SP1 and SP2 setup.  This list may vary depending on what OS you are installing on, what processor architecture, and what prerequisite components were already installed on the system prior to running .NET Framework 2.0 SP1 and SP2 setup.

    Logs produced by the .NET Framework 2.0 SP1 and SP2 setup wrapper:

    • %temp%\dd_dotnetfx20install*.txt
    • %temp%\dd_dotnetfx20error*.txt
    • %temp%\dd_depcheck_netfx20*.txt

    Logs produced by the packages chained during .NET Framework 2.0 SP1 and SP2 setup:

    • .NET Framework 2.0 SP1 and SP2 verbose MSI log - %temp%\dd_net_framework20*.txt
    • .NET Framework 2.0 SP1 and SP2 language pack verbose MSI log - %temp%\dd_NET_Framework*20*LP*.txt

    .NET Framework 3.0 SP1 and SP2 setup log files

    The following is a complete list of log files that can be produced during .NET Framework 3.0 SP1 and SP2 setup.  This list may vary depending on what OS you are installing on, what processor architecture, and what prerequisite components were already installed on the system prior to running .NET Framework 3.0 SP1 and SP2 setup.

    Logs produced by the .NET Framework 3.0 SP1 and SP2 setup wrapper:

    • %temp%\dd_dotnetfx30install*.txt
    • %temp%\dd_dotnetfx30error*.txt
    • %temp%\dd_depcheck_netfx30*.txt

    Logs produced by the packages chained during .NET Framework 3.0 SP1 and SP2 setup:

    • RGB Rasterizer - %temp%\dd_RGB9Rast_*.txt
    • MSXML 6.0 - %temp%\dd_msxml6_*.txt
    • WIC - %temp%\dd_wic*.txt
    • .NET Framework 2.0 SP1 and SP2 verbose MSI log - %temp%\dd_net_framework20*.txt
    • .NET Framework 2.0 SP1 and SP2 language pack verbose MSI log - %temp%\dd_NET_Framework*20*LP*.txt
    • .NET Framework 3.0 SP1 and SP2 verbose MSI log - %temp%\dd_net_framework30*.txt
    • .NET Framework 3.0 SP1 and SP2 ServiceModelReg.exe custom action - %temp%\dd_wcf_retCA*.txt
    • .NET Framework 3.0 SP1 and SP2 language pack verbose MSI log - %temp%\dd_NET_Framework*30*LP*.txt

    .NET Framework 3.5 and 3.5 SP1 setup log files

    The following is a complete list of log files that can be produced during .NET Framework 3.5 and 3.5 SP1 setup.  This list may vary depending on what OS you are installing on, what processor architecture, and what prerequisite components were already installed on the system prior to running .NET Framework 3.5 and 3.5 SP1 setup.

    Logs produced by the .NET Framework 3.5 and 3.5 SP1 setup wrapper:

    • %temp%\dd_dotnetfx35install*.txt
    • %temp%\dd_dotnetfx35error*.txt
    • %temp%\dd_depcheck_netfx_*.txt

    Logs produced by the packages chained during .NET Framework 3.5 and 3.5 SP1 setup:

    • RGB Rasterizer - %temp%\dd_RGB9Rast_*.txt
    • MSXML 6.0 - %temp%\dd_msxml6_*.txt
    • WIC - %temp%\dd_wic*.txt
    • .NET Framework 2.0 SP1 and SP2 verbose MSI log - %temp%\dd_net_framework20*.txt
    • .NET Framework 2.0 SP1 and SP2 language pack verbose MSI log - %temp%\dd_NET_Framework*20*LP*.txt
    • .NET Framework 3.0 SP1 and SP2 verbose MSI log - %temp%\dd_net_framework30*.txt
    • .NET Framework 3.0 SP1 and SP2 ServiceModelReg.exe custom action - %temp%\dd_wcf_retCA*.txt
    • .NET Framework 3.5 and 3.5 SP1 verbose MSI log - %temp%\dd_net_framework35*.txt
    • .NET Framework 3.5 and 3.5 SP1 language pack verbose MSI log - %temp%\dd_NET_Framework35_LangPack*.txt

    Setup log files for other .NET Framework products

    I have written separate blog posts about log file locations for other .NET Framework products not listed above.  Here they are for your reference in case you need them:

    <update date="8/24/2008"> Updated list of .NET Framework 3.0 SP1 log files </update>

    <update date="4/13/2009"> Clarified that the list of logs in this post is applicable to 2.0 SP2, 3.0 SP2 and 3.5 SP1 as well. </update>

     

  • Aaron Stebner's WebLog

    Building an MSI using WiX v3.0 that includes the VC 8.0 runtime merge modules

    • 18 Comments

    I was recently asked a question by a customer who was building an MSI using WiX v3.0 and the Votive add-in for Visual Studio 2005.  They were trying to consume the VC 8.0 runtime merge modules (MSMs) into their MSI, but were having trouble figuring out exactly how to configure their WiX project so that it would correctly consume these MSMs and install the VC 8.0 runtime files as part of their MSI-based setup.

    I looked around a little bit and found these instructions written by Nikola Dudar on the Visual C++ team here at Microsoft.  However, the instructions in that blog post are based on WiX v2.0, and the equivalent steps in WiX v3.0 are much more straightforward, so I decided to post a set of steps that can be used to create an MSI in WiX v3.0 and Votive that consumes the VC 8.0 runtime MSMs:

    1. Install Visual Studio 2005 Standard Edition or higher
    2. Download and install the latest build of WiX 3.0 from http://wix.sourceforge.net/downloadv3.html.  You need to install the ProjectAggregator2 MSI and then the WiX 3.0 MSI
    3. Launch Visual Studio 2005
    4. Choose File | New | Project...
    5. In the New Project dialog, select the WiX project type and then the WiX Project template to create a new WiX project
    6. In the WXS file that is created as part of the new project, add new <Merge> elements as children of the TARGETDIR <Directory> element for each one of the VC 8.0 runtime merge modules that you want to include in your MSI.  For example, to include MSVCRT, use the following items:

      <Merge Id="CRT" Language="0" SourceFile="c:\Program Files\Common Files\Merge Modules\microsoft_vc80_crt_x86.msm" DiskId="1" />


      Note: You will need to change the SourceFile attributes to point to the exact locations of the MSM file on your system.  This location depends on what partition you have your OS installed to.

    7. For each <Merge> element that you addded in step 6, add a <MergeRef> element under the appropriate <Feature> element.  For example:

      <MergeRef Id="CRT" />

    8. Add any other information that you want to include in your MSI, save the project and build it using Visual Studio

    When building an MSI that consumes the VC 8.0 runtime MSMs using Votive v3.0 in Visual Studio 2005, you may see several of the following types of warnings in your build output:

    1. WixProject1.wxs(10,0): Warning LGHT1055: The InstallExecuteSequence table contains an action 'SxsInstallCA' which cannot be merged from the merge module 'c:\Program Files\Common Files\Merge Modules\policy_8_0_Microsoft_VC80_ATL_x86.msm'. This action is likely colliding with an action in the database that is being created. The colliding action may have been authored in the database or merged in from another merge module. If this is a standard action, it is likely colliding due to a difference in the condition for the action in the database and merge module. If this is a custom action, it should only be declared in the database or one merge module.
    2. light.exe(0,0): Warning LGHT1076: ICE03: String overflow (greater than length permitted in column); Table: Component, Column: KeyPath, Key(s): downlevel_manifest.8.0.50727.762.98CB24AD_52FB_DB5F_FF1F_C8B3B9A1E18E
    3. light.exe(0,0): Warning LGHT1076: ICE30: The target file 'ansiatl.dll|ATL80.dll' might be installed in '[SystemFolder]' by two different conditionalized components on an LFN system: 'ansi_atl80.97F81AF1_0E47_DC99_FF1F_C8B3B9A1E18E' and 'nosxs.97F81AF1_0E47_DC99_FF1F_C8B3B9A1E18E'. If the conditions are not mutually exclusive, this will break the component reference counting system.
    4. light.exe(0,0): Warning LGHT1076: ICE82: This action SystemFolder.97F81AF1_0E47_DC99_FF1F_C8B3B9A1E18E has duplicate sequence number 6 in the table InstallExecuteSequence
    5. light.exe(0,0): Warning LGHT1076: ICE83: The keypath for Global Win32 SXS Assembly (Component_=uplevel.66332652_9C28_58B1_FF1F_C8B3B9A1E18E) SHOULD NOT be it's manifest file for assemblies other than Win32 Policy assemblies

    The first type of warning indicates that actions with the same name exist in multiple merge modules.  Windows Installer requires unique action names, and when attempting to merge MSMs that contain multiple actions with the same name, Windows Installer will exclude all but the first action.  In this case, the exact same SxsInstallCA and SxsUninstallCA actions exist in all of the VC 8.0 runtime MSMs, and so all but the first ones are excluded from the merging process.  However, all of these actions are identical and execute the same code behind the scenes, so it is safe to ignore this type of warning because you will not be losing any required functionality during the merge process.

    The second type of warning indicates that some identifiers are longer than the maximum values specified in the _Validation table of the MSI.  The documentation for ICE03 indicates that Windows Installer does not internally limit the column width to the specified value, so these warnings can be safely ignored.

    The third type of warning helps prevent authoring different components that install the same files to the same destination folder (which would violate Windows Installer component rules).  However, in the case of these VC 8.0 MSMs, the components have conditions that are mutually exclusive (Version9x and VersionNT < 501) so the component rules will not be violated and these warnings can be safely ignored.

    The fourth type of warning indicates that actions contain duplicate sequence numbers in the InstallExecuteSequence table.  When actions have duplicate sequence numbers, there is no guarantee about what order they will be run in.  However, in this case, the actions have no order dependencies and it is safe to ignore these warnings as well.

    The fifth type of warning helps prevent authoring incorrect keypath files for Win32 global assemblies that are installed to the WinSxS component store.  This warning indicates that they keypath should not be a manifest file unless the assembly is a Win32 policy assembly.  In this case, the assembly is a Win32 policy assembly, so these warnings can also be safely ignored.

    Note: it is possible to suppress the above warnings by configuring some settings in the WiX linker project property page in Visual Studio.  In general, however, I advise against doing that because if you enable suppressions, you might end up missing other warnings or errors in the same categories that are not safe to ignore.

    <update date="2/12/2008"> Added information about ICE03 warnings that can occur when merging the VC 8.0 MSMs that I missed when I originally wrote this post. </update>

    <update date="2/11/2009"> Removed references to policy MSMs because the general recommendation is to not include policy MSMs when redistributing the VC runtime files. </update>

     

  • Aaron Stebner's WebLog

    Updated versions of .NET Framework cleanup and verification tools with Windows 7 support

    • 19 Comments

    Over the past week or so, I’ve posted updated versions of both the .NET Framework Cleanup Tool and the .NET Framework Setup Verification Tool.  The primary reason for the updates is to address some specific problems using the tools on Windows 7.  I also fixed a few other issues that customers reported to me or that I discovered in my own testing.

    Here is a list of the changes made to each of the tools:

    .NET Framework Cleanup Tool changes (July 24, 2009):

    • Added logic to correctly cleanup the .NET Framework on Windows 7.  The .NET Framework 2.0 SP2, 3.0 SP2 and 3.5 SP1 are all installed as OS components on Windows 7, so the cleanup tool will not allow you to remove these versions of the .NET Framework on this OS.
    • Added detection and logging for the .NET Framework 4.  The cleanup tool does not yet support cleaning up the .NET Framework 4.  This will be added in a future release.
    • Prevent cleanup of mscoree.dll on Vista and higher.

    .NET Framework Setup Verification Tool changes (July 17, 2009)

    • Fixed false errors being reported for non-English versions of the .NET Framework 1.0.
    • Fixed filtering problem that caused the .NET Framework 1.0 to be removed from the list of available products if any 1.0 service packs are installed.
    • Fixed false errors being reported for the .NET Framework 1.1 if the .NET Framework 1.0 is also installed on the system.
    • Fixed false errors being reported for the .NET Framework 3.5 SP1 on Windows 7.
    • Added detection and logging for .NET Framework 4 and Windows 7.  The verification tool does not yet support verifying the .NET Framework 4.  This will be added in a future release.

    User’s Guides and Download Links

    Here are links to the user’s guides for each of the tools – there are links in each user’s guide that can be used to download the latest version of each tool:

    As always, please let me know (by posting a comment on one of my blog posts or sending me an email) if you run into any issues or have any questions using either of these tools.

  • Aaron Stebner's WebLog

    Mailbag: How to detect the presence of the VC 8.0 runtime redistributable package

    • 12 Comments

    Question:

    I am building an installer that will include the Visual C++ (VC) 8.0 runtime files redistributable package (vcredist_x86.exevcredist_x64.exe and/or vcredist_ia64.exe) as a prerequisite.  How can I detect whether or not this package is already installed on the user's system so that my installer can skip installing it when appropriate?

    Answer:

    There was not a specific detection mechanism designed and built into VC 8.0 runtime files redistributable setup packages.  The setup bootstrapper that ships with Visual Studio 2005 uses the following algorithm to check for the existence of these packages:

    1. Call the MsiQueryProductState API
    2. Pass in the product code for the package that you want to detect based on the list below  
    3. Check the return value of this API.  If it is anything other than INSTALLSTATE_DEFAULT, the package is not yet installed

    Visual C++ 2005 runtime files

    Visual C++ 2005 SP1 runtime files

    Visual C++ 2005 SP1 ATL Security Update runtime files

    However, this algorithm is somewhat incomplete.  It does not cover cases where a user has installed some other application on the system that includes the VC 8.0 runtime redistributable merge modules (MSMs) as part of its MSI package.  It also does not cover the case of Windows Vista, where the VC 8.0 runtime files are installed as part of the OS.  (Note - versions of Windows newer than Windows Vista do not treat the VC++ runtime files as system files anymore.  See this knowledge base article for more information.)

    The safest way for a setup to manage detection for the VC 8.0 runtime redistributable package is to use an algorithm similar to the one listed above to check for the MSI product code and then install if it is not yet installed.  This may lead to a few cases where the setup will install it when it doesn't technically need to, but that is better than any scenarios where it could might end up not installing it when the VC runtime files are not yet present.  In addition, using this approach will add a reference count to the VC runtime files to prevent scenarios where uninstalling some other application that includes the VC runtime MSMs causes the VC runtime files to be removed from the system.

    One important note - the VC runtime redistributable packages require that the system has at least Windows Installer 3.0 (and ideally Windows Installer 3.1 because any future hotfixes produced for this package will require Windows Installer 3.1).  If your setup is going to install the VC runtime redist package, it should also check for the presence of Windows Installer 3.x and install it as well if it is not yet installed on the system.

    Other options for installing the VC 8.0 runtime files

    I also want to point out that there are other options for applications that depend on the VC 8.0 runtime files besides redistributing the vcredist_x86 or vcredist_x64 MSI packages. 

    • Include the VC runtime MSMs in your MSI package directly - this can cause issues like the ones I described in this previous blog post, but in some cases this is the easiest solution
    • Statically link to the VC runtimes when building your application - this increases the size of your binaries but eliminates the need to validate that these runtime files are present on users' systems at setup time for your application
    • Install the VC runtimes to a local folder for use only with your application - this complicates the installation logic in your MSI and causes hotfixes to not apply for your the version of these runtime files included with your application on Windows 2000

    These options have various pros and cons, and the choice you make depends on your applications and the scenarios you want to support.  There is additional discussions of some of the trade-offs on the MSDN Forums (for example, this post and this post).  I encourage you to read some of these posts and others that are included as links within them before making your setup packaging decision for the VC 8.0 runtime files.

    <update date="1/24/2006"> Added information about the IA64 version of the VC redist package. </update>

    <update date="11/19/2009"> Added information about VC++ 2005 SP1 and VC++ 2005 SP1 ATL Security Update packages. </update>

    <update date="2/11/2015"> Added a link to a knowledge base article to help clarify that post-Vista versions of Windows do not include VC++ runtime files as OS components. </update>

     

  • Aaron Stebner's WebLog

    Error installing .NET Framework on Windows XP SP2 caused by language settings

    • 24 Comments

    Note - the issue described in this blog post was originally presented as an issue on Windows XP SP2.  However, it can also affect .NET Framework 1.0 and 1.1 installation on any OS released after the .NET Framework 1.0 and 1.1 shipped - specifically, I have seen reports of this issue on Windows Vista.  The steps listed here are applicable to this type of install failure on other newer OS's like Windows Vista and not just Windows XP SP2.  

    I was contacted by a customer last week who could not get the .NET Framework 1.1 to install correctly.  It reported an error while registering System.EnterpriseServices.dll just like I describe in this post.  In the end, the customer discovered that the system locale of the computer was set to Maltese, and he was able to install the .NET Framework by temporarily changing the system locale back to English.

    I did a little research, and found that there is a bug in the .NET Framework that causes it to not work correctly when the default system locale is set to a language that the .NET Framework does not recognize.  This bug has been fixed in the .NET Framework 1.0 SP3 and 1.1 SP1.  However, this bug causes the initial installation of the .NET Framework to fail and rollback, and you cannot install the service pack without first getting the product installed (unless you use a method like I describe here, which will work but is not "officially" supported).

    With the release of Windows XP SP2, Microsoft shipped Enabling Language Kits (ELKs) for 25 new locales (click here for a complete list and a nice description of what features ELKs provide).  Because of the bug in the .NET Framework that I described above, if a computer running XP SP2 has the system locale set to one of these 25 new locales, installation of the .NET Framework will fail while trying to register System.EnterpriseServices.dll (which happens to be the first time that managed code gets run during setup and therefore is the first time the bug is hit).

    If you are running into this bug on your Windows XP SP2 computer, you can use the following steps to work around this bug in the .NET Framework and get it installed:

    1. From the Start menu, type intl.cpl in the Run box or go to Control Panel and choose the Regional and Language Options item
    2. Click the Advanced tab
    3. Change the language in the dropdown box labeled "Select a language to match the language version of the non-Unicode programs you want to use:" to English (this setting represents the system locale for the computer)
    4. Check the box labeled "Apply all settings to the current user account and to the default user profile"
    5. Click OK
    6. Restart
    7. Install the .NET Framework 1.0 or 1.1
    8. Install .NET Framework 1.0 SP3 or 1.1 SP1
    9. Return to the Regional and Language Options control panel and change the language in the Advanced tab back to the original setting

    For reference, here is what the Advanced tab of the Regional and Language Options control panel looks like.  This screenshot is from my laptop, where I was able to reproduce the failure to install the .NET Framework by changing my system locale to Welsh (one of the 25 new ELKs included in XP SP2):
     

    Regional and Language Options control panel Advanced tab

    <update date="7/26/2005> As Michael Kaplan points out, the underlying bug affects both the .NET Framework core setup and the .NET Framework service pack setup.  Once a computer has .NET Framework 1.0 + SP3 and/or 1.1 + SP1, the bug will not affect any future .NET Framework service packs.  In addition, the bug can happen if your computer has a default user locale set to one of the new ELK languages, not just a default system locale. </update>

    <update date="4/17/2008"> Added a note indicating that the issue in this post can affect the .NET Framework 1.0 and 1.1 setup on Windows Vista and not just Windows XP SP2 </update>

     

Page 5 of 48 (1,193 items) «34567»