सिस्टम में c # कोड का उपयोग करके इंस्टॉल किए गए एप्लिकेशन कैसे प्राप्त करें?
जवाबों:
रजिस्ट्री कुंजी "सॉफ़्टवेयर \ Microsoft \ Windows \ CurrentVersion \ Uninstall" के माध्यम से Iterating स्थापित अनुप्रयोगों की एक व्यापक सूची देने लगता है।
नीचे दिए गए उदाहरण के अलावा, आप यहाँ जो मैंने किया है उसके समान संस्करण पा सकते हैं ।
यह एक मोटा उदाहरण है, आप प्रोबाय 2 लिंक में दिए गए लिंक की तरह खाली पंक्तियों को अलग करना चाहते हैं।
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" के तहत स्थापित प्रोग्रामों को सूचीबद्ध कर सकता है, हालांकि यह गलत हो सकता है। यह विंडोज घटकों और अपडेट को भी अनदेखा करता है, जो आपके लिए उपयोगी हो सकता है।
आप इस लेख पर एक नज़र डाल सकते हैं । यह स्थापित अनुप्रयोगों की सूची को पढ़ने के लिए रजिस्ट्री का उपयोग करता है।
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)
{ }
}
}
}
}
मैं मानता हूं कि रजिस्ट्री कुंजी के माध्यम से गणना करना सबसे अच्छा तरीका है।
ध्यान दें , हालांकि, दी गई कुंजी, @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
32-बिट विंडोज इंस्टॉलेशन में सभी एप्लिकेशन और विंडोज 64-बिट इंस्टॉलेशन में 64-बिट एप्लिकेशन को सूचीबद्ध करेगी।
विंडोज 64-बिट इंस्टॉलेशन पर इंस्टॉल किए गए 32-बिट एप्लिकेशन को देखने के लिए, आपको कुंजी की गणना भी करनी होगी @"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
।
regedit
ऐसा लगता है। 32 बिट प्रोग्राम में (64 बिट विंडोज पर), हालांकि, दोनों सूची WOW6432Node
एक से समान हैं regedit
।
मैं एप्स की सूची निकालने में सक्षम होना चाहता था, जैसा कि वे स्टार्ट मेनू में दिखाई देते हैं। रजिस्ट्री का उपयोग करते हुए, मुझे ऐसी प्रविष्टियाँ मिल रही थीं जो स्टार्ट मेनू में दिखाई नहीं देती हैं।
मैं भी exe रास्ता खोजना चाहता था और आखिरकार एक अच्छा दिखने वाला लॉन्चर बनाने के लिए एक आइकन निकालना चाहता था। दुर्भाग्य से, रजिस्ट्री पद्धति के साथ यह एक हिट और मिस की तरह है क्योंकि मेरे अवलोकन हैं कि यह जानकारी विश्वसनीय रूप से उपलब्ध नहीं है।
मेरा विकल्प शेल के आसपास आधारित है: AppsFolder जिसे आप चलाकर एक्सेस कर सकते हैं explorer.exe shell:appsFolder
और जो स्टोर ऐप सहित सभी ऐप को सूचीबद्ध करता है, वर्तमान में इंस्टॉल किया गया है और स्टार्ट मेनू के माध्यम से उपलब्ध है। मुद्दा यह है कि यह एक वर्चुअल फ़ोल्डर है जिसे एक्सेस नहीं किया जा सकता है System.IO.Directory
। इसके बजाय, आपको मूल शेल 32 कमांड का उपयोग करना होगा। सौभाग्य से, Microsoft ने Nuget पर Microsoft.WindowsAPICodePack-Shell प्रकाशित किया जो उपरोक्त आदेशों के लिए एक आवरण है। पर्याप्त ने कहा, यहाँ कोड है:
// GUID taken from https://docs.microsoft.com/en-us/windows/win32/shell/knownfolderid
var FOLDERID_AppsFolder = new Guid("{1e87508d-89c2-42f0-8a7e-645a0f50ca58}");
ShellObject appsFolder = (ShellObject)KnownFolderHelper.FromKnownFolderId(FOLDERID_AppsFolder);
foreach (var app in (IKnownFolder)appsFolder)
{
// The friendly app name
string name = app.Name;
// The ParsingName property is the AppUserModelID
string appUserModelID = app.ParsingName; // or app.Properties.System.AppUserModel.ID
// You can even get the Jumbo icon in one shot
ImageSource icon = app.Thumbnail.ExtraLargeBitmapSource;
}
और यही सब कुछ है। आप ऐप्स का उपयोग करके भी शुरू कर सकते हैं
System.Diagnostics.Process.Start("explorer.exe", @" shell:appsFolder\" + appModelUserID);
यह नियमित Win32 ऐप और UWP स्टोर ऐप के लिए काम करता है। उनके बारे में कैसे सेब।
चूंकि आप सभी इंस्टॉल किए गए ऐप्स को सूचीबद्ध करने में रुचि रखते हैं, इसलिए यह अपेक्षा करना उचित है कि आप नए ऐप या अनइंस्टॉल किए गए ऐप के लिए भी निगरानी करना चाहते हैं, जो आप निम्न का उपयोग कर सकते हैं ShellObjectWatcher
:
ShellObjectWatcher sow = new ShellObjectWatcher(appsFolder, false);
sow.AllEvents += (s, e) => DoWhatever();
sow.Start();
संपादित करें: किसी को यह जानने में भी रुचि हो सकती है कि ऊपर उल्लिखित AppUserMoedlID टास्कबार में समूह विंडोज़ के लिए यूनिक आईडी विंडोज का उपयोग करता है ।
AllEvents
के रूप में इस तरह के ItemCreated
या ItemRenamed
जो मैं क्षुधा का ट्रैक रखने के रूप में वे स्थापित किए गए या हटा दिया का उपयोग कर की कोशिश की। इन घटनाओं के घटना आर्ग में एक Path
संपत्ति होती है, लेकिन यह संपत्ति हमेशा अशक्त होती है, कम से कम मेरे परीक्षणों में। मैंने यह पता लगाने की कोशिश करने की जहमत नहीं उठाई है कि इसे कैसे नामुमकिन माना जाता है क्योंकि यह हमेशा शून्य है। इसके बजाय, मैं बस उन ऐप्स की एक सूची रखता हूं, जिन्हें जब भी कोई आइटम फ़ोल्डर में ऐप्स के माध्यम से पुनरावृति करके उठाया जाता है। आदर्श नहीं है लेकिन काम हो जाता है।
यह ध्यान देने योग्य है कि Win32_Product WMI वर्ग उत्पादों का प्रतिनिधित्व करता है क्योंकि वे विंडोज इंस्टालर द्वारा स्थापित किए गए हैं । हर एप्लिकेशन विंडोज़ इंस्टॉलर का उपयोग नहीं करता है
हालाँकि "सॉफ़्टवेयर \ Microsoft \ Windows \ CurrentVersion \ Uninstall" 32 बिट के लिए अनुप्रयोगों का प्रतिनिधित्व करता है। 64 बिट के लिए भी आपको "HKEY_LOCAL_MACHINE \ SOFTWARE \ Wow6432Node \ Microsoft \ Windows \ CurrentVersion \ Uninstall" ट्रैवस करने की आवश्यकता है और चूंकि प्रत्येक सॉफ़्टवेयर में 64 बिट संस्करण नहीं है, कुल स्थापित एप्लिकेशन दोनों स्थानों पर कुंजियों का एक संघ हैं जिनमें "UninstallString" हैं। उनके साथ मूल्य।
लेकिन सबसे अच्छा विकल्प वही रहता है। रजिस्ट्री की कुंजियाँ एक बेहतर तरीका है क्योंकि प्रत्येक एप्लिकेशन में रजिस्ट्री में प्रविष्टि होती है [विंडोज इंस्टालर में लोगों सहित]। जब भी रजिस्ट्री विधि असुरक्षित होती है जैसे कोई भी संबंधित कुंजी को हटाता है तो आपको पता नहीं चलेगा। अनुप्रयोग प्रविष्टि। इसके विपरीत HKEY_Classes_ROOT \ Installers को बदलना अधिक मुश्किल है क्योंकि यह Microsoft Office या अन्य उत्पादों जैसे लाइसेंसिंग मुद्दों से जुड़ा हुआ है। अधिक मजबूत समाधान के लिए आप हमेशा WMI के साथ रजिस्ट्री विकल्प को जोड़ सकते हैं।
जबकि स्वीकृत समाधान काम करता है, यह पूर्ण नहीं है। से दूर।
यदि आप सभी कुंजी प्राप्त करना चाहते हैं, तो आपको 2 और बातों पर ध्यान देने की आवश्यकता है:
x86 और x64 अनुप्रयोगों की एक ही रजिस्ट्री तक पहुंच नहीं है। मूल रूप से x86 सामान्य रूप से x64 रजिस्ट्री तक नहीं पहुंच सकता। और कुछ एप्लिकेशन केवल x64 रजिस्ट्री में पंजीकृत होते हैं।
तथा
कुछ अनुप्रयोग वास्तव में LocalMachine के बजाय CurrentUser रजिस्ट्री में स्थापित होते हैं
इसे ध्यान में रखते हुए, मैंने WMI का उपयोग किए बिना , निम्न कोड का उपयोग करके सभी स्थापित एप्लिकेशन प्राप्त करने में कामयाबी हासिल की
यहाँ कोड है:
List<string> installs = new List<string>();
List<string> keys = new List<string>() {
@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
@"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
};
// The RegistryView.Registry64 forces the application to open the registry as x64 even if the application is compiled as x86
FindInstalls(RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64), keys, installs);
FindInstalls(RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64), keys, installs);
installs = installs.Where(s => !string.IsNullOrWhiteSpace(s)).Distinct().ToList();
installs.Sort(); // The list of ALL installed applications
private void FindInstalls(RegistryKey regKey, List<string> keys, List<string> installed)
{
foreach (string key in keys)
{
using (RegistryKey rk = regKey.OpenSubKey(key))
{
if (rk == null)
{
continue;
}
foreach (string skName in rk.GetSubKeyNames())
{
using (RegistryKey sk = rk.OpenSubKey(skName))
{
try
{
installed.Add(Convert.ToString(sk.GetValue("DisplayName")));
}
catch (Exception ex)
{ }
}
}
}
}
}
"HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Uninstall" कुंजियों के माध्यम से Iterate करें और उनके "DisplayName" मान जांचें।
Windows इंस्टालर API का उपयोग करें!
यह सभी कार्यक्रमों की विश्वसनीय गणना करने की अनुमति देता है। रजिस्ट्री विश्वसनीय नहीं है, लेकिन WMI हैवीवेट है।
सूची के लिए वस्तु:
public class InstalledProgram
{
public string DisplayName { get; set; }
public string Version { get; set; }
public string InstalledDate { get; set; }
public string Publisher { get; set; }
public string UnninstallCommand { get; set; }
public string ModifyPath { get; set; }
}
सूची बनाने के लिए कॉल:
List<InstalledProgram> installedprograms = new List<InstalledProgram>();
string registry_key = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(registry_key))
{
foreach (string subkey_name in key.GetSubKeyNames())
{
using (RegistryKey subkey = key.OpenSubKey(subkey_name))
{
if (subkey.GetValue("DisplayName") != null)
{
installedprograms.Add(new InstalledProgram
{
DisplayName = (string)subkey.GetValue("DisplayName"),
Version = (string)subkey.GetValue("DisplayVersion"),
InstalledDate = (string)subkey.GetValue("InstallDate"),
Publisher = (string)subkey.GetValue("Publisher"),
UnninstallCommand = (string)subkey.GetValue("UninstallString"),
ModifyPath = (string)subkey.GetValue("ModifyPath")
});
}
}
}
}
जैसा कि अन्य ने बताया है, स्वीकृत उत्तर x86 और x64 दोनों संस्थापनों को वापस नहीं करता है। उसके लिए मेरा समाधान नीचे है। यह एक बनाता है StringBuilder
, रजिस्ट्री मानों को इसमें जोड़ देता है (स्वरूपण के साथ), और एक पाठ फ़ाइल में अपना आउटपुट लिखता है:
const string FORMAT = "{0,-100} {1,-20} {2,-30} {3,-8}\n";
private void LogInstalledSoftware()
{
var line = string.Format(FORMAT, "DisplayName", "Version", "Publisher", "InstallDate");
line += string.Format(FORMAT, "-----------", "-------", "---------", "-----------");
var sb = new StringBuilder(line, 100000);
ReadRegistryUninstall(ref sb, RegistryView.Registry32);
sb.Append($"\n[64 bit section]\n\n{line}");
ReadRegistryUninstall(ref sb, RegistryView.Registry64);
File.WriteAllText(@"c:\temp\log.txt", sb.ToString());
}
private static void ReadRegistryUninstall(ref StringBuilder sb, RegistryView view)
{
const string REGISTRY_KEY = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
using var baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, view);
using var subKey = baseKey.OpenSubKey(REGISTRY_KEY);
foreach (string subkey_name in subKey.GetSubKeyNames())
{
using RegistryKey key = subKey.OpenSubKey(subkey_name);
if (!string.IsNullOrEmpty(key.GetValue("DisplayName") as string))
{
var line = string.Format(FORMAT,
key.GetValue("DisplayName"),
key.GetValue("DisplayVersion"),
key.GetValue("Publisher"),
key.GetValue("InstallDate"));
sb.Append(line);
}
key.Close();
}
subKey.Close();
baseKey.Close();
}
आपका सबसे अच्छा शर्त WMI का उपयोग करना है । विशेष रूप से Win32_Product वर्ग।
मेरा सुझाव है कि आप WMI ( विंडोज मैनेजमेंट इंस्ट्रूमेंटेशन ) पर एक नज़र डालें । यदि आप अपने C # प्रोजेक्ट में System.Management संदर्भ जोड़ते हैं, तो आप वर्ग 'ManagementObjectSearcher' तक पहुँच प्राप्त करेंगे, जिसे आप संभवतः उपयोगी पाएंगे।
इंस्टॉल किए गए एप्लिकेशन के लिए विभिन्न WMI वर्ग हैं , लेकिन अगर यह विंडोज इंस्टालर के साथ स्थापित किया गया था, तो Win32_Product वर्ग शायद आपके लिए सबसे उपयुक्त है।
ManagementObjectSearcher s = new ManagementObjectSearcher("SELECT * FROM Win32_Product");
मैंने 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;
}
मेरी आवश्यकता यह जांचने के लिए है कि मेरे सिस्टम में विशिष्ट सॉफ़्टवेयर स्थापित है या नहीं। यह समाधान उम्मीद के मुताबिक काम करता है। यह आपकी मदद कर सकता है। मैंने दृश्य स्टूडियो 2015 के साथ c # में एक विंडोज़ एप्लिकेशन का उपयोग किया।
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;
}