From 3f583916719eeef598d10a5d4e14ef14f008243b Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Tue, 11 May 2021 07:36:37 -0700 Subject: Merge Dtf --- src/samples/Dtf/Documents/Guide/Content/about.htm | 59 +++ .../Dtf/Documents/Guide/Content/buildingcas.htm | 94 +++++ .../Dtf/Documents/Guide/Content/cabpack.htm | 63 +++ src/samples/Dtf/Documents/Guide/Content/cabs.htm | 101 +++++ .../Dtf/Documents/Guide/Content/cabwrapper.htm | 63 +++ .../Dtf/Documents/Guide/Content/caconfig.htm | 83 ++++ .../Dtf/Documents/Guide/Content/caproxy.htm | 74 ++++ .../Dtf/Documents/Guide/Content/databases.htm | 120 ++++++ .../Dtf/Documents/Guide/Content/debuggingcas.htm | 66 ++++ .../Dtf/Documents/Guide/Content/dependencies.htm | 88 +++++ .../Documents/Guide/Content/filepatchwrapper.htm | 34 ++ .../Dtf/Documents/Guide/Content/history.htm | 437 +++++++++++++++++++++ .../Dtf/Documents/Guide/Content/installutil.htm | 94 +++++ .../Dtf/Documents/Guide/Content/inventory.htm | 78 ++++ .../Dtf/Documents/Guide/Content/managedcas.htm | 53 +++ .../Dtf/Documents/Guide/Content/msihelper.htm | 59 +++ .../Dtf/Documents/Guide/Content/msiwrapper.htm | 80 ++++ .../Dtf/Documents/Guide/Content/packages.htm | 86 ++++ .../Dtf/Documents/Guide/Content/powerdiff.htm | 71 ++++ .../Dtf/Documents/Guide/Content/samplecas.htm | 84 ++++ .../Dtf/Documents/Guide/Content/samples.htm | 59 +++ .../Dtf/Documents/Guide/Content/support.htm | 52 +++ src/samples/Dtf/Documents/Guide/Content/using.htm | 50 +++ .../Dtf/Documents/Guide/Content/whatsnew.htm | 257 ++++++++++++ src/samples/Dtf/Documents/Guide/Content/wifile.htm | 73 ++++ .../Dtf/Documents/Guide/Content/writingcas.htm | 114 ++++++ src/samples/Dtf/Documents/Guide/DTF.hhc | 132 +++++++ src/samples/Dtf/Documents/Guide/DTF.hhk | 126 ++++++ src/samples/Dtf/Documents/Guide/DTF.hhp | 49 +++ src/samples/Dtf/Documents/Guide/dtfguide.helpproj | 29 ++ .../Dtf/Documents/Guide/styles/presentation.css | 394 +++++++++++++++++++ 31 files changed, 3222 insertions(+) create mode 100644 src/samples/Dtf/Documents/Guide/Content/about.htm create mode 100644 src/samples/Dtf/Documents/Guide/Content/buildingcas.htm create mode 100644 src/samples/Dtf/Documents/Guide/Content/cabpack.htm create mode 100644 src/samples/Dtf/Documents/Guide/Content/cabs.htm create mode 100644 src/samples/Dtf/Documents/Guide/Content/cabwrapper.htm create mode 100644 src/samples/Dtf/Documents/Guide/Content/caconfig.htm create mode 100644 src/samples/Dtf/Documents/Guide/Content/caproxy.htm create mode 100644 src/samples/Dtf/Documents/Guide/Content/databases.htm create mode 100644 src/samples/Dtf/Documents/Guide/Content/debuggingcas.htm create mode 100644 src/samples/Dtf/Documents/Guide/Content/dependencies.htm create mode 100644 src/samples/Dtf/Documents/Guide/Content/filepatchwrapper.htm create mode 100644 src/samples/Dtf/Documents/Guide/Content/history.htm create mode 100644 src/samples/Dtf/Documents/Guide/Content/installutil.htm create mode 100644 src/samples/Dtf/Documents/Guide/Content/inventory.htm create mode 100644 src/samples/Dtf/Documents/Guide/Content/managedcas.htm create mode 100644 src/samples/Dtf/Documents/Guide/Content/msihelper.htm create mode 100644 src/samples/Dtf/Documents/Guide/Content/msiwrapper.htm create mode 100644 src/samples/Dtf/Documents/Guide/Content/packages.htm create mode 100644 src/samples/Dtf/Documents/Guide/Content/powerdiff.htm create mode 100644 src/samples/Dtf/Documents/Guide/Content/samplecas.htm create mode 100644 src/samples/Dtf/Documents/Guide/Content/samples.htm create mode 100644 src/samples/Dtf/Documents/Guide/Content/support.htm create mode 100644 src/samples/Dtf/Documents/Guide/Content/using.htm create mode 100644 src/samples/Dtf/Documents/Guide/Content/whatsnew.htm create mode 100644 src/samples/Dtf/Documents/Guide/Content/wifile.htm create mode 100644 src/samples/Dtf/Documents/Guide/Content/writingcas.htm create mode 100644 src/samples/Dtf/Documents/Guide/DTF.hhc create mode 100644 src/samples/Dtf/Documents/Guide/DTF.hhk create mode 100644 src/samples/Dtf/Documents/Guide/DTF.hhp create mode 100644 src/samples/Dtf/Documents/Guide/dtfguide.helpproj create mode 100644 src/samples/Dtf/Documents/Guide/styles/presentation.css (limited to 'src/samples/Dtf/Documents/Guide') diff --git a/src/samples/Dtf/Documents/Guide/Content/about.htm b/src/samples/Dtf/Documents/Guide/Content/about.htm new file mode 100644 index 00000000..393b5a81 --- /dev/null +++ b/src/samples/Dtf/Documents/Guide/Content/about.htm @@ -0,0 +1,59 @@ + + + Deployment Tools Foundation Overview + + + + + + +
+ Deployment Tools Foundation
+ Deployment Tools Foundation
+
+ Overview + v4.0 +
+
+
+ +
+

Deployment Tools Foundation is a rich set of .NET class libraries and + related resources that together bring the Windows deployment platform + technologies into the .NET world. It is designed to greatly simplify + deployment-related development tasks while still exposing the complete + functionality of the underlying technology.

+ +

The primary focus of DTF is to provide a foundation for development of + various kinds of tools to support deployment throughout the product + lifecycle, including setup authoring, building, analysis, debugging, and + testing tools. In addition to tools, DTF can also be useful for install-time + activities such as setup bootstrappers, external UI, and custom actions, + and for application run-time activities that need to access the deployment + platform.

+ +

For a description of the the latest changes, see What's New.

+ +
+ + +
+ + + diff --git a/src/samples/Dtf/Documents/Guide/Content/buildingcas.htm b/src/samples/Dtf/Documents/Guide/Content/buildingcas.htm new file mode 100644 index 00000000..e88ad552 --- /dev/null +++ b/src/samples/Dtf/Documents/Guide/Content/buildingcas.htm @@ -0,0 +1,94 @@ + + + Building Managed Custom Actions + + + + + + +
+ Deployment Tools Foundation
+ Building Managed Custom Actions
+
+ + Development Guide > + Managed CAs > + Building + +
+
+
+ +
+ +

The build process for managed CA DLLs is a little complicated becuase of the + proxy-wrapper and dll-export requirements. Here's an overview:

+
    +
  1. +

    Compile your CA assembly, which references WixToolset.Dtf.WindowsInstaller.dll and + marks exported custom actions with a CustomActionAttribute.

    +
  2. +

    Package the CA assembly, CustomAction.config, WixToolset.Dtf.WindowsInstaller.dll, + and any other dependencies using MakeSfxCA.exe. The filenames of CustomAction.config + and WixToolset.Dtf.WindowsInstaller.dll must not be changed, since + the custom action proxy specifically looks for those files.

    +
+


+

+

Compiling

+

+    csc.exe
+        /target:library
+        /r:$(DTFbin)\WixToolset.Dtf.WindowsInstaller.dll
+        /out:SampleCAs.dll
+        *.cs
+            
+

Wrapping


+    MakeSfxCA.exe
+        $(OutDir)\SampleCAsPackage.dll
+        $(DTFbin)\SfxCA.dll
+        SampleCAs.dll
+        CustomAction.config
+        $(DTFbin)\WixToolset.Dtf.WindowsInstaller.dll
+            
+

+

Now the resulting package, SampleCAsPackage.dll, is ready to be inserted + into the Binary table of the MSI.

+


+

+

For a working example of building a managed custom action package + you can look at included sample ManagedCAs project.

+


+

+ +


+

See also:

+ +


+ +
+ + +
+ + + diff --git a/src/samples/Dtf/Documents/Guide/Content/cabpack.htm b/src/samples/Dtf/Documents/Guide/Content/cabpack.htm new file mode 100644 index 00000000..2d9f725e --- /dev/null +++ b/src/samples/Dtf/Documents/Guide/Content/cabpack.htm @@ -0,0 +1,63 @@ + + + Archive Pack/Unpack Tool + + + + + + +
+ Deployment Tools Foundation
+ Archive Pack/Unpack Tool
+
+ + Development Guide > + Samples > + XPack + +
+
+
+ +
+

Usage: CabPack.exe <directory> <package.cab>
+Usage: XPack /P <archive.cab> <directory>
+Usage: XPack /P <archive.zip> <directory>
+
+Packs all files in a directory tree into an archive,
+using either the cab or zip format. Any existing archive
+with the same name will be overwritten.
+
+
+Usage: XPack /U <archive.cab> <directory>
+Usage: XPack /U <archive.zip> <directory>
+
+Unpacks all files from a cab or zip archive to the
+specified directory. Any existing files with the same
+names will be overwritten.
+

+


+ +
+ + +
+ + + diff --git a/src/samples/Dtf/Documents/Guide/Content/cabs.htm b/src/samples/Dtf/Documents/Guide/Content/cabs.htm new file mode 100644 index 00000000..e88d1e15 --- /dev/null +++ b/src/samples/Dtf/Documents/Guide/Content/cabs.htm @@ -0,0 +1,101 @@ + + + Working with Cabinet Files + + + + + + +
+ Deployment Tools Foundation
+ Working with Cabinet Files
+
+ + Development Guide > + Cabinet Files + +
+
+
+ +
+ +

Creating a cabinet

+
    CabInfo cabInfo = new CabInfo("package.cab");
+    cabInfo.Pack("D:\\FilesToCompress");

+

1.  Create a new CabInfo instance referring to the (future) location of the .cab file.

+

2.  Compress files:

    +
  • Easily compress an entire directory with the Pack method.
  • +
  • Compress a specific list of exernal and internal filenames with the PackFiles method.
  • +
  • Compress a dictionary mapping of internal to external filenames with the PackFileSet method.
  • +
+ +


+

Listing a cabinet

+
    CabInfo cabInfo = new CabInfo("package.cab");
+    foreach (CabFileInfo fileInfo in cabInfo.GetFiles())
+        Console.WriteLine(fileInfo.Name + "\t" + fileInfo.Length);

+

1.  Create a new CabInfo instance referring to the location of the .cab file.

+

2.  Enumerate files returned by the GetFiles method.

    +
  • Each CabFileInfo instance contains metadata about one file.
  • +
+ +


+

Extracting a cabinet

+
    CabInfo cabInfo = new CabInfo("package.cab");
+    cabInfo.Unpack("D:\\ExtractedFiles");

+

1.  Create a new CabInfo instance referring to the location of the .cab file.

+

2.  Extract files:

    +
  • Easily extract all files to a directory with the Unpack method.
  • +
  • Easily extract a single file with the UnpackFile method.
  • +
  • Extract a specific list of filenames with the UnpackFiles method.
  • +
  • Extract a dictionary mapping of internal to external filenames with the UnpackFileSet method.
  • +
+ +


+

Getting progress

+ Most cabinet operation methods have an overload that allows you to specify a event handler + for receiving archive + progress events. The XPack sample + demonstrates use of the callback to report detailed progress to the console. + +


+

Stream-based compression

+ The CabEngine class contains static methods for performing compression/decompression operations directly + on any kind of Stream. However these methods are more difficult to use, since the caller must implement a + stream context + that provides the file metadata which would otherwise have been provided by the filesystem. The CabInfo class + uses the CabEngine class with FileStreams to provide the more traditional file-based interface. + +


+

See also:

+ +


+ +
+ + +
+ + + diff --git a/src/samples/Dtf/Documents/Guide/Content/cabwrapper.htm b/src/samples/Dtf/Documents/Guide/Content/cabwrapper.htm new file mode 100644 index 00000000..fd88437c --- /dev/null +++ b/src/samples/Dtf/Documents/Guide/Content/cabwrapper.htm @@ -0,0 +1,63 @@ + + + + Managed Wrapper Library for Cabinet APIs + + + + +
+
+ + + + + +
Managed Libraries for Windows Installer
+
+
+

Managed Wrapper Library for Cabinet APIs

+
+
+
+

This is a managed library that provides the ability to + create and extract cabinet files. It uses cabinet.dll (present on all versions of Windows) + to do the actual compression/decompression. It provides access to nearly all + cabinet capabilities, including spanning of multiple cab files. It even has support for + preserving directory structures and UTF8 paths.

+

There are two ways to use the library. CabinetInfo + and CabinetFileInfo + (similar to DirectoryInfo and FileInfo respectively) + provide high-level object-oriented methods for doing common file-based cabinet creation and + extraction tasks. On the other hand, the Cabinet + class provides low-level access to all + functionality, and operates completely in terms of .NET Streams. The previous two classes use + the Cabinet class to do all the actual work.

+

There are also two ways to build the library. + Compiling it normally will produce the fully functional + library in the Microsoft.Cab + namespace, while compiling it with the /D:CABMINIMAL + /D:CABEXTRACTONLY flags will create a compact assembly with only the core extraction + functionality, in the Microsoft.Cab.MiniExtract + namespace.

+

The cabinet library interops with native cabinet APIs which use the 'cdecl' + calling-convention. When building against .NET Framework versions before 2.0, + this library requires a special post-build step to process the UnmanagedFunctionPointerAttribute. + If you use this code in another assembly, don't forget to run AugmentIL + on it to fix the delegate calling-conventions, otherwise you will encounter a + NullReferenceException when attempting to call the cabinet APIs. When building against + .NET Framework version 2.0 or later, the UnmanagedFunctionPointerAttribute.cs source file + should be omitted.

+ +


+

See also:

+ +


+
+ + diff --git a/src/samples/Dtf/Documents/Guide/Content/caconfig.htm b/src/samples/Dtf/Documents/Guide/Content/caconfig.htm new file mode 100644 index 00000000..a6c97d2b --- /dev/null +++ b/src/samples/Dtf/Documents/Guide/Content/caconfig.htm @@ -0,0 +1,83 @@ + + + Specifying the Runtime Version + + + + + + +
+ Deployment Tools Foundation
+ Specifying the Runtime Version
+
+ + Development Guide > + Managed CAs > + Writing CAs > + CustomAction.config + +
+
+
+ +
+ +

Every managed custom action package should contain a CustomAction.config file, even though it is not required by the toolset. + Here is a sample:


+<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+    <startup>
+        <supportedRuntime version="v2.0.50727"/>
+    </startup>
+</configuration>

+

The configuration file follows the standard schema for .NET Framework + configuration files documented on MSDN.

+


+

Supported Runtime Version

+

In the startup section, use supportedRuntime + tags to explicitly specify the version(s) of the .NET Framework that the custom action should run on. + If no versions are specified, the chosen version of the .NET Framework will be + the "best" match to what WixToolset.Dtf.WindowsInstaller.dll was built against.

+

Warning: leaving the version unspecified is dangerous + as it introduces a risk of compatibility problems with future versions of the .NET Framework. + It is highly recommended that you specify only the version(s) + of the .NET Framework that you have tested against.

+


+ +

Other Configuration

+

Various other kinds of configuration settings may also be added to this file, as it is a standard + .NET Framework application config file + for the custom action.

+


+ +

See also:

+ +


+ +
+ + +
+ + + diff --git a/src/samples/Dtf/Documents/Guide/Content/caproxy.htm b/src/samples/Dtf/Documents/Guide/Content/caproxy.htm new file mode 100644 index 00000000..2ee962d5 --- /dev/null +++ b/src/samples/Dtf/Documents/Guide/Content/caproxy.htm @@ -0,0 +1,74 @@ + + + + Proxy Class for Managed Custom Actions + + + + +
+
+ + + + + +
Managed Libraries for Windows Installer
+
+
+

Proxy for Managed Custom Actions

+
+
+
+

The custom action proxy allows an MSI developer to write + custom actions in managed code, while maintaing all the advantages of type 1 + DLL custom actions including full access to installer state, properties, + and the session database.

+

There are generally four problems that needed to be + solved in order to create a type 1 custom action in managed code:

+
    +
  1. Exporting the CA function as a native entry point callable by + MSI: The Windows Installer engine expects to call a LoadLibrary and + GetProcAddress on the custom action DLL, so an unmanaged DLL needs to implement + the function that is initially called by MSI and ultimately returns the result. + This function acts as a proxy to relay the custom action call into the + managed custom action assembly, and relay the result back to the caller.

    +
  2. Providing supporting assemblies without + requiring them to be installed as files: If a DLL custom + action runs before the product's files are installed, then it is difficult + to provide any supporting files, because of the way the CA DLL is singly + extracted and executed from a temp file. (This can be a problem for + unmanaged CAs as well.) With managed custom actions we have already hit + that problem since both the CA assembly and the MSI wrapper assembly + need to be loaded. To solve this, the proxy DLL carries an appended + cab package. When invoked, it will extract all contents of the + cab package to a temporary working directory. This way the cab package can + carry any arbitrary dependencies the custom action may require.
  3. +
  4. Hosting and configuring the Common Language Runtime: + In order to invoke a method in a managed assembly from a previously + unmanaged process, the CLR needs to be "hosted". This involves choosing + the correct version of the .NET Framework to use out of the available + version(s) on the system, binding that version to the current process, and + configuring it to load assemblies from the temporary working directory.

    +
  5. Converting the integer session handle into a + Session object: The Session class in the managed + wrapper library has a constructor which takes an integer session handle as + its parameter. So the proxy simply instantiates this object before + calling the real CA function.

    +
+

The unmanaged CAPack module, when used in combination with the managed proxy in + the + Microsoft.WindowsInstaller assembly, accomplishes the tasks above to enable + fully-functional managed DLL custom actions.

+


+

See also:

+ +


+
+ + diff --git a/src/samples/Dtf/Documents/Guide/Content/databases.htm b/src/samples/Dtf/Documents/Guide/Content/databases.htm new file mode 100644 index 00000000..4fe1fba9 --- /dev/null +++ b/src/samples/Dtf/Documents/Guide/Content/databases.htm @@ -0,0 +1,120 @@ + + + Working with MSI Databases + + + + + + +
+ Deployment Tools Foundation
+ Working with MSI Databases
+
+ + Development Guide > + MSI Databases + +
+
+
+ +
+ +

Querying a database

+
    using (Database db = new Database("product.msi", DatabaseOpenMode.ReadOnly))
+    {
+        string value = (string) db.ExecuteScalar(
+            "SELECT `Value` FROM `Property` WHERE `Property` = '{0}'", propName);
+    }

+

1.  Create a new Database + instance referring to the location of the .msi or .msm file.

+

2.  Execute the query:

+ +


+

Updating a binary

+
    Database db = null;
+    View view = null;
+    Record rec = null;
+    try
+    {
+        db = new Database("product.msi", DatabaseOpenMode.Direct);
+        view = db.OpenView("UPDATE `Binary` SET `Data` = ? WHERE `Name` = '{0}'", binName))
+        rec = new Record(1);
+        rec.SetStream(1, binFile);
+        view.Execute(rec);
+        db.Commit();
+    }
+    finally
+    {
+        if (rec != null) rec.Close();
+        if (view != null) view.Close();
+        if (db != null) db.Close();
+    }

+

1.  Create a new Database + instance referring to the location of the .msi or .msm file.

+

2.  Open a view by calling one of the Database.OpenView overloads.

    +
  • Parameters can be substituted in the SQL string using the String.Format syntax.
  • +
+

3.  Create a record with one field containing the new binary value.

+

4.  Execute the view by calling one of the View.Execute overloads.

    +
  • A record can be supplied for substitution of field tokens (?) in the query.
  • +
+

5.  Commit the Database.

+

6.  Close the handles.

+ +


+

About handles

+

Handle objects (Database, View, Record, SummaryInfo, Session) will remain open until + they are explicitly closed or until the objects are collected by the GC. So for the tightest + code, handle objects should be explicitly closed when they are no longer needed, + since closing them can release significant resources, and too many unnecessary + open handles can degrade performance. This is especially important within a loop + construct: for example when iterating over all the Records in a table, it is much cleaner + and faster to close each Record after it is used.

+

The handle classes in the managed library all extend the + InstallerHandle + class, which implements the IDisposable interface. This makes them easily managed with C#'s + using statement. Alternatively, they can be closed in a finally block.

+

As a general rule, methods in the library return new handle objects that should be managed + and closed by the calling code, while properties only return a reference to a prexisting handle + object.

+ +


+

See also:

+ +


+ +
+ + +
+ + + diff --git a/src/samples/Dtf/Documents/Guide/Content/debuggingcas.htm b/src/samples/Dtf/Documents/Guide/Content/debuggingcas.htm new file mode 100644 index 00000000..ca1be161 --- /dev/null +++ b/src/samples/Dtf/Documents/Guide/Content/debuggingcas.htm @@ -0,0 +1,66 @@ + + + Debugging Managed Custom Actions + + + + + + +
+ Deployment Tools Foundation
+ Debugging Managed Custom Actions
+
+ + Development Guide > + Managed CAs > + Debugging + +
+
+
+ +
+

There are two ways to attach a debugger to a managed custom action.

+

Attach to message-box: Add some temporary code to your custom action to display a + message box. Then when the message box pops up at install time, you can attch your + debugger to that process (usually identifiable by the title of the message box). + Once attached, you can ensure that symbols are loaded if necessary (they will be automatically + loaded if PDB files were embedded in the CA assembly at build time), then set breakpoints + anywhere in the custom action code.

+

MMsiBreak environment variable: When debugging managed custom actions, + you should use the MMsiBreak environment variable instead of MsiBreak. Set the MMsiBreak + variable to the custom action entrypoint name. (Remember this might be different from + the method name if it was overridden by the CustomActionAttribute.) When the CA proxy + finds a matching name, the CLR JIT-debugging dialog + will appear with text similar to "An exception 'Launch for user' has occurred + in YourCustomActionName." The debug break occurs after the custom + action assembly has been loaded, but just before custom action method is invoked. + Once attached, you can ensure that symbols are loaded if necessary, + then set breakpoints anywhere in the custom action code. Note: the MMsiBreak + environment variable can also accept a comma-separated list of action names, any of + which will cause a break when hit.

+


+ +
+ + +
+ + + diff --git a/src/samples/Dtf/Documents/Guide/Content/dependencies.htm b/src/samples/Dtf/Documents/Guide/Content/dependencies.htm new file mode 100644 index 00000000..cfec5880 --- /dev/null +++ b/src/samples/Dtf/Documents/Guide/Content/dependencies.htm @@ -0,0 +1,88 @@ + + + Dependencies + + + + + + +
+ Deployment Tools Foundation
+ Dependencies
+
+ + Overview > + Dependencies + +
+
+
+ +
+ +

This page lists all the components that the DTF project depends on, at build time and at run-time.

+ +

Build-time Dependencies

+
    +
  • Visual Studio / .NET Framework - Most of DTF can be built with Visual Studio 2005 & + .NET Framework 2.0. However, the LINQ project requires VS 2008 & .NET Framework 3.5.

  • + +
  • Sandcastle - .NET documentation build engine from Microsoft, used to process all the XML doc-comments + in DTF libraries into DTFAPI.chm. + (official site)

  • + +
  • Sandcastle Builder - Sandcastle by itself is complex and difficult to use; this free tool + from Codeplex provides an easy-to-use project system around it to automate the documentation build process. + (project link)

  • + +
  • HTML Help Workshop - Tools for building HTML Help 1.x (CHM files). Used to build DTF.chm. + (download link)

  • +
+ +

Run-time Dependencies

+
    +
  • .NET Framework - Most of DTF requires .NET Framework 2.0. (.NET 1.1 is no longer supported.) + The only exception is the LINQ assembly which requires .NET Framework 3.5.

  • + +
  • Windows Installer - Windows Installer introduced new APIs and capabilities with each successive + version. Obviously, the corresponding functionality in the managed APIs is only available when the required + version of the Windows Instaler (msi.dll) is installed on the system. Use the Installer.Version property + to easily check the currently installed MSI version. Attempting to use an API not supported by the current + version will result in an EntryPointNotFoundException. To check what version is required for a particular API, + see the documentation link to the corresponding unmanaged API in MSI.chm.

    +

    In some instances when a newer version of MSI provides an "Ex" alternative to a function, only the "Ex" + function is used by the managed library. This may hide some functionality that would have otherwise been + available on a system with an older version of MSI.

  • + +
  • cabinet.dll - The DTF cabinet compression library uses cabinet.dll to implement the + low-level cabinet compression and decompression. This DLL is part of all versions of Windows, + located in the system directory.

  • + +
  • System.IO.Compression.DeflateStream - The DTF zip compression library uses this class + to implement the low-level zip compression and decompression. This class is part of .NET Framework + 2.0 and later.

  • +
+ +
+ + +
+ + + diff --git a/src/samples/Dtf/Documents/Guide/Content/filepatchwrapper.htm b/src/samples/Dtf/Documents/Guide/Content/filepatchwrapper.htm new file mode 100644 index 00000000..6bab69b5 --- /dev/null +++ b/src/samples/Dtf/Documents/Guide/Content/filepatchwrapper.htm @@ -0,0 +1,34 @@ + + + + Managed Wrapper for Binary File Patch APIs + + + + +
+
+ + + + + +
Managed Libraries for Windows Installer
+
+
+

Managed Wrapper for Binary File Patch APIs

+
+
+
+

The binary file patch creation and application APIs (supplied by MsPatchC.dll and + MsPatchA.dll) are wrapped in the Microsoft.WindowsInstaller.FilePatch.dll assembly.

+ +


+

See also:

+ +


+
+ + diff --git a/src/samples/Dtf/Documents/Guide/Content/history.htm b/src/samples/Dtf/Documents/Guide/Content/history.htm new file mode 100644 index 00000000..704ce875 --- /dev/null +++ b/src/samples/Dtf/Documents/Guide/Content/history.htm @@ -0,0 +1,437 @@ + + + Change History + + + + + + +
+ Deployment Tools Foundation
+ Change History
+
+ + Overview > + Change History + +
+
+
+ +
+ +

2007-07-03

+See What's New?
 
 
+
+

2005-03-30

+ +
    +
  • New custom action proxy
      +
    • Managed custom actions use an XML config file to specify the CLR version.
    • +
    • New CAPack module is an unmanaged self-extracting CA DLL that can wrap both + managed and unmanaged custom actions. (The old managed CAProxy module is obsolete.)
    • +
    • Custom action build process is different but still complicated -- + see documentation for details.
    • +
    • CustomActionAttribute no longer accepts the optional NativeDependencies + parameter since it does not apply to the new proxy (all packaged files + are always extracted and available when the CA executes).
    • +
  • + +
  • 64bit support
      +
    • Various code fixes to pointer/handle types and structure alignments.
    • +
    • Cabinet and MSI libraries tested on AMD64 CLR.
    • +
    • Unmanaged and managed parts of custom action proxy tested on AMD64.
    • +
  • + +
  • MSI 3.1 APIs added:
      +
    • Installer.SetExternalUI(ExternalUIRecordHandler)
    • +
    • Installer.NotifySidChange
    • +
  • + +
  • Code builds easier with .NET Famework 2.0
      +
    • AugmentIL post-build step is no longer necessary when compiling the cabinet code + against .NET Framework 2.0, which has builtin support for cdecl delegates.
    • +
    • All C# code compiles against .NET Framework 2.0 without obsolete warnings, + when setting the NETFX2 preprocessor define.
    • +
    • Same code is still compatible with .NET Framework 1.0 + AugmentIL.
    • +
  • + +
  • Miscellaneous bugfixes/changes:
      +
    • InstallPackage.ExtractFiles could fail in some cominations of + compressed/uncompressed files - fixed.
    • +
    • Installer.DeterminePatchSequence was broken due to an incorrect interop struct - fixed.
    • +
    • CabinetInfo and CabinetFileInfo classes made serializable.
    • +
    • Added Session.FormatString method to simplify formatting a string with + property substitutions.
    • +
  • +
  • Documentation updates:
      +
    • Updated all documentation for new CA proxy.
    • +
    • Added new topic discussing InstallUtil.
    • +
  • +
+ +
+

2004-04-13

+ +
    +
  • Documentation
      +
    • Consolidated all documentation into a single CHM file.
    • +
    • Added new topics about working with MSI databases & cabinet files, + to help new users get oriented more easily.
    • +
  • + +
  • WindowsInstaller
      +
    • Removed [Beta] tags from MSI 3.0 APIs, but otherwise there + have been no changes since 3.0 Beta 1.
        +
      • Be warned these are still the least-tested parts of + the library, so early users may encounter bugs.
      • +
    • +
  • + +
  • InstallPackage
      +
    • Fixed InstallPackage.ExtractFiles() bug when directory doesn't exist.
    • +
    • Added ability to handle uncompressed files in a package marked as compressed.
    • +
  • + +
  • Cabinet
      +
    • Fixed improper handling of file attributes.
        +
      • This bug caused some packages to not be extractable by other tools.
      • +
    • +
    • Added support for UTF filenames.
        +
      • Non-ASCII filenames will automatically be stored as UTF-8. + (But note most other tools don't know how to extract them.)
      • +
    • +
  • +
+ +
+

2003-10-13

+ +
    +
  • Cab
      +
    • Fixed a bug introduced in v2.4.0 that caused files to be left in the %TEMP% + directory after creating a cab.
    • +
    • Unsealed the CabinetInfo, CabinetFileInfo, CabinetStatus classes and made a few methods + protected and virtual.
    • +
  • + +
  • AugmentIL
      +
    • Fixed a bug that sometimes caused a crash when specifying a relative output path + on the command-line.
    • +
    • Fixed a bug that sometimes caused the Win32 version to be missing from the output file.
    • +
  • + +
  • Samples\Diff: added new sample tool
      +
    • Recursively diffs directories, MSIs, MSPs, CABs, other files.
    • +
  • +
+ +
+

2003-09-23

+ +
    +
  • Cab
      +
    • Fixed a bug that caused compressing very large files/file sets to use way too + much memory. Performance on large inputs is now within a few % of native cab tools + (sometimes even a little faster!) for the same compression level.
    • +
  • + +
  • WindowsInstaller
      +
    • All the new MSI 3.0 beta APIs are wrapped, resulting in the following additions:
        +
      • New classes - Product, Patch (for accessing sourcelist and other config)
      • +
      • New methods on Install class - GetProducts, GetPatches, RemovePatches, + ApplyMultiplePatches, DetermineApplicablePatches, ExtractPatchXmlData
      • +
      • New enumerations - InstallContext, PatchStates, SourceType
      • +
      • Additional InstallProperty values
      • +
    • +
    • Note, MSI 3.0 support should be considered preliminary for now, + as APIs (both native and managed) are subject to change.
    • +
    • For MSI 2.0 compatibility, developers should not use any classes or + methods that are marked as [MSI 3.0 beta] in the documentation.
    • +
    • And unrelated to 3.0, a few additional enums have been added: + DialogAttributes, ControlAttributes, CustomActionTypes, + IniFileAction, RegistryRoot, RemoveFileInstallMode, + ServiceControlEvents, ServiceInstallFlags, TextStyles, + UpgradeAttributes, LocatorType
    • +
    • Also made a few minor non-breaking changes to keep the library FxCop-clean.
    • +
  • + +
  • AugmentIL
      +
    • Added support for strongname signing and delay-signing. AugmentIL tries to + locate the keyfile using the AssemblyKeyFileAttribute, or you may specify the + path with the new /key option.
    • +
    • All "released" assemblies will now be strongname-signed + (with an unofficial key).
    • +
  • + +
  • CAProxy
      +
    • Added support for NativeDependencies property on CustomActionAttribute. This enables + custom actions to P/Invoke into native DLLs that are carried with them.
    • +
  • + +
  • Samples\SampleCAs
      +
    • In SampleCA2, changed MessageBox.Show("") to session.Message(User,""), + because generally it is a bad practice for CAs to show independent UI.
    • +
    • Added test of CustomActionAttribute.NativeDependencies functionality.
    • +
  • + +
  • Samples\CabPack: added new sample
      +
    • Demonstrates & tests the cab library by creating self-extracting packages
    • +
  • + +
  • Samples\Inventory: added new sample
      +
    • Shows a hierarchical, relational, searchable view of all of the product, + feature, component, file, and patch data managed by MSI, for all products + installed on the system.
    • +
  • +
+ +
+

2003-09-12

+ +
    +
  • Cab:
      +
    • Added CabinetInfo.CompressDirectory method, capable of compressing an + entire directory tree structure.
    • +
    • Updated documentation of various methods concerning support of directory + structure inside cabs.
    • +
    • CabinetInfo case-sensitivity was inconsistent - + now it is case-insensitive by default, though case is still preserved
    • +
    • Separated assembly attributes into assembly.cs
    • +
  • +
  • Msi:
      +
    • InstallerException and subclasses automatically get extended error data + from MSI's last-error-record when available. The data is stored + in the exception and made available through the GetErrorRecord() + method, and the exception's Message includes the formatted error + message and data. This makes most exceptions extremely informative!
    • +
    • Added View.GetValidationErrors() method, and supporting ValidationErrorInfo + struct and ValidationError enum. This wrapper for the MsiViewGetError + API had been accidentally left out.
    • +
    • Session.Message() now supports message-box flags to specify buttons & icon
    • +
    • Added doc remarks to various methods about closing handles.
    • +
    • Separated assembly attributes into assembly.cs
    • +
  • +
  • AugmentIL:
      +
    • Recent builds of ildasm v2.0.* have a slightly different output format, + which could break AugmentIL in some cases - fixed
    • +
  • +
  • SampleCAs:
      +
    • Removed 'using' clause from SampleCA1 -- there's no need to close the session's active database handle
    • +
  • +
  • Documentation:
      +
    • Added note to ReadMe about compiling the cab source into another assembly
    • +
  • +
+ +
+

2003-08-07

+ +
    +
  • Cab:
      +
    • CabinetInfo.IsValid() usually returned false even for valid cabs - fixed
    • +
    • Extracting cab files with null timestamps generated exception - fixed
    • +
  • +
  • Msi:
      +
    • Added InstallCanceledException, subclass of InstallerException; + Methods which may be canceled by the user can throw this exception
    • +
    • Added MessageResult enumeration; + Used by Session.Message() and ExternalUIHandler delegate
    • +
    • Installer.EnableLog() now supports extended attributes correctly: + Append mode and flush-every-line
    • +
    • Added Session.DoActionSequence() - + This wrapper for the MsiSequence API had been accidentally left out
    • +
  • +
  • CAProxy:
      +
    • Catches InstallCanceledException, returns ERROR_INSTALL_USEREXIT + so CA developer doesn't necessarily have to handle the exception
    • +
  • +
  • Msi\Package:
      +
    • Added TransformInfo class: metadata about an individual patch transform
    • +
    • Added PatchPackage.GetTransform*() methods which return TransformInfo
    • +
  • +
  • Documentation:
      +
    • Added section to ReadMe.htm about building managed custom actions
    • +
  • +
+ +
+

2003-06-02

+ +
    +
  • Msi:
      +
    • Validation didn't work on merge modules - fixed
    • +
  • +
  • CAProxy:
      +
    • Was broken in 2.1 - fixed
    • +
  • +
+ +
+

2003-05-14

+ +
    +
  • Msi:
      +
    • External UI handler didn't survive a garbage collection - fixed
    • +
    • Validation engine was completely broken - now it should work + at least for MSIs which are already mostly valid
    • +
    • Added DynamicLoad property to CustomActionAttribute
      + Usage: set DynamicLoad=false when using XmlSerialization; default is true
    • +
  • +
  • Msi\Package:
      +
    • File extraction and update methods didn't work on merge modules - fixed
    • +
    • Made file update code slightly more robust
    • +
    • Removed hard-reference to the FilePatch assembly - now it is only + loaded if working with binary file patches
    • +
  • +
  • AugmentIL:
      +
    • AugmentIL would crash if some input files had read-only attr - fixed
    • +
    • Made /verbose switch slightly more verbose
    • +
  • +
  • CAProxy:
      +
    • Added support for the DynamicLoad property of CustomActionAttribute
    • +
    • Added MMsiBreak debugging functionality - see doc
    • +
  • +
  • Samples\WiFile:
      +
    • Added /l (list files) switch
    • +
  • +
  • Samples\SampleCAs:
      +
    • In the makefile the comments about debug builds had an error; + Now the sample builds debug packages (correctly) by default.
    • +
  • +
  • Documentation:
      +
    • Wrote AugmentIL.htm describing the AugmentIL tool and its options.
    • +
    • Wrote WiFile.htm describing the WiFile sample tool.
    • +
    • Added section to ReadMe.htm about debugging managed custom actions.
    • +
  • +
+ +
+

2003-03-31

+ +
    +
  • Msi: Implemented the remaining APIs, also minor improvements and bugfixes
      +
    • All published APIs are wrapped, with the exception of four: + MsiGetFileSignatureInformation (because I don't know of a .NET analog + for the returned certificate structure), and 3 APIs for previewing UI
    • +
    • Database.OpenView and Database.Execute* now take String.Format style params
    • +
    • Database.ApplyTransform can optionally use the error-suppression flags + stored in the transform summary info
    • +
    • Added a few supporting enumerations and structures for the remaining APIs
    • +
    • InstallerException gets a descriptive message for any MSI or system error
    • +
    • Fixed a bug in InstallerException which would usually report "error 0"
    • +
    • Added optimization for setting a Record field to a MemoryStream
    • +
    • Record.GetStream is capable of extracting substorages
    • +
    • Moved InstallPath class to Microsoft.WindowsInstaller.Package assembly
    • +
  • +
  • Msi\FilePatch: added new project
      +
    • Binary file patch API wrapper
    • +
  • +
  • Msi\Package: added new project
      +
    • Helper classes for working with MSI and MSP packages
    • +
  • +
  • Cab: some minor bugfixes
      +
    • Cabinet.Extract(stream, name) threw a NullReferenceException if the file + didn't exist in the cab -- now it returns null
    • +
    • CabinetInfo.CompressFileSet() was broken -- fixed
    • +
    • If a Cabinet callback throws an exception, it is propogated as the + inner-exception of the CabinetException
    • +
  • +
  • Samples\WiFile: added new sample
      +
    • Demonstrates some features of InstallPackage class in Msi\Package project
    • +
  • +
+ +
+

2003-03-20

+ +Documentation!
    +
  • Msi and Cab sources include complete C# XML documentation.
  • +
  • Msi and Cab makefiles generate XML documentation files.
  • +
  • Reference CHM compiled from XML documentation with NDoc.
  • +
+ +

I am aware that exceptions are still not documented in most areas. + Other than that, feel free to send me a note if it's still not clear + how to use parts of the API after reading the documentation.

+ +

Version is still 1.1 because there are no code changes in this release.

+ +
+

2003-03-13

+ +
    +
  • Msi: lots of small improvements for usability and consistency
      +
    • Reworked ExternalUIHandler support
    • +
    • Added Installer properties/methods:
        +
      • Components
      • +
      • ComponentClients()
      • +
      • ComponentState()
      • +
      • ComponentPath()
      • +
      • EnableLog()
      • +
    • +
    • Added Session.EvaluateCondition() method
    • +
    • Improved exception-handling in many methods in Installer, Database, + & Session classes
    • +
    • Added extensive XML doc-comments to Installer, Database, View, + & Session classes
    • +
    • A few breaking changes:
        +
      • View.ModifyMode enumeration moved outside View and + renamed ViewModifyMode
      • +
      • InstallLogMode enumeration renamed to InstallLogModes + (naming convention for bitfields)
      • +
      • Record constructor takes arbitrary number of parameters
      • +
    • +
  • +
  • AugmentIL: almost completely rewritten
      +
    • Ildasm/ilasm steps are built-in
        +
      • The round-trip can be done in one step
      • +
      • IL source input/output is still supported
      • +
    • +
    • Never throws an unhandled exception
    • +
    • Organized command-line options, consistent with other .NET tools
    • +
    • Uses a plugin architecture to allow additional augmentations
    • +
  • +
  • CAProxy: Added AIL_CAProxy.cs - AugmentIL plugin generates CA proxy methods
  • + +
  • SampleCAs: Updated makefile for new AugmentIL usage
  • +
+ +
+

2003-01-16

+ +
    +
  • ReadMe.htm: Added section on writing managed CAs
  • +
  • SampleCAs: Added missing reference to System.Windows.Forms.dll to the makefile
  • +
  • AugmentIL: Added specific warning messages for when CA method has wrong signature
  • +
  • Put sources in Toolbox-hosted Source Depot.
  • +
+ +
+

2003-01-14

+Initial posting to http://toolbox + +

 

+
+ + +
+ + + diff --git a/src/samples/Dtf/Documents/Guide/Content/installutil.htm b/src/samples/Dtf/Documents/Guide/Content/installutil.htm new file mode 100644 index 00000000..e235a7b6 --- /dev/null +++ b/src/samples/Dtf/Documents/Guide/Content/installutil.htm @@ -0,0 +1,94 @@ + + + About InstallUtil + + + + + + +
+ Deployment Tools Foundation
+ About InstallUtil
+
+ + Development Guide > + Managed CAs > + InstallUtil + +
+
+
+ +
+

+ InstallUtil is often considered as another option for executing MSI custom actions + written in managed code. But in most cases it is not the best solution, for a number + of reasons.

+

+ InstallUtil (in either InstallUtil.exe or InstallUtilLib.dll form) is a .NET Framework + tool for executing the System.Configuration.Installer classes that are implemented + in an assembly. That way the assembly can contain any special code required to install + itself and uninstall itself. Essentially it is the .NET replacement for COM self-registration + aka DllRegisterServer.

+

+ Self-reg or System.Configuration.Installer is convenient for development use in + order to test code without creating an actual setup package, or for an IDE which + wants to generate self-installing code. But experienced setup developers and the + Windows Installer documentation + all agree that self-reg is a bad practice for a + production-quality setup. The current theory of state-of-the-art setup is that it + should be as data-driven as possible. That is, the setup package describes as fully + as possible the desired state of the system, and then the installer engine calculates + the necessary actions to install, uninstall, patch, etc.

+

+ S.C.I encourages developers to write code for things such as registering services + or registering COM classes or other things which are more appropriately done using + built-in MSI functionality (the ServiceInstall and Registry tables). The Visual + Studio .NET wizards also tend to generate this kind of install code. Again, that + is nice for development but not good for real installations. You end up with similar + but slightly different code in many places for doing the same thing. And that code + is a black-box to the installer engine.

+

+ An ideal MSI custom action is a logical extension of the setup engine, meaning it + is data-driven and written in a very generic way to read from existing or custom + tables in the MSI database, following a very similar pattern to the built-in actions. + This makes the CA re-usable, and makes the installation more transparent. S.C.I + custom actions invoked by InstallUtil cannot be data-driven because they don't have + full access to the install session or database. They also cannot write to the install + session's regular MSI log, but instead use a separate log which is bad for supportability.

+

+ InstallUtil also requires that the assembly be installed before the CA is able to + execute. This is a problem for CAs that need to execute during the UI phase, or + gather information before installation. For that purpose MSI allows custom action + binaries to be embedded as non-installed files, but InstallUtil cannot make use + of those.

+

+ Custom actions developed with DTF have none of the limitations of InstallUtil, + giving a setup developer full capabilities to write well-designed custom actions, + only now in managed code. +

+ +

 

+
+ + +
+ + + diff --git a/src/samples/Dtf/Documents/Guide/Content/inventory.htm b/src/samples/Dtf/Documents/Guide/Content/inventory.htm new file mode 100644 index 00000000..40a6ef74 --- /dev/null +++ b/src/samples/Dtf/Documents/Guide/Content/inventory.htm @@ -0,0 +1,78 @@ + + + Windows Installer System Inventory Viewer + + + + + + +
+ Deployment Tools Foundation
+ Windows Installer System Inventory Viewer
+
+ + Development Guide > + Samples > + Inventory + +
+
+
+ +
+

This application shows a hierarchical, relational, searchable + view of all of the product, feature, component, file, and patch + data managed by MSI, for all products installed on the system.

+


+ +

Navigation

+
    +
  1. The tree on the left is self-explanatory.

  2. +
  3. Click on a row-header (grey box on the left side of the + grid) to jump to a table with more details about the item referred + to by that row. For example, clicking on a row-header of a + table that lists components will take you to a table that lists + the files in that component. Not every table has this ability, + but the cursor will turn to a hand shape to indicate when this is + possible.

  4. +
  5. Also you can navigate back and forward through your history + using the buttons in the application or mouse buttons 4 and 5.

  6. +
+


+ +

Searching

+

The search feature is not hard to find. By default, searches + are limited to the current table. However, if you choose to find + "In Subtree" by checking the box, the search will include + the current table as well as all tables under the current location in + the tree. While this can take a long time if there is a lot of + data under the current node, you can stop the search at any time with + the stop button. The search pauses when a match is found, but + clicking "Find" again will continue the same search from that + point (unless you uncheck the "Continue" checkbox or change + the search string).

+ +


+
+ + +
+ + + diff --git a/src/samples/Dtf/Documents/Guide/Content/managedcas.htm b/src/samples/Dtf/Documents/Guide/Content/managedcas.htm new file mode 100644 index 00000000..9cce0432 --- /dev/null +++ b/src/samples/Dtf/Documents/Guide/Content/managedcas.htm @@ -0,0 +1,53 @@ + + + Managed Custom Actions + + + + + + +
+ Deployment Tools Foundation
+ Managed Custom Actions
+
+ + Development Guide > + Managed CAs + +
+
+
+ + + + +
+ + + diff --git a/src/samples/Dtf/Documents/Guide/Content/msihelper.htm b/src/samples/Dtf/Documents/Guide/Content/msihelper.htm new file mode 100644 index 00000000..c1493117 --- /dev/null +++ b/src/samples/Dtf/Documents/Guide/Content/msihelper.htm @@ -0,0 +1,59 @@ + + + + Included Components + + + + +
+
+ + + + + +
Managed Libraries for Windows Installer
+
+
+

Helper Classes for Windows Installer Packages

+
+
+
+

Included are some useful helper classes for working with + MSI and MSP packages:

+ +


+

These classes are in the Microsoft.WindowsInstaller.Package.dll assembly.

+


+

See also:

+

The WiFile sample tool demonstrates some usage of the + InstallPackage class.

+


+
+ + diff --git a/src/samples/Dtf/Documents/Guide/Content/msiwrapper.htm b/src/samples/Dtf/Documents/Guide/Content/msiwrapper.htm new file mode 100644 index 00000000..70190ac4 --- /dev/null +++ b/src/samples/Dtf/Documents/Guide/Content/msiwrapper.htm @@ -0,0 +1,80 @@ + + + + Included Components + + + + +
+
+ + + + + +
Managed Libraries for Windows Installer
+
+
+

Managed wrapper library for Windows Installer APIs

+
+
+
+

Microsoft.WindowsInstaller.dll is a complete .NET wrapper for the + Windows Installer APIs. It provides a convenient object model that is + comfortable to .NET developers and still familiar to anyone who has used + the MSI scripting object model.

+

Notes

+ +

Why rewrite it?

+

It is possible to access MSI's COM Automation interfaces via C# and VB.NET. + So why create yet another wrapper? Here are some of my reasons:

+ + +


+

See also:

+ +


+
+ + diff --git a/src/samples/Dtf/Documents/Guide/Content/packages.htm b/src/samples/Dtf/Documents/Guide/Content/packages.htm new file mode 100644 index 00000000..aa521685 --- /dev/null +++ b/src/samples/Dtf/Documents/Guide/Content/packages.htm @@ -0,0 +1,86 @@ + + + Working with Install Packages + + + + + + +
+ Deployment Tools Foundation
+ Working with Install Packages
+
+ + Development Guide > + Install Packages + +
+
+
+ +
+ +

Updating files in a product layout

+

The InstallPackage class makes it easy to work with files and cabinets + in the context of a compressed or uncompressed product layout.

+

This hypothetical example takes an IDictionary 'files' which maps file keys to file paths. Each + file is to be updated in the package layout; cabinets are even recompressed if necessary to include the new files.

+
    using (InstallPackage pkg = new InstallPackage("d:\builds\product.msi",
+        DatabaseOpenMode.Transact))
+    {
+        pkg.WorkingDirectory = Path.Combine(Path.GetTempFolder(), "pkgtmp");
+        foreach (string fileKey in files.Keys)
+        {
+            string sourceFilePath = files[fileKey];
+            string destFilePath = pkg.Files[fileKey].SourcePath;
+            destFilePath = Path.Combine(pkg.WorkingDirectory, destFilePath);
+            File.Copy(sourceFilePath, destFilePath, true);
+        }
+        pkg.UpdateFiles(new ArrayList(files.Keys));
+        pkg.Commit();
+        Directory.Delete(pkg.WorkingDirectory, true);
+    }

+

1.  Create a new InstallPackage + instance referring to the location of the .msi. This is actually just a specialized subclass of a Database.

+

2.  Set the WorkingDirectory. + This is the root directory where the package expects to find the new source files.

+

3.  Copy each file to its proper location in the working directory. The + InstallPackage.Files + property is used to look up the relative source path of each file.

+

4.  Call InstallPackage.UpdateFiles + with the list of file keys. This will re-compress and package the files if necessary, and also update the + following data: File.FileSize, File.Version, File.Language, MsiFileHash.HashPart*.

+

5.  Commit the database changes and cleanup the working directory.

+ + +


+

See also:

+ +


+ +
+ + +
+ + + diff --git a/src/samples/Dtf/Documents/Guide/Content/powerdiff.htm b/src/samples/Dtf/Documents/Guide/Content/powerdiff.htm new file mode 100644 index 00000000..f420b47e --- /dev/null +++ b/src/samples/Dtf/Documents/Guide/Content/powerdiff.htm @@ -0,0 +1,71 @@ + + + MSI, MSP, CAB Diff Tool + + + + + + +
+ Deployment Tools Foundation
+ MSI, MSP, CAB Diff Tool
+
+ + Development Guide > + Samples > + DDiff + +
+
+
+ +
+

MSI, MSP, CAB Diff Tool

+ +

Usage: DDiff target1 target2 [options]
+Example: DDiff d:\dir1 d:\dir2
+Example: DDiff setup1.msi setup2.msi
+Example: DDiff patch1.msp patch2.msp -patchtarget target.msi
+Example: DDiff package1.cab package2.cab
+
+Options:
+  /o [filename]    Output results to text file (UTF8)
+  /p [package.msi] Diff patches relative to target MSI
+

+


+ +

The following types of inputs can be diffed: +

    +
  • Directories: files and subdirectories are compared.
  • +
  • Cab files: internal file list and files are compared.
  • +
  • MSI/MSM database files: summary info, tables, and embedded binary and cab streams are compared.
  • +
  • MSP files: summary info and embedded file cab are compared. When a patch target MSI is provided, the MSP's tables are also compared.
  • +
  • Versioned files: Win32 file version is compared.
  • +
  • Text files: if diff.exe is in the path, it is used to get a line-by-line diff.
  • +
  • Other files: file size and bytes are compared.
  • +
+ All processing is done recursively. So a versioned file within a cab within an MSI within a directory will have meaningful diff results.

+ +


+
+ +
+ + + diff --git a/src/samples/Dtf/Documents/Guide/Content/samplecas.htm b/src/samples/Dtf/Documents/Guide/Content/samplecas.htm new file mode 100644 index 00000000..4dfed6f0 --- /dev/null +++ b/src/samples/Dtf/Documents/Guide/Content/samplecas.htm @@ -0,0 +1,84 @@ + + + Sample C# Custom Action + + + + + + +
+ Deployment Tools Foundation
+ Sample C# Custom Action
+
+ + Development Guide > + Managed CAs > + Writing CAs > + C# Sample + +
+
+
+ +
+ +

MSI custom actions are MUCH easier to write in C# than + in C++!

    [CustomAction]
+    public static ActionResult SampleCustomAction1(Session session)
+    {
+        session.Log("Hello from SampleCA1");
+        
+        string testProp = session["SampleCATest"];
+        string testProp2;
+        testProp2 = (string) session.Database.ExecuteScalar(
+            "SELECT `Value` FROM `Property` WHERE `Property` = 'SampleCATest'");
+        
+        if(testProp == testProp2)
+        {
+            session.Log("Simple property test passed.");
+            return ActionResult.Success;
+        }
+        else
+            return ActionResult.Failure;
+    }
+            
+

A sample CA project with two CAs is included in the + Samples\ManagedCA directory.  Running the CustomActionTest project will package the CA and insert + it into a test MSI. The MSI will invoke the custom actions, but it will not install anything + since the second sample CA returns ActionResult.UserExit. +

+ +


+

See also:

+ +


+ +
+ + +
+ + + diff --git a/src/samples/Dtf/Documents/Guide/Content/samples.htm b/src/samples/Dtf/Documents/Guide/Content/samples.htm new file mode 100644 index 00000000..3bcd379a --- /dev/null +++ b/src/samples/Dtf/Documents/Guide/Content/samples.htm @@ -0,0 +1,59 @@ + + + Sample Applications + + + + + + +
+ Deployment Tools Foundation
+ Sample Applications
+
+ + Development Guide > + Samples + +
+
+
+ +
+

Besides the simple managed custom action sample, there are three functional + and useful sample tools included in this distribution:

+

MSI Inventory
+ Shows a hierarchical, relational, searchable view of all of the product, + feature, component, file, and patch data managed by MSI, for all products + installed on the system.

+

WiFile
+ Extracts and updates cabbed files in an MSI setup.

+

CabPack
+ Creates simple self-extracting cab packages. OK, so this one isn't + especially useful as a tool, but the code should be helpful.

+

DDiff
+ Recursively diffs MSI, MSP, CAB, and other files and directories. + Much more thorough than widiffdb.vbs.

+


+
+ + +
+ + + diff --git a/src/samples/Dtf/Documents/Guide/Content/support.htm b/src/samples/Dtf/Documents/Guide/Content/support.htm new file mode 100644 index 00000000..89acbadf --- /dev/null +++ b/src/samples/Dtf/Documents/Guide/Content/support.htm @@ -0,0 +1,52 @@ + + + Support/Bugs + + + + + + +
+ Deployment Tools Foundation
+ Support/Bugs
+
+ + Overview > + Support/Bugs + +
+
+
+ +
+

Please send general support questions or comments to the + wix-users discussion list.

+ +

Bugs, suggestions, or feature requests can be submitted at the + WiX project + on Sourceforge.net.

+ +


+
+ + +
+ + + diff --git a/src/samples/Dtf/Documents/Guide/Content/using.htm b/src/samples/Dtf/Documents/Guide/Content/using.htm new file mode 100644 index 00000000..6fe960e8 --- /dev/null +++ b/src/samples/Dtf/Documents/Guide/Content/using.htm @@ -0,0 +1,50 @@ + + + Deployment Tools Foundation Development Guide + + + + + + +
+ Deployment Tools Foundation
+ Deployment Tools Foundation Development Guide
+
+ + Development Guide + +
+
+
+ + + + +
+ + + diff --git a/src/samples/Dtf/Documents/Guide/Content/whatsnew.htm b/src/samples/Dtf/Documents/Guide/Content/whatsnew.htm new file mode 100644 index 00000000..3efe67bd --- /dev/null +++ b/src/samples/Dtf/Documents/Guide/Content/whatsnew.htm @@ -0,0 +1,257 @@ + + + What's New? + + + + + + +
+ Deployment Tools Foundation
+ What's New?
+
+ + Overview > + What's New? + + 2007-07-03 +
+
+
+ +
+ +

Highlights

+
    +
  • New project name name "Deployment Tools Foundation", and + new namespaces WixToolset.Dtf.*

  • +
  • Added ZIP compression library

  • +
  • Added library for reading/writing Win32 resources including file versions

  • +
  • Managed custom action improvements:

      +
    • Simplified authoring and building -- new MakeSfxCA tool + automatically maps DLL entrypoints to CA methods.

    • +
    • Managed custom action DLLs now run in a separate process for + better reliability with respect to CLR versions, but still have + full access to the MSI session.

    • +
  • +
  • Found and fixed many bugs with extensive unit test suite

  • +
  • LINQ to MSI ! (preview)

  • +
+ +

Unfortunately, all these changes do mean that migrating tools and applications from + the previous release can be a moderate amount of work.

+ +

Breaking Changes

+

For the first time since v1.0, this release contains some major breaking + changes, due to a significant redesign and cleanup effort that has been a + long time coming. The overall purpose of the changes is to bring the class + libraries much closer to ship-quality.

+
    +
  • All libraries use a new namespace hierarchy + under WixToolset.Dtf. + The new namespace aligns with the new project name, gives all the various + libraries an identity that makes them obviously related to the DTF project, + and mostly avoids "taking over" a namespace that might be rightfully owned + by the platform technology owner.

  • + +
  • Assemblies are also renamed to follow namespaces.

  • + +
  • A new unified compression framework forms the basis for the new ZIP + library and a redesigned CAB library. Additional archive formats can + be plugged into the framework. The stream-based compression APIs have + been redesigned to be more object-oriented and easier to use. The file-based + APIs are mostly unchanged from the old cabinet library, although some names + have changed in order to fit into the new unified framework.

  • + +
  • Large parts of the WindowsInstaller library have been redesigned + to be more object-oriented and to better follow .NET Framework design + guidelines. And various APIs throughout the library have naming or other + changes for better consistency and to follow conventions and best + pratices as enforced by FxCop.

  • + +
  • The WindowsInstaller APIs no longer make any attempt to mimic the + MSI COM automation interfaces. The naming and object patterns in the + automation interfaces often conflicted with with best practices for + .NET Framework class libraries. Since most people start using DTF + without having ever experienced MSI scripting, there is little + reason to match the scripting object model. Making the APIs more + consistent with .NET conventions will make them much easier to use + for people already experienced with the .NET Framework.

  • + +
  • APIs in all class libraries use generics where appropriate, especially + the generic collection interfaces. This means .NET Framework 2.0 or later + is required.

  • + +
  • The FilePatch library is missing from this release. An updated + and redesigned file-delta library is in development.

  • +
+ +

Other Changes

+
    +
  • New MakeSfxCA tool for building managed custom action packages: In addition to + packaging the CA DLL and dependencies, it automatically detects managed CA methods + and generates corresponding unmanaged DLL entrypoints in the CA host DLL (SfxCA.dll), + where they are called by MSI. Previously it was necessary to either provide this + mapping in a CustomAction.config file, or live with the generic "ManagedCustomActionN" + names when authoring the CustomAction table in the MSI. For more info, see the + help topic on building managed custom actions.

  • + +
  • Out-of-proc managed custom action DLLs: + When a managed custom action runs, it normally requests a specific major + version of the CLR via CustomAction.config. However in the previous implementation, + the request could be ignored if there was already a different version of the CLR + loaded into the MSI process, either from a previous custom action or by some other + means. (The CLR doesn't allow side-by-side versions within the same process.) + While there have been no reports of this issue causing setup failures in practice, + it may be only a matter of time, as new CLR versions keep coming out.

    + +

    The redesigned native host for managed custom actions, SfxCA.dll, re-launches + itself in a separate process before loading the CLR and invoking the managed CA. + This ensures that the desired CLR version is always loaded, assuming it is available + on the system. It also sets up a named-pipe remoting channel between the two processes. + All session-related MSI API calls are routed through that channel, so that the + custom action has full access to the installer session just as if it were + running in-process.

  • + +
  • The new zip compression library supports nearly all features of the zip + file format. This includes the ZIP64 extensions for archives greater than 4GB, + as well as disk-spanning capabilities. Zip encryption is not supported. The zip + library has been tested against a variety of third-party zip tools; please + report any issues with incompatible packages.

    + +

    Currently only the basic DEFLATE compression algorithm is supported + (via System.IO.Compression.DeflateStream), and the compression level is not adjustable + when packing an archive. The zip file format has a mechanism for plugging in arbitrary + compression algorithms, and that capability is exposed: you can provide a Stream object + capable of compressing and decompressing bytes as an alternative to DeflateStream.

  • + +
  • Added support for the few APIs new in MSI 4.0:

    +
      +
    • Installer.GetPatchFileList()
    • +
    • InstallLogModes.RMFilesInUse
    • +
    • ComponentAttributes.DisableRegistryReflection
    • +
    • ControlAttributes.ElevationShield
    • +
     
  • + +
  • The documentation is now built with the + Sandcastle doc build engine, + with help from the Sandcastle + Help File Builder. (The old CHM was built with NDoc.)

  • + +
  • The documentation includes detailed class diagrams for the + WindowsInstaller and Compression namespaces.

  • + +
  • WindowsInstaller API doc topics now link straight to the corresponding + unmanaged MSI API topics in MSDN. If you know an unmanaged MSI API you want to + use but don't know the managed equivalent, you can search for it and find what + managed APIs link to it.

  • + +
  • Unit tests cover about 90% of the Compression, Compression.Zip, and + Compression.Cab assemblies -- basically everything except some rare + error-handling cases.

  • + +
  • Unit tests along with samples cover over 50% of the WindowsInstaller and + WindowsInstaller.Package assemblies (including custom action functionality). More + test cases are still being added.

  • +
+ +

Bugfixes

+

In addition to the extensive cleanup due to redesigns and unit tests, the following + reported bugs have been fixed:

+
    +
  • Managed custom actions could in rare instances fail to load with error 183 + (directory already exists)

  • +
  • Timestamps of files in a cabinet could be incorrectly offset based on the timezone. + (This was due to a behavior change in the DateTime class between .NET 1.1 and 2.0.)

  • +
  • Unicode file paths for cabbed files could be handled incorrectly in some cases

  • +
  • Installer.DetermineApplicablePatches just didn't work

  • +
  • InstallPackage.ApplyPatch couldn't handle applying multiple patches to the same layout

  • +
+ +

LINQ to MSI

+

You'll never want to write MSI SQL again!

+

Language INtegrated Query is a new feature in .NET Framework 3.5 and C# 3.0. Through + a combination of intuitive language syntax and powerful query operations, LINQ provides + a whole new level of productivity for working with data in your code. While the .NET + Framework 3.5 provides LINQ capability for SQL databases and XML data, now you + can write LINQ queries to fetch and even update data in MSI databases!

+ +

Look at the following example:
+ +

    var actions = from a in db.InstallExecuteSequences
+                  join ca in db.CustomActions on a.Action equals ca.Action
+                  where ca.Type == CustomActionTypes.Dll
+                  orderby a.Sequence
+                  select new {
+                      Name = a.Action,
+                      Target = ca.Target,
+                      Sequence = a.Sequence };
+          
+    foreach (var a in actions)
+    {
+        Console.WriteLine(a);
+    }
+    
+ + The query above gets automatically translated to MSI SQL:

+ +

    SELECT `InstallExecuteSequence`.`Action`, + `CustomAction`.`Target`, `InstallExecuteSequence`.`Sequence` FROM `InstallExecuteSequence`, `CustomAction` + WHERE `InstallExecuteSequence`.Action` = `CustomAction`.`Action` ORDER BY `InstallExecuteSequence`.`Sequence`

+ +

But the query is not executed until the foreach + enumeration. Then records are fetched from the results incrementally as the enumeration progresses. + The objects fetched are actually of an anonymous type created there in the query with exactly + the desired fields. So the result of this code will be to print the Action, Target, and Sequence + of all Type 1 custom actions.

+ +

The query functionality is currently limited by the capabilities of the MSI SQL engine. For + example, a query can't use where (ca.Type & + CustomActionTypes.Dll) != 0 because the bitwise-and operator is not supported by + MSI SQL. The preview version of LINQ to MSI will throw an exception for cases like that, but + the eventual goal is to have it automatically move the data and operation outside of MSI when + necessary, so that any arbitrary expressions are supported in the query.

+ +

Note there are no MSI handles (or IDisposables) + to worry about! Handles are all managed internally and closed deterministically. Also, + with the entity object model for common tables, the compiler will tell you if you get a + column name wrong or misspelled. The entity objects even support easy inserting, updating, + and deleting (not shown here).

+ +

For more examples, see the LinqTest project in the source. More documentation + is being written.

+ +

Obviously, LINQ to MSI requires .NET Framework 3.5. Everything else + in DTF requires only .NET Framework 2.0.

+ +

Note: The LINQ functionality in this DTF release is of preview quality only + and should not be used in production. While there are unit tests covering a wide + variety of queries, using advanced queries outside what is covered by the tests + is likely to result in unexpected exceptions, and retrieved data might possibly be + incorrect or incomplete. An updated LINQ to MSI library is in development.

+ +

 

+ +
+ + +
+ + + diff --git a/src/samples/Dtf/Documents/Guide/Content/wifile.htm b/src/samples/Dtf/Documents/Guide/Content/wifile.htm new file mode 100644 index 00000000..20998b73 --- /dev/null +++ b/src/samples/Dtf/Documents/Guide/Content/wifile.htm @@ -0,0 +1,73 @@ + + + Windows Installer Package File Manipulation Tool + + + + + + +
+ Deployment Tools Foundation
+ Windows Installer Package File Manipulation Tool
+
+ + Development Guide > + Samples > + WiFile + +
+
+
+ +
+

Usage: WiFile.exe package.msi /l [filename,filename2,...]
+Usage: WiFile.exe package.msi /x [filename,filename2,...]
+Usage: WiFile.exe package.msi /u [filename,filename2,...]
+
+Lists (/l), extracts (/x) or updates (/u) files in an MSI or MSM.
+Files are extracted using their source path relative to the package.
+Specified filenames do not include paths.
+Filenames may be a pattern such as *.exe or file?.dll
+

+


+ +

Example

+

The most powerful use of WiFile.exe is to do a round-trip update of files in a + compressed MSI/MSM package. It works like this:

    +
  1. Extract specific file(s) or all files from the package: + WiFile.exe package.msi /x *
  2. +
  3. The files are now expanded into their directory structure. You can edit/update + the files however you like.
  4. +
  5. Update the package with the changed files: WiFile.exe package.msi /u *  + This also updates the file metadata in the MSI including the file version, size, and hash.
  6. +

+


+ +

Notes

+
    +
  • Also works with packages that have multiple and/or external cab(s).

  • +
+ +


+
+ +
+ + + diff --git a/src/samples/Dtf/Documents/Guide/Content/writingcas.htm b/src/samples/Dtf/Documents/Guide/Content/writingcas.htm new file mode 100644 index 00000000..6beccf5f --- /dev/null +++ b/src/samples/Dtf/Documents/Guide/Content/writingcas.htm @@ -0,0 +1,114 @@ + + + Writing Managed Custom Actions + + + + + + +
+ Deployment Tools Foundation
+ Writing Managed Custom Actions
+
+ + Development Guide > + Managed CAs > + Writing CAs + +
+
+
+ +
+

Caveats

+

Before choosing to write a custom action in managed code instead of + traditional native C++ code, you should carefully consider the following:

+
    +
  • Obviously, it introduces a dependency on the .NET Framework. Your + MSI package should probably have a LaunchCondition to check for the presence + of the correct version of the .NET Framework before anything else happens.

  • +
  • If the custom action runs at uninstall time, then even the uninstall of + your product may fail if the .NET Framework is not present. This means a + user could run into a problem if they uninstall the .NET Framework before + your product.

  • +
  • A managed custom action should be configured to run against a specific + version of the .NET Framework, and that version should match the version your + actual product runs against. Allowing the version to "float" to the latest + installed .NET Framework is likely to lead to compatibility problems with + future versions. The .NET Framework provides side-by-side functionality for + good reason -- use it.

  • + +
+


+

How To

+
    +
  • A custom action function needs to be declared as + public static (aka Public Shared in VB.NET). It takes one parameter which is + a Session object, and returns a + ActionResult enumeration.

    +
        [CustomAction]
    +    public static ActionResult MyCustomAction(Session session)

    +
  • The function must have a + CustomActionAttribute, which enables it to be + linked to a proxy function. The attribute can take an optional + "name" parameter, which is the name of the entrypoint + that is exported from the custom action DLL.

    +
  • Fill in MSI CustomAction table entries just like you + would for a normal type 1 native-DLL CA. Managed CAs can also work just + as well in deferred, rollback, and commit modes.

    +
  • If the custom action function throws any kind of + Exception that isn't handled internally, then it will be caught by the proxy + function. The Exception message and stack trace will be printed to the + MSI log if logging is enabled, and the CA will return a failure code.

    +
  • To be technically correct, any MSI handles obtained should be + closed before a custom action function exits -- otherwise a warning + gets printed to the log. The handle classes in the managed library + (Database, + View, + Record, + SummaryInfo) + all implement the IDisposable interface, + which makes them easily managed with C#'s using + statement. Alternatively, they can be closed in a finally block. + As a general rule, methods return new handle objects that should be + managed and closed by the user code, while properties only return a reference + to a prexisting handle object.

  • +
  • Don't forget to use a CustomAction.config file to + specify what version of the .NET Framework the custom action should run against.

  • +
+ +


+

See also:

+ +


+ +
+ + +
+ + + diff --git a/src/samples/Dtf/Documents/Guide/DTF.hhc b/src/samples/Dtf/Documents/Guide/DTF.hhc new file mode 100644 index 00000000..bf43e447 --- /dev/null +++ b/src/samples/Dtf/Documents/Guide/DTF.hhc @@ -0,0 +1,132 @@ + + + + + + + + diff --git a/src/samples/Dtf/Documents/Guide/DTF.hhk b/src/samples/Dtf/Documents/Guide/DTF.hhk new file mode 100644 index 00000000..bc6e49b3 --- /dev/null +++ b/src/samples/Dtf/Documents/Guide/DTF.hhk @@ -0,0 +1,126 @@ + + + + + + + diff --git a/src/samples/Dtf/Documents/Guide/DTF.hhp b/src/samples/Dtf/Documents/Guide/DTF.hhp new file mode 100644 index 00000000..e9b8ad90 --- /dev/null +++ b/src/samples/Dtf/Documents/Guide/DTF.hhp @@ -0,0 +1,49 @@ +[OPTIONS] +Auto Index=Yes +Compatibility=1.1 or later +Compiled file=DTF.chm +Contents file=DTF.hhc +Default Window=DTF +Default topic=Content\about.htm +Display compile progress=Yes +Error log file=DTFhelp.log +Full-text search=Yes +Index file=DTF.hhk +Language=0x409 English (United States) +Title=Deployment Tools Foundation + +[WINDOWS] +DTF="Deployment Tools Foundation","DTF.hhc","DTF.hhk","Content\about.htm","Content\about.htm",,,,,0x22520,,0x384e,[143,72,937,601],,,,,,,0 + + +[FILES] +styles\presentation.css +Content\about.htm +Content\whatsnew.htm +Content\dependencies.htm +Content\using.htm +DTF.hhc +DTF.hhk +Content\samples.htm +Content\support.htm +Content\history.htm +Content\inventory.htm +Content\wifile.htm +Content\cabpack.htm +Content\powerdiff.htm +Content\cabs.htm +Content\databases.htm +Content\packages.htm +Content\managedcas.htm +Content\samplecas.htm +Content\writingcas.htm +Content\buildingcas.htm +Content\debuggingcas.htm +Content\caproxy.htm +Content\caconfig.htm +Content\installutil.htm + +[MERGE FILES] +DTFAPI.chm + +[INFOTYPES] diff --git a/src/samples/Dtf/Documents/Guide/dtfguide.helpproj b/src/samples/Dtf/Documents/Guide/dtfguide.helpproj new file mode 100644 index 00000000..4df2765d --- /dev/null +++ b/src/samples/Dtf/Documents/Guide/dtfguide.helpproj @@ -0,0 +1,29 @@ + + + + + + + {3CFD8620-B41C-470C-ABEF-9D38076A2A8D} + dtf + + + + + + + + + + $(OutputPath)DTFAPI.chm + + + + + + false + + + + + diff --git a/src/samples/Dtf/Documents/Guide/styles/presentation.css b/src/samples/Dtf/Documents/Guide/styles/presentation.css new file mode 100644 index 00000000..b71c8582 --- /dev/null +++ b/src/samples/Dtf/Documents/Guide/styles/presentation.css @@ -0,0 +1,394 @@ + +/* page style */ + +body { + margin: 0; + background-color: #FFFFFF; + padding: 0; + font-size: 80%; + font-family: verdana, sans-serif; + color: #000000; +} + +table { + /* this is a trick to force tables to inherit the body font size */ + font-size: 100%; +} + +/* non-scrolling (control) region style */ + +div#control { + margin: 0; + background-color: #D4DFFF; + padding: 4px; + width: 100%; + border-bottom-color: #C8CDDE; + border-bottom-style: solid; + border-bottom-width: 1; +} + +span.productTitle { + font-size: 80%; +} + +span.topicTitle { + font-size: 140%; + font-weight: bold; + color: #003399; +} + +span#chickenFeet { + float: left; +} + +span#languageFilter { + float: right; +} + +/* scrolling (content) region style */ + +div#main { + margin: 0; + padding: 1em; + width: 100%; + clear: both; +} + +/* sections */ + +div#header { + font-size: 70%; + color: #666666; + margin-bottom: 0.5em; +} + +div.section { + margin-bottom: 1em; +} + +div.sectionTitle { + display: inline; + font-size: 120%; + font-weight: bold; + color: #003399; +} + +div.sectionContent { + margin-top: 0.2em; +} + +span.subsectionTitle { + font-weight: bold; +} + +div#footer { + margin-top: 1em; + border-top: thin solid #003399; + padding-top: 0.5em; +} + +/* authored content (block) */ + +p { + margin-top: 0; + margin-bottom: 1em; +} + +dl { + margin-top: 0; + margin-bottom: 1em; +} + +div.code { + clear: both; + width: 100%; + background: #F7F7FF; + padding: 0.4em; + font-family: "Andale Mono"; + /* font-family: "Courier New"; */ + /* font-family: "This is not a monospace font", monospace; */ + font-size: inherit; + margin-bottom: 1em; +} + +pre { + margin: 0; + padding: 0; +} + +table.authoredTable { + table-layout: fixed; + width: 100%; + margin-bottom: 1em; +} + +table.authoredTable th { + border-bottom-color: #C8CDDE; + border-bottom-style: solid; + border-bottom-width: 1; + background: #EFEFF7; + padding: 0.2em; + text-align: left; + color: #000066; + font-weight: bold; +} + +table.authoredTable td { + border-bottom-style: solid; + border-bottom-color: #C8CDDE; + border-bottom-width: 1px; + background: #F7F7FF; + padding: 0.2em; + vertical-align: top; +} + +div.alert { + border: 1px solid #C8CDDE; + background: #F7F7FF; +} + +div.media { + text-align: center; + margin-bottom: 1em; +} + + +/* authored content (inline) */ + +span.keyword { + font-weight: bold; +} + +span.code { + font-family: "Andale Mono", "Courier New", Courier, monospace; +} + +/* auto-generated controls */ + +div.langTabs { + width: 100%; +} + +div.langTab { + float: left; + width: 16%; + border-top: 1px solid #C8CDDE; + border-left: 1px solid #C8CDDE; + border-right: 1px solid #C8CDDE; + background: #F7F7FF; + padding: 0.2em; + text-align: left; + color: #000066; + font-weight: normal; +} + +div.activeLangTab { + float: left; + width: 16%; + border-top: 1px solid #C8CDDE; + border-left: 1px solid #C8CDDE; + border-right: 1px solid #C8CDDE; + background: #EFEFF7; + padding: 0.2em; + text-align: left; + color: #000066; + font-weight: bold; +} + +table.members { + table-layout: fixed; + width: 100%; +} + +table.members th.iconColumn { + width: 60px; +} + +table.members th.nameColumn { + width: 33%; +} + +table.members th.descriptionColumn { + width: 66%; +} + +table.members th { + border-bottom-color: #C8CDDE; + border-bottom-style: solid; + border-bottom-width: 1; + background: #EFEFF7; + padding: 0.2em; + text-align: left; + color: #000066; + font-weight: bold; +} + +table.members td { + border-bottom-style: solid; + border-bottom-color: #C8CDDE; + border-bottom-width: 1px; + background: #F7F7FF; + padding: 0.2em; + vertical-align: top; + overflow: hidden; +} + +table.exceptions { + table-layout: fixed; + width: 100%; +} + + +table.exceptions th.exceptionNameColumn { + width: 33%; +} + +table.exceptions th.exceptionConditionColumn { + width: 66%; +} + +table.exceptions th { + border-bottom-color: #C8CDDE; + border-bottom-style: solid; + border-bottom-width: 1; + background: #EFEFF7; + padding: 0.2em; + text-align: left; + color: #000066; + font-weight: bold; +} + +table.exceptions td { + border-bottom-style: solid; + border-bottom-color: #C8CDDE; + border-bottom-width: 1px; + background: #F7F7FF; + padding: 0.2em; + vertical-align: top; +} + +table.permissions { + table-layout: fixed; + width: 100%; +} + + +table.permissions th.permissionNameColumn { + width: 33%; +} + +table.permissions th.permissionConditionColumn { + width: 66%; +} + +table.permissions th { + border-bottom-color: #C8CDDE; + border-bottom-style: solid; + border-bottom-width: 1; + background: #EFEFF7; + padding: 0.2em; + text-align: left; + color: #000066; + font-weight: bold; +} + +table.permissions td { + border-bottom-style: solid; + border-bottom-color: #C8CDDE; + border-bottom-width: 1px; + background: #F7F7FF; + padding: 0.2em; + vertical-align: top; +} + +span.obsolete { + color: red; +} + +span.cs { + display: inline; +} + +span.vb { + display: none; +} + +span.cpp { + display: none; +} +/* syntax styling */ + +div.code span.identifier { + font-size: 120%; + font-weight: bold; +} + +div.code span.keyword { + color: green; +} + +div.code span.parameter { + font-style: italic; + color: purple; +} + +div.code span.literal { + color: purple; +} + +div.code span.comment { + color: red; +} + +span.foreignPhrase { + font-style: italic; +} + +span.placeholder { + font-style: italic; +} + +a { + color: blue; + font-weight: bold; + text-decoration: none; +} + +MSHelp\:link { + color: blue; + font-weight: bold; + hoverColor: #3366ff; +} + +span.nolink { + font-weight: bold; +} + +table.filter { + table-layout: fixed; +} + +tr.tabs td.tab { + width: 10em; + background: #F7F7FF; + padding: 0.2em; + text-align: left; + color: #000066; + font-weight: normal; + overflow: hidden; + cursor: pointer; +} + +tr.tabs td.activeTab { + width: 10em; + background: #EFEFF7; + padding: 0.2em; + text-align: left; + color: #000066; + font-weight: bold; + overflow: hidden; +} + +td.line { + background: #EFEFF7; +} -- cgit v1.2.3-55-g6feb