aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2021-03-19 07:47:43 -0700
committerRob Mensching <rob@firegiant.com>2021-03-19 07:49:43 -0700
commit062d6387692d074f502176296f361c52026b96d5 (patch)
tree2c20c118139b5f08a1702ec41b63f53c27ae0bf2
parente62434acc6c6e41bbafd3f1d46b2ed2011a9ad98 (diff)
downloadwix-062d6387692d074f502176296f361c52026b96d5.tar.gz
wix-062d6387692d074f502176296f361c52026b96d5.tar.bz2
wix-062d6387692d074f502176296f361c52026b96d5.zip
Improve finding files relative to Core.Native assembly
Should fix unit testing issues when .cub files cannot be found.
-rw-r--r--src/WixToolset.Core.Native/AssemblyExtensions.cs70
-rw-r--r--src/WixToolset.Core.Native/WindowsInstallerValidator.cs16
-rw-r--r--src/WixToolset.Core.Native/WixNativeExe.cs28
3 files changed, 84 insertions, 30 deletions
diff --git a/src/WixToolset.Core.Native/AssemblyExtensions.cs b/src/WixToolset.Core.Native/AssemblyExtensions.cs
new file mode 100644
index 00000000..590a6887
--- /dev/null
+++ b/src/WixToolset.Core.Native/AssemblyExtensions.cs
@@ -0,0 +1,70 @@
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
3namespace WixToolset.Core.Native
4{
5 using System;
6 using System.IO;
7 using System.Reflection;
8 using System.Text;
9
10 internal static class AssemblyExtensions
11 {
12 internal static FindAssemblyRelativeFileResult FindFileRelativeToAssembly(this Assembly assembly, string relativePath, bool searchNativeDllDirectories)
13 {
14 // First try using the Assembly.Location. This works in almost all cases with
15 // no side-effects.
16 var path = Path.Combine(Path.GetDirectoryName(assembly.Location), relativePath);
17 var possiblePaths = new StringBuilder(path);
18
19 var found = File.Exists(path);
20 if (!found)
21 {
22 // Fallback to the Assembly.CodeBase to handle "shadow copy" scenarios (like unit tests) but
23 // only check codebase if it is different from the Assembly.Location path.
24 var codebase = Path.Combine(Path.GetDirectoryName(new Uri(assembly.CodeBase).LocalPath), relativePath);
25
26 if (!codebase.Equals(path, StringComparison.OrdinalIgnoreCase))
27 {
28 path = codebase;
29 possiblePaths.Append(Path.PathSeparator + path);
30
31 found = File.Exists(path);
32 }
33
34 if (!found && searchNativeDllDirectories && AppContext.GetData("NATIVE_DLL_SEARCH_DIRECTORIES") is string searchDirectoriesString)
35 {
36 // If instructed to search native DLL search directories, try to find our file there.
37 possiblePaths.Append(Path.PathSeparator + searchDirectoriesString);
38
39 var searchDirectories = searchDirectoriesString?.Split(Path.PathSeparator);
40 foreach (var directoryPath in searchDirectories)
41 {
42 var possiblePath = Path.Combine(directoryPath, relativePath);
43 if (File.Exists(possiblePath))
44 {
45 path = possiblePath;
46 found = true;
47 break;
48 }
49 }
50 }
51 }
52
53 return new FindAssemblyRelativeFileResult
54 {
55 Found = found,
56 Path = found ? path : null,
57 PossiblePaths = possiblePaths.ToString()
58 };
59 }
60
61 internal class FindAssemblyRelativeFileResult
62 {
63 public bool Found { get; set; }
64
65 public string Path { get; set; }
66
67 public string PossiblePaths { get; set; }
68 }
69 }
70}
diff --git a/src/WixToolset.Core.Native/WindowsInstallerValidator.cs b/src/WixToolset.Core.Native/WindowsInstallerValidator.cs
index d013e5f9..9f4b26a3 100644
--- a/src/WixToolset.Core.Native/WindowsInstallerValidator.cs
+++ b/src/WixToolset.Core.Native/WindowsInstallerValidator.cs
@@ -86,9 +86,6 @@ namespace WixToolset.Core.Native
86 var previousHwnd = IntPtr.Zero; 86 var previousHwnd = IntPtr.Zero;
87 InstallUIHandler previousUIHandler = null; 87 InstallUIHandler previousUIHandler = null;
88 88
89 var baseCubePath = Path.Combine(Path.GetDirectoryName(typeof(WindowsInstallerValidator).Assembly.Location), CubesFolder);
90 var cubeFiles = this.CubeFiles.Select(s => Path.Combine(baseCubePath, s)).ToList();
91
92 try 89 try
93 { 90 {
94 using (var database = new Database(this.DatabasePath, OpenDatabase.Direct)) 91 using (var database = new Database(this.DatabasePath, OpenDatabase.Direct))
@@ -116,11 +113,18 @@ namespace WixToolset.Core.Native
116 } 113 }
117 114
118 // Merge in the cube databases. 115 // Merge in the cube databases.
119 foreach (var cubeFile in cubeFiles) 116 foreach (var cubeFile in this.CubeFiles)
120 { 117 {
118 var findCubeFile = typeof(WindowsInstallerValidator).Assembly.FindFileRelativeToAssembly(Path.Combine(CubesFolder, cubeFile), searchNativeDllDirectories: false);
119
120 if (!findCubeFile.Found)
121 {
122 throw new WixException(ErrorMessages.CubeFileNotFound(findCubeFile.Path));
123 }
124
121 try 125 try
122 { 126 {
123 using (var cubeDatabase = new Database(cubeFile, OpenDatabase.ReadOnly)) 127 using (var cubeDatabase = new Database(findCubeFile.Path, OpenDatabase.ReadOnly))
124 { 128 {
125 try 129 try
126 { 130 {
@@ -136,7 +140,7 @@ namespace WixToolset.Core.Native
136 { 140 {
137 if (0x6E == e.NativeErrorCode) // ERROR_OPEN_FAILED 141 if (0x6E == e.NativeErrorCode) // ERROR_OPEN_FAILED
138 { 142 {
139 throw new WixException(ErrorMessages.CubeFileNotFound(cubeFile)); 143 throw new WixException(ErrorMessages.CubeFileNotFound(findCubeFile.Path));
140 } 144 }
141 145
142 throw; 146 throw;
diff --git a/src/WixToolset.Core.Native/WixNativeExe.cs b/src/WixToolset.Core.Native/WixNativeExe.cs
index 9ae758ca..fb41b2f2 100644
--- a/src/WixToolset.Core.Native/WixNativeExe.cs
+++ b/src/WixToolset.Core.Native/WixNativeExe.cs
@@ -7,7 +7,6 @@ namespace WixToolset.Core.Native
7 using System.ComponentModel; 7 using System.ComponentModel;
8 using System.Diagnostics; 8 using System.Diagnostics;
9 using System.IO; 9 using System.IO;
10 using System.Reflection;
11 10
12 internal class WixNativeExe 11 internal class WixNativeExe
13 { 12 {
@@ -81,35 +80,16 @@ namespace WixToolset.Core.Native
81 { 80 {
82 if (String.IsNullOrEmpty(PathToWixNativeExe)) 81 if (String.IsNullOrEmpty(PathToWixNativeExe))
83 { 82 {
84 var path = Path.Combine(Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath), WixNativeExeFileName); 83 var result = typeof(WixNativeExe).Assembly.FindFileRelativeToAssembly(WixNativeExeFileName, searchNativeDllDirectories: true);
85 var possiblePaths = path;
86 84
87 var found = File.Exists(path); 85 if (!result.Found)
88 if (!found && AppContext.GetData("NATIVE_DLL_SEARCH_DIRECTORIES") is string searchDirectoriesString)
89 {
90 possiblePaths = searchDirectoriesString;
91 var separatorChar = Path.PathSeparator;
92 var searchDirectories = searchDirectoriesString?.Split(separatorChar);
93 foreach (var directoryPath in searchDirectories)
94 {
95 var possiblePath = Path.Combine(directoryPath, WixNativeExeFileName);
96 if (File.Exists(possiblePath))
97 {
98 path = possiblePath;
99 found = true;
100 break;
101 }
102 }
103 }
104
105 if (!found)
106 { 86 {
107 throw new PlatformNotSupportedException( 87 throw new PlatformNotSupportedException(
108 $"Could not find platform specific '{WixNativeExeFileName}'", 88 $"Could not find platform specific '{WixNativeExeFileName}'",
109 new FileNotFoundException($"Could not find internal piece of WiX Toolset from: {possiblePaths}", WixNativeExeFileName)); 89 new FileNotFoundException($"Could not find internal piece of WiX Toolset from: {result.PossiblePaths}", WixNativeExeFileName));
110 } 90 }
111 91
112 PathToWixNativeExe = path; 92 PathToWixNativeExe = result.Path;
113 } 93 }
114 } 94 }
115 95