2009-05-26 41 views

Trả lời

88

Lặp lại qua khóa đăng ký "SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Uninstall" dường như cung cấp danh sách đầy đủ các ứng dụng đã cài đặt.

Ngoài ví dụ bên dưới, bạn có thể tìm thấy phiên bản tương tự với những gì tôi đã thực hiện here.

Đây là ví dụ điển hình, bạn sẽ muốn làm điều gì đó để loại bỏ các hàng trống như trong liên kết thứ 2 được cung cấp.

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

Ngoài ra, bạn có thể sử dụng WMI như đã được đề cập:

ManagementObjectSearcher mos = new ManagementObjectSearcher("SELECT * FROM Win32_Product"); 
foreach(ManagementObject mo in mos.Get()) 
{ 
    Console.WriteLine(mo["Name"]); 
} 

Nhưng điều này là khá chậm để thực hiện, và tôi đã nghe nó chỉ có thể cài đặt các chương trình danh sách dưới "AllUsers", mặc dù điều đó có thể không đúng. Nó cũng bỏ qua các thành phần Windows & cập nhật, có thể hữu ích cho bạn.

+20

Cần lưu ý rằng việc sử dụng lớp WMI Win32_Product là một ý tưởng tồi nếu bạn định chạy truy vấn này nhiều lần. Xem bài viết này của Microsoft KB: http://support.microsoft.com/kb/974524/EN-US Vấn đề cốt lõi là (a) Win32_Product thực sự chậm và (b) nó tạo ra một "Windows Installer đã cấu hình lại sản phẩm . " thông báo nhật ký sự kiện cho * mọi sản phẩm được cài đặt trên hệ thống của bạn ... mỗi khi bạn chạy truy vấn. Doh! Bài viết này đề xuất sử dụng lớp Win32reg_AddRemovePrograms ... không có sẵn trừ khi bạn đã cài đặt SMS. Doh! Vì vậy, có thể tốt hơn để gắn bó với truy vấn đăng ký. –

+0

Nhận xét của Simon Gillbee phải là câu trả lời được chấp nhận, hoặc Kirtans! WMI WIN32_Product không phải là cách để đến đây, hãy tin tôi! – bdd

+8

Er, đó là lý do tại sao ví dụ đăng ký là câu trả lời đầu tiên của tôi. WMI đã được trình bày đơn giản như là một giải pháp thay thế, và thậm chí ở đó tôi tuyên bố "điều này là khá chậm hơn để thực hiện" và những hạn chế khác. Đọc câu trả lời ngay từ đầu. ;) – Xiaofu

0

Đặt cược tốt nhất của bạn là sử dụng WMI. Cụ thể là lớp Win32_Product.

+2

Có thể chậm hơn? – Kiquenet

+0

không sử dụng điều này: https://stackoverflow.com/a/46315976/1498669 – Bernhard

1

Lặp lại các phím "HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Uninstall" và kiểm tra giá trị "DisplayName" của chúng.

10

Bạn có thể xem this article. Nó sử dụng registry để đọc danh sách các ứng dụng đã cài đặt.

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

Tôi không muốn toàn bộ danh sách, tôi chỉ cần một số chương trình cài đặt đã chọn để tôi có thể làm gì cho điều đó. Cảm ơn bạn –

1

Tôi có thể đề nghị bạn xem WMI (Windows Management Instrumentation). Nếu bạn thêm tham chiếu System.Management vào dự án C# của mình, bạn sẽ có quyền truy cập vào lớp `ManagementObjectSearcher ', mà có thể bạn sẽ thấy hữu ích.

Có nhiều lớp WMI khác nhau cho Installed Applications, nhưng nếu nó được cài đặt với Windows Installer, thì lớp Win32_Product có lẽ phù hợp nhất với bạn.

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

không sử dụng điều này: https://stackoverflow.com/a/46315976/1498669 – Bernhard

1

Sử dụng API trình cài đặt Windows!

Nó cho phép thực hiện liệt kê đáng tin cậy của tất cả các chương trình. Registry không đáng tin cậy, nhưng WMI là nặng.

+0

chắc chắn là trọng lượng nặng - nếu chạy liên tục, người ta sẽ thấy hiệu suất giảm như trọng lượng nặng. nếu tính năng của ứng dụng của tôi tùy thuộc vào ứng dụng khác và biết nếu được cài đặt đúng cách, tôi chỉ cần khóa đăng ký cho 32 hoặc 64 chỉ khi ứng dụng có sẵn trong 64 bit) nếu tôi phải sử dụng wmi, tôi sẽ giới hạn chỉ sử dụng một lần trong một ứng dụng thông qua một thủ thuật bất động sản thông minh. – gg89

1

Tôi đã sử dụng cách tiếp cận của Nicks - Tôi cần kiểm tra xem Công cụ từ xa cho Visual Studio có được cài đặt hay không, có vẻ hơi chậm nhưng trong một chuỗi riêng biệt điều này là tốt cho tôi. - ở đây đang mở rộng của tôi:

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

nó đáng chú ý là lớp Win32_Product WMI đại diện cho các sản phẩm như chúng được cài đặt bởi Windows Installer [http://msdn.microsoft.com/en-us/library/aa394378%28v=vs.85%29.aspx].not mọi ứng dụng sử dụng các cửa sổ cài đặt

tuy nhiên "SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Uninstall "đại diện cho các ứng dụng cho 32 bit. Đối với 64 bit, bạn cũng cần phải đi qua "HKEY_LOCAL_MACHINE \ SOFTWARE \ Wow6432Node \ Microsoft \ Windows \ CurrentVersion \ Uninstall" và vì không phải mọi phần mềm đều có phiên bản 64 bit, tổng số ứng dụng được cài đặt là một tổ hợp phím trên cả hai vị trí có "UninstallString" Giá trị với chúng.

nhưng các tùy chọn tốt nhất vẫn giữ nguyên .Truy cập khóa đăng ký là cách tiếp cận tốt hơn vì mọi ứng dụng đều có mục nhập trong sổ đăng ký [kể cả ứng dụng trong Windows Installer]. bạn sẽ không biết mục nhập Ứng dụng. Ngược lại, việc thay đổi HKEY_Classes_ROOT \ Installers trở nên phức tạp hơn vì nó được liên kết với các vấn đề cấp phép như văn phòng Microsoft hoặc các sản phẩm khác. để có giải pháp mạnh mẽ hơn, bạn luôn có thể kết hợp thay thế đăng ký với WMI.

+0

Win32_Sản phẩm là điều xấu: https://gregramsey.net/2012/02/20/win32_product-is-evil/ – Mick

4

Tôi đồng ý rằng việc đếm qua khóa đăng ký là cách tốt nhất.

Note, tuy nhiên, rằng chìa khóa nhất định, @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", sẽ liệt kê tất cả các ứng dụng trong một cài đặt Windows 32-bit, và các ứng dụng 64-bit trong Windows cài đặt 64-bit.

Để xem các ứng dụng 32 bit được cài đặt trên bản cài đặt Windows 64 bit, bạn cũng cần phải liệt kê khóa @"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall".

+0

Bạn có chắc chắn về điều này không? Trên Windows 10 Enterprise 64bit của tôi, hai danh sách trông giống nhau và các ứng dụng x86 hiển thị trong cả hai. –

0

Yêu cầu của tôi là kiểm tra xem phần mềm cụ thể có được cài đặt trong hệ thống của tôi hay không. Giải pháp này hoạt động như mong đợi. Nó có thể giúp bạn. Tôi đã sử dụng ứng dụng cửa sổ trong C# với studio trực quan 2015.

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; 

     } 
Các vấn đề liên quan