Skip to content

Commit 7894cba

Browse files
authored
Add Uninstall-Package (#28)
1 parent 6831253 commit 7894cba

1 file changed

Lines changed: 103 additions & 1 deletion

File tree

src/code/ProgramsProvider.cs

Lines changed: 103 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,17 @@
55
using Microsoft.Win32;
66
using System;
77
using System.Collections.Generic;
8+
using System.Diagnostics;
9+
using System.Management.Automation;
810

911
namespace AnyPackage.Provider.Programs
1012
{
1113
[PackageProvider("Programs")]
12-
public sealed class ProgramsProvider : PackageProvider, IGetPackage
14+
public sealed class ProgramsProvider : PackageProvider, IGetPackage, IUninstallPackage
1315
{
1416
private const string _uninstallKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
17+
private const string _uninstallString = "UninstallString";
18+
private const string _quietUninstallString = "QuietUninstallString";
1519

1620
protected override object? GetDynamicParameters(string commandName)
1721
{
@@ -40,6 +44,29 @@ public void GetPackage(PackageRequest request)
4044
GetPackage(hkcu, request);
4145
}
4246

47+
public void UninstallPackage(PackageRequest request)
48+
{
49+
if (request.Package is not null)
50+
{
51+
UninstallPackage(request.Package, request);
52+
}
53+
else
54+
{
55+
using var powershell = PowerShell.Create();
56+
powershell.AddCommand("Get-Package").AddParameter("Name", request.Name);
57+
58+
if (request.Version is not null)
59+
{
60+
powershell.AddParameter("Version", request.Version);
61+
}
62+
63+
foreach (var package in powershell.Invoke<PackageInfo>())
64+
{
65+
UninstallPackage(package, request);
66+
}
67+
}
68+
}
69+
4370
private void GetPackage(RegistryKey key, PackageRequest request)
4471
{
4572
var dynamicParameters = request.DynamicParameters as GetPackageDynamicParameters;
@@ -104,5 +131,80 @@ private void GetPackage(RegistryKey key, PackageRequest request)
104131
}
105132
}
106133
}
134+
135+
private void UninstallPackage(PackageInfo package, PackageRequest request)
136+
{
137+
string uninstallString;
138+
139+
if (package.Metadata.ContainsKey(_quietUninstallString))
140+
{
141+
request.WriteVerbose("Quiet uninstall string found.");
142+
uninstallString = package.Metadata[_quietUninstallString].ToString();
143+
}
144+
else if (package.Metadata.ContainsKey(_uninstallString))
145+
{
146+
request.WriteVerbose("Uninstall string found.");
147+
uninstallString = package.Metadata[_uninstallString].ToString();
148+
}
149+
else
150+
{
151+
throw new InvalidOperationException($"Package '{package.Name}' with version '{package.Version} cannot find uninstall program.");
152+
}
153+
154+
using var process = GetProcess(uninstallString);
155+
process.Start();
156+
process.WaitForExit();
157+
158+
request.WritePackage(package);
159+
}
160+
161+
private Process GetProcess(string text)
162+
{
163+
bool quoted, found;
164+
int i, position;
165+
166+
quoted = found = false;
167+
i = position = 0;
168+
169+
if (text[0] == '"')
170+
{
171+
quoted = true;
172+
}
173+
174+
for (i = quoted ? 1 : 0; i < text.Length; i++)
175+
{
176+
if (text[i] == ' ' && !quoted)
177+
{
178+
position = i;
179+
found = true;
180+
break;
181+
}
182+
else if (text[i] == '"' && quoted)
183+
{
184+
position = i;
185+
found = true;
186+
break;
187+
}
188+
}
189+
190+
var process = new Process();
191+
192+
if (found && quoted)
193+
{
194+
process.StartInfo.FileName = text.Substring(0, position + 1).Replace("\"", "");
195+
process.StartInfo.Arguments = text.Substring(position + 1, text.Length - position - 1).Trim();
196+
}
197+
else if (found)
198+
{
199+
process.StartInfo.FileName = text.Substring(0, position);
200+
process.StartInfo.Arguments = text.Substring(position, text.Length - position).Trim();
201+
}
202+
else
203+
{
204+
process.StartInfo.FileName = text;
205+
}
206+
207+
return process;
208+
}
107209
}
108210
}

0 commit comments

Comments
 (0)