查找是否安装了第三方软件,安装path和EXE的名称?

我在C#和MATLAB中调用另一个软件(CMG)来做一些处理的软件。 我的问题是,我在我的程序中放入的软件的地址在我的个人计算机上是正确的,而不是在客户的计算机上(我不知道在他们的计算机上CMG软件的path是什么)。

我怎样才能提供一个通用的地址forms,以使其在每台计算机上工作?

以下是我从MATLAB软件中调用的path:

C:\Program Files (x86)\CMG\STARS\2011.10\Win_x64\EXE\st201110.exe 

正如你看到它是在驱动器C和版本是2011.10。 所以,如果客户的版本是其他的东西,并且安装在其他驱动器上,这个path是没有意义的。

方法1

注册表项SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Uninstall提供了大多数应用程序安装位置的列表:

在这里输入图像说明

注意:它没有列出所有的EXE应用程序在PC上,因为有些不需要安装。

在你的情况下,我很确定,CMG STARS将被列出,你将能够遍历所有查看DisplayName值的子项并获取InstallLocation来搜索它。

另请注意,此卸载注册表项存在于注册表中的3个位置:
1. SOFTWARE \ Microsoft \ Windows \ CurrentVersion \卸载CurrentUser内
2. SOFTWARE \ Microsoft \ Windows \ CurrentVersion \在LocalMachine内部卸载
3. SOFTWARE \ Wow6432Node \ Microsoft \ Windows \ CurrentVersion \在LocalMachine中卸载

这是一个返回应用程序安装位置的类:

 using Microsoft.Win32; public static class InstalledApplications { public static string GetApplictionInstallPath(string nameOfAppToFind) { string installedPath; string keyName; // search in: CurrentUser keyName = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"; installedPath = ExistsInSubKey(Registry.CurrentUser, keyName, "DisplayName", nameOfAppToFind); if (!string.IsNullOrEmpty(installedPath)) { return installedPath; } // search in: LocalMachine_32 keyName = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"; installedPath = ExistsInSubKey(Registry.LocalMachine, keyName, "DisplayName", nameOfAppToFind); if (!string.IsNullOrEmpty(installedPath)) { return installedPath; } // search in: LocalMachine_64 keyName = @"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"; installedPath = ExistsInSubKey(Registry.LocalMachine, keyName, "DisplayName", nameOfAppToFind); if (!string.IsNullOrEmpty(installedPath)) { return installedPath; } return string.Empty; } private static string ExistsInSubKey(RegistryKey root, string subKeyName, string attributeName, string nameOfAppToFind) { RegistryKey subkey; string displayName; using (RegistryKey key = root.OpenSubKey(subKeyName)) { if (key != null) { foreach (string kn in key.GetSubKeyNames()) { using (subkey = key.OpenSubKey(kn)) { displayName = subkey.GetValue(attributeName) as string; if (nameOfAppToFind.Equals(displayName, StringComparison.OrdinalIgnoreCase) == true) { return subkey.GetValue("InstallLocation") as string; } } } } } return string.Empty; } } 

REF:我从这里修改了上面的代码来返回安装路径。


方法2

您也可以使用System Management .Net DLL来获取InstallLocation,虽然速度很慢,并且会为系统上的每个已安装产品创建“Windows Installer重新配置产品”事件日志消息。

 using System.Management; ManagementObjectSearcher mos = new ManagementObjectSearcher("SELECT * FROM Win32_Product"); foreach (ManagementObject mo in mos.Get()) { Debug.Print(mo["Name"].ToString() + "," + mo["InstallLocation"].ToString() + Environment.NewLine); } 

获取EXE的名字

上述两种方法都不能告诉你可执行文件的名字,但是通过迭代安装路径中的所有文件并使用我在这里讨论的技术来查看文件属性来检测EXE的正确性文件说明 ,例如:

 private string GetFileExeNameByFileDescription(string fileDescriptionToFind, string installPath) { string exeName = string.Empty; foreach (string filePath in Directory.GetFiles(installPath, "*.exe")) { string fileDescription = GetSpecificFileProperties(filePath, 34).Replace(Environment.NewLine, string.Empty); if (fileDescription == fileDescriptionToFind) { exeName = GetSpecificFileProperties(filePath, 0).Replace(Environment.NewLine, string.Empty); break; } } return exeName; } 

在这里输入图像说明


无论使用哪种方法(1或2),我建议您保存exe名称的位置,以便只执行一次该操作。 在我看来,它更好地使用方法1,因为它的速度更快,并且不会创建所有“Windows安装程序重新配置产品”。 事件日志。


使用安装程序的替代方法

如果正在安装应用程序,则可以在安装过程中找到CMG STARS所在的位置使用Windows Installer清点产品和修补程序 :

列举产品
使用MsiEnumProductsEx函数来枚举安装在系统中的Windows Installer应用程序。 此功能可以查找系统中当前用户和其他用户的所有每台计算机安装和每个用户的应用程序安装(托管和非托管)。 使用dwContext参数指定要找到的安装上下文。 您可以指定任何一个或任何可能的安装上下文的组合。 使用szUserSid参数指定要找到的应用程序的用户上下文。

在安装过程中,您可以找到CMG STARS的exe路径,并使用该值保存注册表项。

我在这里讨论使用这种方法在注册表中保存EXE的安装路径来更新应用程序 。


小费

正如评论中所提到的,值得在注册表中搜索EXE的名称st201110.exe,并查看CMG STAR应用程序的作者是否已经在可直接访问的注册表项中提供此信息。


B计划

如果一切都失败了,用户使用FileOpenDialog,让他们手动指定exe的路径。


如果第三方应用程序被卸载或升级会怎么样?

我提到要在注册表(或数据库,配置文件等)中存储安装路径和exe名称,并且在进行任何外部调用之前,应该始终检查exe文件是否存在,例如:

 if (!File.Exists(installPath + exeName)) { //Run through the process to establish where the 3rd party application is installed }