summaryrefslogtreecommitdiff
path: root/src/tools/Dtf/WiFile
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2022-07-14 15:19:53 -0700
committerRob Mensching <rob@firegiant.com>2022-07-14 16:02:24 -0700
commit229242cf7c328b89b5aa65ed7a04e33c8b93b393 (patch)
treede0a9547e73e46490b0946d6850228d5b30258b8 /src/tools/Dtf/WiFile
parentf46ca6a9dce91607ffc9855270dd6998216e1a8b (diff)
downloadwix-229242cf7c328b89b5aa65ed7a04e33c8b93b393.tar.gz
wix-229242cf7c328b89b5aa65ed7a04e33c8b93b393.tar.bz2
wix-229242cf7c328b89b5aa65ed7a04e33c8b93b393.zip
Rename "samples" segment to "tools"
This segment is a bit of a "miscellaneous section" in the WiX repo. As such it has been difficult to name. I originally eschewed the name "tools" because what is in the "wix" segment was once called "tools". However, now that wix.exe is firmly established as the entry point for WiX operations, I've become comfortable with its segment being named "wix". That meant "tools" was again available and "tools" better describes the content of this section.
Diffstat (limited to 'src/tools/Dtf/WiFile')
-rw-r--r--src/tools/Dtf/WiFile/WiFile.cs147
-rw-r--r--src/tools/Dtf/WiFile/WiFile.csproj27
2 files changed, 174 insertions, 0 deletions
diff --git a/src/tools/Dtf/WiFile/WiFile.cs b/src/tools/Dtf/WiFile/WiFile.cs
new file mode 100644
index 00000000..1e5c80df
--- /dev/null
+++ b/src/tools/Dtf/WiFile/WiFile.cs
@@ -0,0 +1,147 @@
1// 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.
2
3using System;
4using System.IO;
5using System.Reflection;
6using System.Collections;
7using System.Collections.Generic;
8using System.Diagnostics.CodeAnalysis;
9using System.Globalization;
10using System.Text.RegularExpressions;
11using WixToolset.Dtf.WindowsInstaller;
12using WixToolset.Dtf.WindowsInstaller.Package;
13
14[assembly: AssemblyDescription("Windows Installer package file extraction and update tool")]
15
16
17/// <summary>
18/// Shows sample use of the InstallPackage class.
19/// </summary>
20public class WiFile
21{
22 public static void Usage(TextWriter w)
23 {
24 w.WriteLine("Usage: WiFile.exe package.msi /l [filename,filename2,...]");
25 w.WriteLine("Usage: WiFile.exe package.msi /x [filename,filename2,...]");
26 w.WriteLine("Usage: WiFile.exe package.msi /u [filename,filename2,...]");
27 w.WriteLine();
28 w.WriteLine("Lists (/l), extracts (/x) or updates (/u) files in an MSI or MSM.");
29 w.WriteLine("Files are extracted using their source path relative to the package.");
30 w.WriteLine("Specified filenames do not include paths.");
31 w.WriteLine("Filenames may be a pattern such as *.exe or file?.dll");
32 }
33
34 [SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase")]
35 public static int Main(string[] args)
36 {
37 if(!(args.Length == 2 || args.Length == 3))
38 {
39 Usage(Console.Out);
40 return -1;
41 }
42
43 string msiFile = args[0];
44
45 string option = args[1].ToLowerInvariant();
46 if(option.StartsWith("-", StringComparison.Ordinal)) option = "/" + option.Substring(1);
47
48 string[] fileNames = null;
49 if(args.Length == 3)
50 {
51 fileNames = args[2].Split(',');
52 }
53
54 try
55 {
56 switch(option)
57 {
58 case "/l":
59 using(InstallPackage pkg = new InstallPackage(msiFile, DatabaseOpenMode.ReadOnly))
60 {
61 pkg.Message += new InstallPackageMessageHandler(Console.WriteLine);
62 IEnumerable<string> fileKeys = (fileNames != null ? FindFileKeys(pkg, fileNames) : pkg.Files.Keys);
63
64 foreach(string fileKey in fileKeys)
65 {
66 Console.WriteLine(pkg.Files[fileKey]);
67 }
68 }
69 break;
70
71 case "/x":
72 using(InstallPackage pkg = new InstallPackage(msiFile, DatabaseOpenMode.ReadOnly))
73 {
74 pkg.Message += new InstallPackageMessageHandler(Console.WriteLine);
75 ICollection<string> fileKeys = FindFileKeys(pkg, fileNames);
76
77 pkg.ExtractFiles(fileKeys);
78 }
79 break;
80
81 case "/u":
82 using(InstallPackage pkg = new InstallPackage(msiFile, DatabaseOpenMode.Transact))
83 {
84 pkg.Message += new InstallPackageMessageHandler(Console.WriteLine);
85 ICollection<string> fileKeys = FindFileKeys(pkg, fileNames);
86
87 pkg.UpdateFiles(fileKeys);
88 pkg.Commit();
89 }
90 break;
91
92 default:
93 Usage(Console.Out);
94 return -1;
95 }
96 }
97 catch(InstallerException iex)
98 {
99 Console.WriteLine("Error: " + iex.Message);
100 return iex.ErrorCode != 0 ? iex.ErrorCode : 1;
101 }
102 catch(FileNotFoundException fnfex)
103 {
104 Console.WriteLine(fnfex.Message);
105 return 2;
106 }
107 catch(Exception ex)
108 {
109 Console.WriteLine("Error: " + ex.Message);
110 return 1;
111 }
112 return 0;
113 }
114
115 static ICollection<string> FindFileKeys(InstallPackage pkg, ICollection<string> fileNames)
116 {
117 List<string> fileKeys = null;
118 if(fileNames != null)
119 {
120 fileKeys = new List<string>();
121 foreach(string fileName in fileNames)
122 {
123 string[] foundFileKeys = null;
124 if(fileName.IndexOfAny(new char[] { '*', '?' }) >= 0)
125 {
126 foundFileKeys = pkg.FindFiles(FilePatternToRegex(fileName));
127 }
128 else
129 {
130 foundFileKeys = pkg.FindFiles(fileName);
131 }
132 fileKeys.AddRange(foundFileKeys);
133 }
134 if(fileKeys.Count == 0)
135 {
136 throw new FileNotFoundException("Files not found in package.");
137 }
138 }
139 return fileKeys;
140 }
141
142 static Regex FilePatternToRegex(string pattern)
143 {
144 return new Regex("^" + Regex.Escape(pattern).Replace("\\*", ".*").Replace("\\?", ".") + "$",
145 RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
146 }
147}
diff --git a/src/tools/Dtf/WiFile/WiFile.csproj b/src/tools/Dtf/WiFile/WiFile.csproj
new file mode 100644
index 00000000..c8d39235
--- /dev/null
+++ b/src/tools/Dtf/WiFile/WiFile.csproj
@@ -0,0 +1,27 @@
1
2<!-- 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. -->
3
4
5<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
6 <PropertyGroup>
7 <ProjectGuid>{AE562F7F-EE33-41D6-A962-DA488FEFBD08}</ProjectGuid>
8 <OutputType>Exe</OutputType>
9 <RootNamespace>WixToolset.Dtf.Tools.WiFile</RootNamespace>
10 <AssemblyName>WiFile</AssemblyName>
11 <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
12 </PropertyGroup>
13
14 <ItemGroup>
15 <Compile Include="WiFile.cs" />
16 </ItemGroup>
17
18 <ItemGroup>
19 <Reference Include="System" />
20 <Reference Include="System.Data" />
21 <Reference Include="System.Xml" />
22 <ProjectReference Include="..\..\Libraries\WindowsInstaller.Package\WindowsInstaller.Package.csproj" />
23 <ProjectReference Include="..\..\Libraries\WindowsInstaller\WindowsInstaller.csproj" />
24 </ItemGroup>
25
26 <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), wix.proj))\tools\WixBuild.targets" />
27</Project>