시스템에 설치된 애플리케이션 가져 오기
C # 코드를 사용하여 시스템에 애플리케이션을 설치하는 방법은 무엇입니까?
레지스트리 키 "SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Uninstall"을 반복하면 설치된 응용 프로그램의 전체 목록이 제공되는 것 같습니다.
아래 예제를 제외하고 여기에서 수행 한 것과 유사한 버전을 찾을 수 있습니다 .
이것은 대략적인 예입니다. 제공된 두 번째 링크에서와 같이 빈 행을 제거하기 위해 무언가를하고 싶을 것입니다.
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 구성 요소 및 업데이트를 무시합니다.
이 기사를 볼 수 있습니다 . 레지스트리를 사용하여 설치된 응용 프로그램 목록을 읽습니다.
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"
, 윈도우 64 비트 설치의 모든 32 비트 Windows 설치에서 응용 프로그램 및 64 비트 응용 프로그램을 나열합니다.
Windows 64 비트 설치에 설치된 32 비트 애플리케이션도 보려면 키를 열거해야합니다 @"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
.
Win32_Product WMI 클래스는 Windows Installer에 의해 설치되는 제품을 나타냅니다 . 모든 응용 프로그램이 Windows 설치 프로그램을 사용하는 것은 아닙니다.
그러나 "SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Uninstall"은 32 비트 용 응용 프로그램을 나타냅니다. 64 비트의 경우 "HKEY_LOCAL_MACHINE \ SOFTWARE \ Wow6432Node \ Microsoft \ Windows \ CurrentVersion \ Uninstall"을 통과해야합니다. 모든 소프트웨어에 64 비트 버전이있는 것은 아니기 때문에 설치된 전체 응용 프로그램은 "UninstallString"이있는 두 위치에서 키의 합집합입니다. 그들과 함께 가치.
그러나 최상의 옵션은 동일한 .traverse 레지스트리 키로 유지되는 것이 좋습니다. 모든 응용 프로그램이 레지스트리에 항목 (Windows Installer의 항목 포함)이 있기 때문에 더 나은 방법입니다. 그러나 레지스트리 방법은 마치 누군가가 해당 키를 제거하는 것처럼 안전하지 않습니다. 반대로 HKEY_Classes_ROOT \ Installers를 변경하는 것은 Microsoft Office 또는 기타 제품과 같은 라이선스 문제와 관련되어 있기 때문에 더 까다 롭습니다. 보다 강력한 솔루션을 위해 언제든지 레지스트리 대안을 WMI와 결합 할 수 있습니다.
"HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Uninstall"키를 반복하고 "DisplayName"값을 확인합니다.
Windows Installer API를 사용하십시오!
모든 프로그램을 신뢰할 수있게 열거 할 수 있습니다. 레지스트리는 신뢰할 수 없지만 WMI는 무겁습니다.
가장 좋은 방법은 WMI 를 사용하는 것 입니다. 특히 Win32_Product 클래스입니다.
WMI ( Windows Management Instrumentation )를 살펴 보시기 바랍니다 . System.Management 참조를 C # 프로젝트에 추가하면`ManagementObjectSearcher '클래스에 액세스 할 수 있으며 유용 할 것입니다.
설치된 응용 프로그램에 대한 다양한 WMI 클래스가 있지만 Windows Installer와 함께 설치된 경우 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;
}
내 요구 사항은 내 시스템에 특정 소프트웨어가 설치되어 있는지 확인하는 것입니다. 이 솔루션은 예상대로 작동합니다. 도움이 될 수 있습니다. 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;
}
시작 메뉴에 나타나는대로 앱 목록을 추출 할 수 있기를 원했습니다. 레지스트리를 사용하여 시작 메뉴에 표시되지 않는 항목을 가져 왔습니다.
또한 exe 경로를 찾고 아이콘을 추출하여 멋진 런처를 만들고 싶었습니다. 불행히도 레지스트리 방법을 사용하면이 정보를 안정적으로 사용할 수 없다는 것이 관찰 되었기 때문에 일종의 히트 앤 미스입니다.
My alternative is based around the shell:AppsFolder which you can access by running explorer.exe shell:appsFolder
and which lists all apps, including store apps, currently installed and available through the start menu. The issue is that this is a virtual folder that can't be accessed with System.IO.Directory
. Instead, you would have to use native shell32 commands. Fortunately, Microsoft published the Microsoft.WindowsAPICodePack-Shell on Nuget which is a wrapper for the aforementioned commands. Enough said, here's the code:
// GUID taken from https://docs.microsoft.com/en-us/windows/win32/shell/knownfolderid
var FODLERID_AppsFolder = new Guid("{1e87508d-89c2-42f0-8a7e-645a0f50ca58}");
ShellObject appsFolder = (ShellObject)KnownFolderHelper.FromKnownFolderId(FODLERID_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;
}
And that's all there is to it. You can also start the apps using
System.Diagnostics.Process.Start("explorer.exe", @" shell:appsFolder\" + appModelUserID);
This works for regular Win32 apps and UWP store apps. How about them apples.
Since you are interested in listing all installed apps, it is reasonable to expect that you might want to monitor for new apps or uninstalled apps as well, which you can do using the ShellObjectWatcher
:
ShellObjectWatcher sow = new ShellObjectWatcher(appsFolder, false);
sow.AllEvents += (s, e) => DoWhatever();
sow.Start();
Edit: One might also be interested in knowing that the AppUserMoedlID mentioned above is the unique ID Windows uses to group windows in the taskbar.
While the accepted solution works, it is not complete. By far.
If you want to get all the keys, you need to take into consideration 2 more things:
x86 & x64 applications do not have access to the same registry. Basically x86 cannot normally access x64 registry. And some applications only register to the x64 registry.
and
some applications actually install into the CurrentUser registry instead of the LocalMachine
With that in mind, I managed to get ALL installed applications using the following code, WITHOUT using WMI
Here is the code:
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)
{ }
}
}
}
}
}
참고URL : https://stackoverflow.com/questions/908850/get-installed-applications-in-a-system
'Programing' 카테고리의 다른 글
확장 방법을 식별하기위한 반영 (0) | 2020.10.27 |
---|---|
Asp.Net MVC PDF를 생성하기 위해보기를 얻는 방법 (0) | 2020.10.27 |
JavaScriptSerializer.Deserialize-필드 이름을 변경하는 방법 (0) | 2020.10.27 |
이전 git-commit을 복제하는 방법 (및 git에 대한 추가 질문) (0) | 2020.10.27 |
5 개의 오류 후에 GCC를 중지하도록 지시하는 방법은 무엇입니까? (0) | 2020.10.27 |