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/WiFile/WiFile.cs | 147 +++++++++++++++++++++++++++++++++++ src/samples/Dtf/WiFile/WiFile.csproj | 27 +++++++ 2 files changed, 174 insertions(+) create mode 100644 src/samples/Dtf/WiFile/WiFile.cs create mode 100644 src/samples/Dtf/WiFile/WiFile.csproj (limited to 'src/samples/Dtf/WiFile') diff --git a/src/samples/Dtf/WiFile/WiFile.cs b/src/samples/Dtf/WiFile/WiFile.cs new file mode 100644 index 00000000..1e5c80df --- /dev/null +++ b/src/samples/Dtf/WiFile/WiFile.cs @@ -0,0 +1,147 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +using System; +using System.IO; +using System.Reflection; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Text.RegularExpressions; +using WixToolset.Dtf.WindowsInstaller; +using WixToolset.Dtf.WindowsInstaller.Package; + +[assembly: AssemblyDescription("Windows Installer package file extraction and update tool")] + + +/// +/// Shows sample use of the InstallPackage class. +/// +public class WiFile +{ + public static void Usage(TextWriter w) + { + w.WriteLine("Usage: WiFile.exe package.msi /l [filename,filename2,...]"); + w.WriteLine("Usage: WiFile.exe package.msi /x [filename,filename2,...]"); + w.WriteLine("Usage: WiFile.exe package.msi /u [filename,filename2,...]"); + w.WriteLine(); + w.WriteLine("Lists (/l), extracts (/x) or updates (/u) files in an MSI or MSM."); + w.WriteLine("Files are extracted using their source path relative to the package."); + w.WriteLine("Specified filenames do not include paths."); + w.WriteLine("Filenames may be a pattern such as *.exe or file?.dll"); + } + + [SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase")] + public static int Main(string[] args) + { + if(!(args.Length == 2 || args.Length == 3)) + { + Usage(Console.Out); + return -1; + } + + string msiFile = args[0]; + + string option = args[1].ToLowerInvariant(); + if(option.StartsWith("-", StringComparison.Ordinal)) option = "/" + option.Substring(1); + + string[] fileNames = null; + if(args.Length == 3) + { + fileNames = args[2].Split(','); + } + + try + { + switch(option) + { + case "/l": + using(InstallPackage pkg = new InstallPackage(msiFile, DatabaseOpenMode.ReadOnly)) + { + pkg.Message += new InstallPackageMessageHandler(Console.WriteLine); + IEnumerable fileKeys = (fileNames != null ? FindFileKeys(pkg, fileNames) : pkg.Files.Keys); + + foreach(string fileKey in fileKeys) + { + Console.WriteLine(pkg.Files[fileKey]); + } + } + break; + + case "/x": + using(InstallPackage pkg = new InstallPackage(msiFile, DatabaseOpenMode.ReadOnly)) + { + pkg.Message += new InstallPackageMessageHandler(Console.WriteLine); + ICollection fileKeys = FindFileKeys(pkg, fileNames); + + pkg.ExtractFiles(fileKeys); + } + break; + + case "/u": + using(InstallPackage pkg = new InstallPackage(msiFile, DatabaseOpenMode.Transact)) + { + pkg.Message += new InstallPackageMessageHandler(Console.WriteLine); + ICollection fileKeys = FindFileKeys(pkg, fileNames); + + pkg.UpdateFiles(fileKeys); + pkg.Commit(); + } + break; + + default: + Usage(Console.Out); + return -1; + } + } + catch(InstallerException iex) + { + Console.WriteLine("Error: " + iex.Message); + return iex.ErrorCode != 0 ? iex.ErrorCode : 1; + } + catch(FileNotFoundException fnfex) + { + Console.WriteLine(fnfex.Message); + return 2; + } + catch(Exception ex) + { + Console.WriteLine("Error: " + ex.Message); + return 1; + } + return 0; + } + + static ICollection FindFileKeys(InstallPackage pkg, ICollection fileNames) + { + List fileKeys = null; + if(fileNames != null) + { + fileKeys = new List(); + foreach(string fileName in fileNames) + { + string[] foundFileKeys = null; + if(fileName.IndexOfAny(new char[] { '*', '?' }) >= 0) + { + foundFileKeys = pkg.FindFiles(FilePatternToRegex(fileName)); + } + else + { + foundFileKeys = pkg.FindFiles(fileName); + } + fileKeys.AddRange(foundFileKeys); + } + if(fileKeys.Count == 0) + { + throw new FileNotFoundException("Files not found in package."); + } + } + return fileKeys; + } + + static Regex FilePatternToRegex(string pattern) + { + return new Regex("^" + Regex.Escape(pattern).Replace("\\*", ".*").Replace("\\?", ".") + "$", + RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); + } +} diff --git a/src/samples/Dtf/WiFile/WiFile.csproj b/src/samples/Dtf/WiFile/WiFile.csproj new file mode 100644 index 00000000..b5a95481 --- /dev/null +++ b/src/samples/Dtf/WiFile/WiFile.csproj @@ -0,0 +1,27 @@ + + + + + + + {AE562F7F-EE33-41D6-A962-DA488FEFBD08} + Exe + WixToolset.Dtf.Samples.WiFile + WiFile + v2.0 + + + + + + + + + + + + + + + + -- cgit v1.2.3-55-g6feb