如何使用c#代碼獲取系統中安裝的應用程序?在系統中獲取已安裝的應用程序
回答
通過註冊表項「SOFTWARE \微軟\的Windows \ CurrentVersion \卸載」迭代似乎給安裝的應用程序的完整列表。
除了下面的例子,你可以找到一個類似的版本,我已經做了here。
這是一個粗略的例子,您可能會想要做一些事情來去除空白行,就像在提供的第二個鏈接中一樣。
string registry_key = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
using(Microsoft.Win32.RegistryKey key = Registry.LocalMachine.OpenSubKey(registry_key))
{
foreach(string subkey_name in key.GetSubKeyNames())
{
using(RegistryKey subkey = key.OpenSubKey(subkey_name))
{
Console.WriteLine(subkey.GetValue("DisplayName"));
}
}
}
或者,你可以使用WMI如已經提到:
ManagementObjectSearcher mos = new ManagementObjectSearcher("SELECT * FROM Win32_Product");
foreach(ManagementObject mo in mos.Get())
{
Console.WriteLine(mo["Name"]);
}
但是,這是相當慢的執行,我聽說它可能只在「ALLUSERS」安裝列表中的程序,雖然這可能是不正確的。它也會忽略Windows組件&更新,這可能對您很方便。
最好的選擇是使用WMI。具體是Win32_Product類。
遍歷「HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Uninstall」鍵並檢查其「DisplayName」值。
你可以看看this article。它利用註冊表來讀取已安裝應用程序的列表。
public void GetInstalledApps()
{
string uninstallKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
using (RegistryKey rk = Registry.LocalMachine.OpenSubKey(uninstallKey))
{
foreach (string skName in rk.GetSubKeyNames())
{
using (RegistryKey sk = rk.OpenSubKey(skName))
{
try
{
lstInstalled.Items.Add(sk.GetValue("DisplayName"));
}
catch (Exception ex)
{ }
}
}
}
}
我不想整個列表,我只需要一些選定的安裝程序,所以我能做些什麼。謝謝 – 2015-01-21 10:15:50
我可以建議你看看WMI(Windows Management Instrumentation)。 如果將System.Management引用添加到C#項目中,您將可以訪問「ManagementObjectSearcher」類,您可能會發現它很有用。
對於Installed Applications有各種WMI類,但是如果它與Windows安裝程序一起安裝,那麼Win32_Product類可能最適合您。
ManagementObjectSearcher s = new ManagementObjectSearcher("SELECT * FROM Win32_Product");
不使用此:https://stackoverflow.com/a/46315976/1498669 – Bernhard 2017-09-20 07:39:33
使用Windows Installer API!
它允許可靠地列舉所有程序。註冊表不可靠,但WMI是重量級的。
我使用了Nicks方法 - 我需要檢查Visual Studio的遠程工具是否安裝,看起來有點慢,但在一個單獨的線程中,這對我來說很好。 - 我在這裏的擴展代碼:
private bool isRdInstalled() {
ManagementObjectSearcher p = new ManagementObjectSearcher("SELECT * FROM Win32_Product");
foreach (ManagementObject program in p.Get()) {
if (program != null && program.GetPropertyValue("Name") != null && program.GetPropertyValue("Name").ToString().Contains("Microsoft Visual Studio 2012 Remote Debugger")) {
return true;
}
if (program != null && program.GetPropertyValue("Name") != null) {
Trace.WriteLine(program.GetPropertyValue("Name"));
}
}
return false;
}
值得注意的是,的Win32_Product WMI類代表產品,因爲它們是由Windows安裝程序[http://msdn.microsoft.com/en-us/library/aa394378%28v=vs.85%29.aspx].not每一個應用程序使用Windows Installer安裝
但是「SOFTWARE \微軟\的Windows \ CurrentVersion \ Uninstall「代表32位的應用程序。對於64位,您還需要遍歷「HKEY_LOCAL_MACHINE \ SOFTWARE \ Wow6432Node \ Microsoft \ Windows \ CurrentVersion \ Uninstall」,並且由於並非每個軟件都具有64位版本,因此安裝的所有應用程序都是具有「UninstallString」與他們的價值。
但是最好的選擇保持不變。因爲每個應用程序都有一個註冊表項[包括Windows安裝程序中的項目],所以最好的選項保持不變。但是註冊表方法不安全,就好像任何人刪除相應的鍵那樣您將不知道應用程序條目。相反,更改HKEY_Classes_ROOT \ Installers更爲棘手,因爲它與許可問題(如Microsoft Office或其他產品)相關聯。 爲更強大的解決方案,您可以隨時將註冊表替代與WMI結合使用。
我同意通過註冊表項枚舉是最好的方法。
注意但是,指定的密鑰@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
將列出32位Windows安裝中的所有應用程序以及Windows 64位安裝中的64位應用程序。
爲了還能看到安裝在Windows 64位安裝上的32位應用程序,您還需要枚舉密鑰@"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
。
我的要求是檢查我的系統中是否安裝了特定的軟件。此解決方案按預期工作。它可能會幫助你。我在Visual Studio 2015中使用了c#中的windows應用程序。
private void Form1_Load(object sender, EventArgs e)
{
object line;
string softwareinstallpath = string.Empty;
string registry_key = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
using (var baseKey = Microsoft.Win32.RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64))
{
using (var key = baseKey.OpenSubKey(registry_key))
{
foreach (string subkey_name in key.GetSubKeyNames())
{
using (var subKey = key.OpenSubKey(subkey_name))
{
line = subKey.GetValue("DisplayName");
if (line != null && (line.ToString().ToUpper().Contains("SPARK")))
{
softwareinstallpath = subKey.GetValue("InstallLocation").ToString();
listBox1.Items.Add(subKey.GetValue("InstallLocation"));
break;
}
}
}
}
}
if(softwareinstallpath.Equals(string.Empty))
{
MessageBox.Show("The Mirth connect software not installed in this system.")
}
string targetPath = softwareinstallpath + @"\custom-lib\";
string[] files = System.IO.Directory.GetFiles(@"D:\BaseFiles");
// Copy the files and overwrite destination files if they already exist.
foreach (var item in files)
{
string srcfilepath = item;
string fileName = System.IO.Path.GetFileName(item);
System.IO.File.Copy(srcfilepath, targetPath + fileName, true);
}
return;
}
值得注意的是,如果您計劃重複運行此查詢,使用WMI Win32_Product類是一個壞主意。請參閱此Microsoft知識庫文章:http://support.microsoft.com/kb/974524/EN-US 核心問題是(a)Win32_Product非常慢,(b)它生成一個「Windows安裝程序重新配置產品「。事件日誌消息,用於*系統中每個安裝的產品...每次運行查詢。衛生署! 本文建議使用Win32reg_AddRemovePrograms類...除非已安裝SMS,否則不會出現該類。衛生署! 因此可能更好地堅持使用註冊表查詢。 – 2010-03-05 00:00:10
Simon Gillbee的評論應該是被接受的答案,或Kirtans! WMI WIN32_Product不是去這裏的路,相信我! – bdd 2010-03-16 23:58:52
呃,這就是爲什麼這個註冊表例子首先在我的答案中。 WMI只是作爲一種替代解決方案提出的,即使在那裏我也會說「執行速度慢」等缺點。從一開始就閱讀答案。 ;) – Xiaofu 2010-03-17 07:42:30