@@ -18,7 +18,7 @@ public sealed class Database : MsiHandle
1818 /// </summary>
1919 /// <param name="path">Path to the database to be opened.</param>
2020 /// <param name="type">Persist mode to use when opening the database.</param>
21- public Database ( string path , OpenDatabase type )
21+ private Database ( string path , OpenDatabase type )
2222 {
2323 var error = MsiInterop . MsiOpenDatabase ( path , ( IntPtr ) type , out var handle ) ;
2424 if ( 0 != error )
@@ -34,15 +34,90 @@ public Database(string path, OpenDatabase type)
3434 /// </summary>
3535 public static int MsiMaxStreamNameLength => MsiInterop . MsiMaxStreamNameLength ;
3636
37+ /// <summary>
38+ /// Creates a new <see cref="Database"/> with the specified path.
39+ /// </summary>
40+ /// <param name="path">Path of database to be created.</param>
41+ /// <param name="asPatch">Indicates whether the database should be opened as a patch file.</param>
42+ public static Database Create ( string path , bool asPatch = false )
43+ {
44+ var fileCreated = false ;
45+ var mode = OpenDatabase . CreateDirect ;
46+
47+ if ( asPatch )
48+ {
49+ mode |= OpenDatabase . OpenPatchFile ;
50+ }
51+
52+ try
53+ {
54+ fileCreated = PathUtil . CreateOrGetShortPath ( path , out var shortPath ) ;
55+
56+ return new Database ( shortPath , mode ) ;
57+ }
58+ catch // cleanup on error if we created the short path file.
59+ {
60+ if ( fileCreated )
61+ {
62+ File . Delete ( path ) ;
63+ }
64+
65+ throw ;
66+ }
67+ }
68+
69+ /// <summary>
70+ /// Opens an existing <see cref="Database"/> with the specified path.
71+ /// </summary>
72+ /// <param name="path">Path of database to open.</param>
73+ /// <param name="transact">Indicates whether to open the database in transaction mode.</param>
74+ /// <param name="asPatch">Indicates whether the database should be opened as a patch file.</param>
75+ public static Database Open ( string path , bool transact = false , bool asPatch = false )
76+ {
77+ var mode = transact ? OpenDatabase . Transact : OpenDatabase . Direct ;
78+
79+ if ( asPatch )
80+ {
81+ mode |= OpenDatabase . OpenPatchFile ;
82+ }
83+
84+ // Use the short path to avoid issues with long paths in the MSI API.
85+ var shortPath = PathUtil . GetShortPath ( path ) ;
86+
87+ return new Database ( shortPath , mode ) ;
88+ }
89+
90+ /// <summary>
91+ /// Opens an existing <see cref="Database"/> with the specified path.
92+ /// </summary>
93+ /// <param name="path">Path of database to open.</param>
94+ /// <param name="asPatch">Indicates whether the database should be opened as a patch file.</param>
95+ public static Database OpenAsReadOnly ( string path , bool asPatch = false )
96+ {
97+ var mode = OpenDatabase . ReadOnly ;
98+
99+ if ( asPatch )
100+ {
101+ mode |= OpenDatabase . OpenPatchFile ;
102+ }
103+
104+ // Use the short path to avoid issues with long paths in the MSI API.
105+ var shortPath = PathUtil . GetShortPath ( path ) ;
106+
107+ return new Database ( shortPath , mode ) ;
108+ }
109+
37110 /// <summary>
38111 /// Apply a transform to the MSI.
39112 /// </summary>
40113 /// <param name="transformFile">Path to transform to apply.</param>
41114 public void ApplyTransform ( string transformFile )
42115 {
116+ var shortTransformFile = PathUtil . GetShortPath ( transformFile ) ;
117+
43118 // get the curret validation bits
44119 var conditions = TransformErrorConditions . None ;
45- using ( var summaryInfo = new SummaryInformation ( transformFile ) )
120+ using ( var summaryInfo = new SummaryInformation ( shortTransformFile ) )
46121 {
47122 try
48123 {
@@ -65,7 +140,9 @@ public void ApplyTransform(string transformFile)
65140 /// <param name="errorConditions">Specifies the error conditions that are to be suppressed.</param>
66141 public void ApplyTransform ( string transformFile , TransformErrorConditions errorConditions )
67142 {
68- var error = MsiInterop . MsiDatabaseApplyTransform ( this . Handle , transformFile , errorConditions ) ;
143+ var shortTransformFile = PathUtil . GetShortPath ( transformFile ) ;
144+
145+ var error = MsiInterop . MsiDatabaseApplyTransform ( this . Handle , shortTransformFile , errorConditions ) ;
69146 if ( 0 != error )
70147 {
71148 throw new MsiException ( error ) ;
@@ -119,7 +196,9 @@ public void Commit()
119196 /// shows which properties should be validated to verify that this transform can be applied to the database.</param>
120197 public void CreateTransformSummaryInfo ( Database referenceDatabase , string transformFile , TransformErrorConditions errorConditions , TransformValidations validations )
121198 {
122- var error = MsiInterop . MsiCreateTransformSummaryInfo ( this . Handle , referenceDatabase . Handle , transformFile , errorConditions , validations ) ;
199+ var shortTransformFile = PathUtil . GetShortPath ( transformFile ) ;
200+
201+ var error = MsiInterop . MsiCreateTransformSummaryInfo ( this . Handle , referenceDatabase . Handle , shortTransformFile , errorConditions , validations ) ;
123202 if ( 0 != error )
124203 {
125204 throw new MsiException ( error ) ;
@@ -137,7 +216,9 @@ public void Import(string idtPath)
137216 var folderPath = Path . GetFullPath ( Path . GetDirectoryName ( idtPath ) ) ;
138217 var fileName = Path . GetFileName ( idtPath ) ;
139218
140- var error = MsiInterop . MsiDatabaseImport ( this . Handle , folderPath , fileName ) ;
219+ var shortFolderPath = PathUtil . GetShortPath ( folderPath ) ;
220+
221+ var error = MsiInterop . MsiDatabaseImport ( this . Handle , shortFolderPath , fileName ) ;
141222 if ( 1627 == error ) // ERROR_FUNCTION_FAILED
142223 {
143224 throw new WixInvalidIdtException ( idtPath ) ;
@@ -161,7 +242,9 @@ public void Export(string tableName, string folderPath, string fileName)
161242 folderPath = Environment . CurrentDirectory ;
162243 }
163244
164- var error = MsiInterop . MsiDatabaseExport ( this . Handle , tableName , folderPath , fileName ) ;
245+ var shortFolderPath = PathUtil . GetShortPath ( folderPath ) ;
246+
247+ var error = MsiInterop . MsiDatabaseExport ( this . Handle , tableName , shortFolderPath , fileName ) ;
165248 if ( 0 != error )
166249 {
167250 throw new MsiException ( error ) ;
@@ -177,13 +260,29 @@ public void Export(string tableName, string folderPath, string fileName)
177260 /// there are no differences between the two databases.</returns>
178261 public bool GenerateTransform ( Database referenceDatabase , string transformFile )
179262 {
180- var error = MsiInterop . MsiDatabaseGenerateTransform ( this . Handle , referenceDatabase . Handle , transformFile , 0 , 0 ) ;
181- if ( 0 != error && 0xE8 != error ) // ERROR_NO_DATA(0xE8) means no differences were found
263+ var fileCreated = false ;
264+
265+ try
182266 {
183- throw new MsiException ( error ) ;
267+ fileCreated = PathUtil . CreateOrGetShortPath ( transformFile , out var shortTransformFile ) ;
268+
269+ var error = MsiInterop . MsiDatabaseGenerateTransform ( this . Handle , referenceDatabase . Handle , shortTransformFile , 0 , 0 ) ;
270+ if ( 0 != error && 0xE8 != error ) // ERROR_NO_DATA(0xE8) means no differences were found
271+ {
272+ throw new MsiException ( error ) ;
273+ }
274+
275+ return ( 0xE8 != error ) ;
184276 }
277+ catch // Cleanup on error
278+ {
279+ if ( fileCreated )
280+ {
281+ File . Delete ( transformFile ) ;
282+ }
185283
186- return ( 0xE8 != error ) ;
284+ throw ;
285+ }
187286 }
188287
189288 /// <summary>
0 commit comments