3
3
4
4
using System ;
5
5
using System . IO ;
6
+ using System . Runtime . InteropServices ;
6
7
using Microsoft . Win32 ;
7
- using WixToolset . Dtf . WindowsInstaller ;
8
+ using Microsoft . Win32 . Msi ;
8
9
9
10
if ( args . Length < 3 )
10
11
{
@@ -99,51 +100,34 @@ static bool DetectSdk(string featureBandVersion, string platform)
99
100
100
101
static bool RemoveDependent ( string dependent )
101
102
{
102
- Installer . SetInternalUI ( InstallUIOptions . Silent ) ;
103
+ // Disable MSI UI
104
+ _ = MsiSetInternalUI ( ( uint ) InstallUILevel . NoChange , IntPtr . Zero ) ;
103
105
104
106
// Open the installer dependencies registry key
105
- // This has to be an exhaustive search as we're not looking for a specific provider key, but for a specific dependent
106
- // that could be registered against any provider key.
107
107
using var hkInstallerDependenciesKey = Registry . LocalMachine . OpenSubKey ( @"SOFTWARE\Classes\Installer\Dependencies" , writable : true ) ;
108
108
if ( hkInstallerDependenciesKey == null )
109
109
{
110
110
Console . WriteLine ( "Installer dependencies key does not exist." ) ;
111
- return false ; // No dependencies to remove
111
+ return false ;
112
112
}
113
113
114
- // Iterate over each provider key in the dependencies
115
114
foreach ( string providerKeyName in hkInstallerDependenciesKey . GetSubKeyNames ( ) )
116
115
{
117
116
Console . WriteLine ( $ "Processing provider key: { providerKeyName } ") ;
118
117
119
118
using var hkProviderKey = hkInstallerDependenciesKey . OpenSubKey ( providerKeyName , writable : true ) ;
120
119
if ( hkProviderKey == null ) continue ;
121
120
122
- // Open the Dependents subkey
123
121
using var hkDependentsKey = hkProviderKey . OpenSubKey ( "Dependents" , writable : true ) ;
124
122
if ( hkDependentsKey == null ) continue ;
125
123
126
- // Check if the dependent exists and continue if it does not
127
- string [ ] dependentsKeys = hkDependentsKey . GetSubKeyNames ( ) ;
128
- bool dependentExists = false ;
124
+ bool dependentExists = hkDependentsKey . GetSubKeyNames ( )
125
+ . Any ( dependentsKeyName => string . Equals ( dependentsKeyName , dependent , StringComparison . OrdinalIgnoreCase ) ) ;
129
126
130
- foreach ( string dependentsKeyName in dependentsKeys )
131
- {
132
- if ( string . Equals ( dependentsKeyName , dependent , StringComparison . OrdinalIgnoreCase ) )
133
- {
134
- dependentExists = true ;
135
- break ;
136
- }
137
- }
138
-
139
- if ( ! dependentExists )
140
- {
141
- continue ; // Skip to the next provider key if the dependent does not exist
142
- }
127
+ if ( ! dependentExists ) continue ;
143
128
144
129
Console . WriteLine ( $ "Dependent match found: { dependent } ") ;
145
130
146
- // Attempt to remove the dependent key
147
131
try
148
132
{
149
133
hkDependentsKey . DeleteSubKey ( dependent ) ;
@@ -155,16 +139,14 @@ static bool RemoveDependent(string dependent)
155
139
return false ;
156
140
}
157
141
158
- // Check if any dependents are left
159
142
if ( hkDependentsKey . SubKeyCount == 0 )
160
143
{
161
- // No remaining dependents, handle product uninstallation
162
144
try
163
145
{
164
146
string productCode = hkProviderKey . GetValue ( "ProductId" ) . ToString ( ) ;
165
147
166
- // Configure the product to be absent
167
- Installer . ConfigureProduct ( productCode , 0 , InstallState . Absent , "" ) ;
148
+ // Configure the product to be absent (uninstall the product)
149
+ uint error = MsiConfigureProductEx ( productCode , ( int ) InstallUILevel . Default , InstallState . ABSENT , "" ) ;
168
150
Console . WriteLine ( "Product configured to absent successfully." ) ;
169
151
}
170
152
catch ( Exception ex )
@@ -175,7 +157,6 @@ static bool RemoveDependent(string dependent)
175
157
}
176
158
return true ;
177
159
}
178
-
179
160
return false ;
180
161
}
181
162
@@ -244,3 +225,11 @@ static bool IsRebootPending()
244
225
Console . WriteLine ( "No reboot pending." ) ;
245
226
return false ;
246
227
}
228
+
229
+ [ DllImport ( "msi.dll" , CharSet = CharSet . Unicode ) ]
230
+ [ DefaultDllImportSearchPaths ( DllImportSearchPath . System32 ) ]
231
+ static extern uint MsiConfigureProductEx ( string szProduct , int iInstallLevel , InstallState eInstallState , string szCommandLine ) ;
232
+
233
+ [ DllImport ( "msi.dll" , CharSet = CharSet . Unicode ) ]
234
+ [ DefaultDllImportSearchPaths ( DllImportSearchPath . System32 ) ]
235
+ static extern uint MsiSetInternalUI ( uint dwUILevel , IntPtr phWnd ) ;
0 commit comments