66

C #코드를 사용하여 시스템에 설치된 응용 프로그램을 얻는 방법은 무엇입니까?

10 답변


92

레지스트리 키 "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 구성 요소 & 업데이 트가 당신을 위해 편리 할 수 있습니다.


  • 이 쿼리를 반복적으로 실행하려면 WMI Win32_Product 클래스를 사용하는 것이 좋지 않다는 점에 유의해야합니다. 이 Microsoft KB 문서를 참조하십시오.support.microsoft.com/kb/974524/EN-US핵심 문제는 (a) Win32_Product가 실제로 느리고 (b) "Windows Installer가 제품을 재구성했습니다." 에 대한 이벤트 로그 메시지...마다시스템에 설치된 제품 ... 쿼리를 실행할 때마다. 도! 이 기사에서는 SMS를 설치하지 않은 한 Win32reg_AddRemovePrograms 클래스를 사용하는 것이 좋습니다. 도! 따라서 레지스트리 쿼리를 사용하는 것이 좋습니다. - Simon Gillbee
  • Simon Gillbee의 댓글은 허용 된 답변 또는 Kirtans이어야합니다. WMI WIN32_Product는 여기에있는 길은 아니지만 나를 믿어 라! - bdd
  • 어, 그 이유는 레지스트리 예제가 내 대답은 첫 번째 이유입니다. WMI는 단순히 대안 솔루션으로 제시되었으며 심지어 거기에 "나는 실행하기가 다소 느리다"라고 말합니다. 및 기타 단점. 처음부터 답을 읽으십시오. ;) - Xiaofu
  • 좀 이상하지만 프로그램을 제거하고 다시 설치 한 다음 레지스트리 키를 사용하여 찾으십시오. 컴퓨터를 다시 시작하지 않는 한 할 수 없습니다. - Yar
  • 내 자신의 질문에 대답하려면 :stackoverflow.com/questions/27838798/…64 비트와 32 비트를 쿼리해야 할 수도 있습니다. - Robert Koernke

10

좀 봐봐.이 기사. 레지스트리를 사용하여 설치된 응용 프로그램 목록을 읽습니다.

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)
                { }
            }
        }
    }
}


  • 전체 목록을 필요로하지 않으므로 일부 설치 프로그램 만 필요하므로 무엇을 할 수 있습니까? 고맙습니다 - Dhru 'soni

5

Win32_Product WMI 클래스가 Windows Installer에 의해 설치된대로 제품을 나타냅니다.http://msdn.microsoft.com/en-us/library/aa394378%28v=vs.85%29.aspx].not모든 응용 프로그램은 Windows Installer를 사용합니다.

그러나 "SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Uninstall"은 32 비트 응용 프로그램을 나타냅니다. 64 비트의 경우 "HKEY_LOCAL_MACHINE \ SOFTWARE \ WOW6432Node \ Microsoft \ Windows \ CurrentVersion \ Uninstall"을 트래버스해야하며 모든 소프트웨어가 64 비트 버전이 아니므로 설치된 전체 응용 프로그램은 "UninstallString" 그들과 함께 가치.

가장 좋은 옵션은 동일하게 유지됩니다. 모든 응용 프로그램이 레지스트리 [Windows Installer의 항목 포함]에 항목을 가지고 있기 때문에 .traverse 레지스트리 키는 더 나은 접근 방법입니다. 레지스트리 방법은 누군가가 해당 키를 제거한 것처럼 안전하지 않은 경우 알 수 없습니다. HKEY_Classes_ROOT \ Installers를 변경하는 것은 Microsoft 사무실이나 다른 제품과 같은 라이선스 문제와 관련되어 있기 때문에 더 까다 롭습니다. 보다 견고한 솔루션을 위해 항상 레지스트리 대안을 WMI와 결합 할 수 있습니다.



5

나는 레지스트리 키를 통해 열거하는 것이 최선의 방법이라는 데 동의합니다.

노트그러나, 주어진 열쇠는,@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", 32 비트 Windows 설치의 모든 응용 프로그램 및 Windows 64 비트 설치의 64 비트 응용 프로그램을 나열합니다.

Windows 64 비트 설치에 설치된 32 비트 응용 프로그램도 보려면 키를 열거해야합니다@"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall".


  • 이거 확실하니? 내 Windows 10 Enterprise 64 비트에서는 두 목록이 비슷하게 보이고 x86 응용 프로그램이 모두 표시됩니다. - Florian Straub

1

"HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Uninstall"키를 반복하고 "DisplayName"값을 확인하십시오.


1

당신이 WMI (Windows Management Instrumentation). System.Management 참조를 C #프로젝트에 추가하면 'ManagementObjectSearcher'클래스에 액세스 할 수 있습니다.이 클래스는 아마도 유용 할 것입니다.

다양한 WMI 클래스가 있습니다.설치된 응용 프로그램, Windows Installer로 설치 한 경우에는 Win32_Product 클래스가 가장 적합 할 수 있습니다.

ManagementObjectSearcher s = new ManagementObjectSearcher("SELECT * FROM Win32_Product");



1

Windows Installer API를 사용하십시오!

모든 프로그램을 신뢰할 수있는 열거 형으로 만들 수 있습니다. 레지스트리가 안정적이지는 않지만 WMI는 중량입니다.


  • 확실히 무거운 무게 - 반복적으로 달리면, 하나는 무거운 무게처럼 성능 저하를 볼 수 있습니다. 내 응용 프로그램의 기능이 다른 응용 프로그램에 종속되어 있고 제대로 설치되어 있는지 확인하는 경우, 응용 프로그램이 64 비트에서도 사용할 수있는 경우에만 32 또는 64 용 제거 레지스트리 키가 필요합니다.) 반면에 wmi를 사용해야하는 경우 똑똑한 속성 트릭을 통해 응용 프로그램을 사용하는 동안 한 번만 사용하도록 제한됩니다. - gg89

1

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;
    }


0

최선의 방법은 사용하는 것입니다.WMI. 특히Win32_Product수업.



-1

내 요구 사항은 특정 소프트웨어가 내 시스템에 설치되어 있는지 확인하는 것입니다. 이 솔루션은 예상대로 작동합니다. 도움이 될지도 모릅니다. 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;

        }


  • foreach (key.GetSubKeyNames ()의 string subkey_name) < - null 일 경우 여기를 확인하지 않습니다. - Burgo855

연결된 질문


관련된 질문

최근 질문