Na skupnosti za razvijalce in IT Pro-je mstech.si je bilo postavljeno vprašanje, kako lahko prikažemo informacije o nameščenih aplikacijah v Add/Remove programs in kako odstranimo nek program iz računalnika.
Ker je bilo vprašanje zelo zanimivo, sem začel malce raziskovati. Na žalost so teme na spletu glede tega skope oziroma so podani zgolj odgovori s stališča, kako se lotit, ni pa nekega praktičnega enostavnega primera. Zato sem se lotil enega enostavnega primera, kako prikazati nameščene programe in kako zagnati uninstall.
Add/Remove panel deluje na sistemu registra. Torej, ko namestite aplikacijo, namestitveni program shrani v register dodane informacije pod HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{ProductCode}. Dokaj simple, ne? No, ni tako. Problem je, ker so določeni programi, ki so nameščeni v sam register označeni z GUID-om (ponavadi je to Product Code), zato je človeku razumljiv prikaz nameščenih programov dokaj problematičen (seveda razen če imamo telepatično sposobnost spreminjanja GUID-ov v nek razumen tekst).
Microsoft predlaga oziroma delno zahteva, da namestitveni programi shranijo v ta del registra sledeče podatke (razni namestitveni programi – InstallWise, InstallShield,…) to avtomatsko naredijo:
Struktura tega zgleda v registru takole:
Zahvajujoč tej specifikaciji, nam GUID-i ne delajo več težav. Torej, vse kar rabimo, je DisplayName in UninstallString, ki ga poberemo iz registra.
Torej, kako začeti?
- Sestavimo obrazec za prikaz (namizno aplikacijo – za spremembo Windows Forms in ne WPF :) –> čeprav v WPFju ta koda tudi deluje, razen oblikovnega vmesnik, kjer je binding malce drugačen ;))
- se povežemo na register, pridobimo informacije in nato zaženemo nov proces (če nimamo pravic, zaženemo administratorski način – konec koncev delamo z registri)
Obrazec za prikaz
Obrazec za prikaz bo v našem primeru dokaj enostaven. Imeli bomo tekstovno polje (TextBox), da bomo lahko iskali po aplikacijah (če poberemo ven aplikacije, jih ponavadi ni malo), gumb za iskanje (Button) ter kontrolo za prikaz programov (izbrali bomo ListBox).
Končni rezultat:
Koda za prikaz in izvršitev uninstall-a
Zdaj vemo, kar se moramo povezati, zato se bomo povezali na register pod HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\ in se sprehodili čez programe ter jih prikazali.
Ustvarili bomo metodo ListItems, ki bo sprejela iskalni text. Prvo stvar, ki jo bomo naredili, je da bomo počistili kontrolo ListBox (da ne bomo imeli dvojnih vnosov).
lstResults.Items.Clear(); //lstResults je ime našega ListBox-a
Potem se bomo povezali na register, in sicer HKEY_LOCAL_MACHINE. Uporabljali bomo knjižnico Win32 API za dostop do registrov, ki se nahaja v imenskem prostoru Microsoft.Win32 (če ga še niste dodali, dodajte v using). Naslednji korak je, da se povežemo na register. Obstaja RegisterKey, ki ima konstanto LocalMachine, s katerim dobimo dostop do HKEY_LOCAL_MACHINE.
RegistryKey baseKey = Registry.LocalMachine;
Naslednji korak je povezava na SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\. Ker ima HKEY_LOCAL_MACHINE subkey-e (register je ena lepa drevesna struktura :)), lahko odpremo SubKey.
RegistryKey subkeys = baseKey.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall");
Zdaj se nahajamo v subkey-sih, zato se lahko po njih sprehajamo. Ker bi radi imeli možnost iskanja, ima RegistryKey metodo GetSubKeyNames(), s katero dobimo imena SubKey-ev. Zdaj se lahko z LINQ-om (metoda vrne polje string-ov) sprehodimo po njih glede na vnešeno polje.
string[] results;//vrnemo rezultate glede na akcijo
if (string.IsNullOrEmpty(searchString))
results = subkeys.GetSubKeyNames();
else
results = (from c in subkeys.GetSubKeyNames()
where c.Contains(searchString)
select c).ToArray();
Zdaj smo dobili vse subkey-e, vendar še nismo rešili problema z GUID-i. V ta namen bomo naredili privatni razred, ki nam bo služil za informacijo o imenu programa ter poti do namestitvene datoteke.
/// <summary>
/// pomožni razred za informacije o uninstall-u
/// </summary>
private class ProgramToUninstall
{
/// <summary>
/// prikažemo ime
/// </summary>
/// <remarks>
/// določeni zapisi v registrih so v GUID-ih ... imajo pa zato vrednost DisplayName
/// </remarks>
public string DisplayName { get; set; }
/// <summary>
/// pod do uninstall-a, ki je ali msiexe ali pa setup z različnimi parametri
/// </summary>
public string UninstallPath { get; set; }
}
Zdaj lahko poberemo ven podatke za prikaz.
//zlistamo v seznamu
for (int i = 0; i < results.Length; i++)
{
RegistryKey key = subkeys.OpenSubKey(results);
object value = key.GetValue("DisplayName", null); //null je privzeta vrednost, ki jo vrne, če ne najde vrednosti
object uninstall = key.GetValue("UninstallString", null);
if (value != null && uninstall != null) //če ga nima, ga ne prikažemo
{
ProgramToUninstall program = new ProgramToUninstall
{
DisplayName = value.ToString(),
UninstallPath = uninstall.ToString()
};
lstResults.Items.Add(program);
lstResults.DisplayMember = "DisplayName"; //potrebujemo, da povemo, kaj se uporabniku prikaže
}
}
Zlistanje deluje, zdaj pa vse, kar moramo narediti, da vežemo to na event klika gumba (v našem primeru):
private void btnSearch_Click(object sender, EventArgs e)
{
ListItems(tbSearch.Text);
}
Zdaj nam manjka še samo zagon uninstall-a (naredili bomo kar na sistem dvoklik-a na ). Prvo, kar potrebujemo, je pretvorba trenutnega izbranega item-a:
ProgramToUninstall software = lstResults.SelectedItem as ProgramToUninstall;
Ker želimo zagnati uninstall, uporabimo razred ProcessInfo, ki je namenjen informaciji o zaganjanju novih procesov (pri tem še pazimo, da zaženemo setup pod admin pravicami: verb=runas :)). V zadnji fazi uporabi razred Process, ki je namenjen zaganjanju procesov, programov, itd. (nahaja se v imenskem prostoru System.Diagnostics). Dodali bomo še pogoj, da odstranimo v primeru, da uporabnik potrdi izbiro.
private void lstResults_MouseDoubleClick(object sender, MouseEventArgs e)
{
ProgramToUninstall software = lstResults.SelectedItem as ProgramToUninstall;
//pogledamo, kje se aplikacija nahaja ter sprožimo uninstall (pod admin pravicami)
//pridobimo uninstall string
ProcessStartInfo info = new ProcessStartInfo();
info.Verb = "runas";//zaženemo kot admin (ni pa nujno)
info.FileName = software.UninstallPath;
try
{
DialogResult result = MessageBox.Show("Želite odstraniti program?", "Informacija", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (result == System.Windows.Forms.DialogResult.Yes)
{
Process.Start(info);
}
}
catch (Exception error)
{
MessageBox.Show("Napaka: " + error, "Napaka", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
Evole, aplikacija je narejena. Primer si lahko prenesete na tem naslovu. Veselo nadziranje nameščenih programov.
p.s.
Če imate custom inštalacijo, ki je nameščena na drugačen način, kot to zahteva Add/Remove, potem morate brisati na drugačen način kot predvideva namestitev aplikacije.
HedaWhece - ponedeljek, 18. november 2024
Currently I started taking flaxseed capsule, turmeric tablet, Ginger capsule and lemon juice twice daily <a href=https://fastpriligy.top/>order priligy online uk</a>
HedaWhece - nedelja, 10. november 2024
Interestingly, further stratification of patient groups based on inverse GATA3 PDEF expression improves the predictive capability of PDEF Figure 5C <a href=https://fastpriligy.top/>priligy amazon uk</a>