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

San*_*bad 11 c# windows matlab path pathname

我正在用C#和MATLAB制作一个软件,调用另一个软件(CMG)进行一些处理.我的问题是我在我的程序中放置的软件地址只在我的个人计算机上正确,而不是在客户的计算机上(我不知道在他们的计算机上通往CMG软件的路径是什么).

我如何提供地址的一般形式,以使其适用于每台计算机?

以下是我从MATLAB软件调用的路径:

C:\Program Files (x86)\CMG\STARS\2011.10\Win_x64\EXE\st201110.exe
Run Code Online (Sandbox Code Playgroud)

如您所见,它位于驱动器C中,版本为2011.10.因此,如果客户的版本是其他内容并且它安装在其他驱动器上,则此路径没有意义.

Jer*_*son 21

方法1

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

在此输入图像描述

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

在您的情况下,我非常确定将列出CMG STARS,您可以通过遍历查看DisplayName值并获取InstallLocation的所有子项来搜索它.

另请注意,此Uninstall注册表项存在于注册表中的3个位置:
1.在CurrentUser中的
SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall 2.在LocalMachine中的SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
3. SOFTWARE\Wow6432Node\Microsoft\Windows\LocalVersion \在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;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是你怎么称呼它:

string installPath = InstalledApplications.GetApplictionInstallPath(nameOfAppToFind);

要获取nameOfAppToFind,您需要在DisplayName中查看注册表:

在此输入图像描述

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);
}
Run Code Online (Sandbox Code Playgroud)

获得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;
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


您使用的方法(1或2)我建议您保存exe名称的位置,这样您只需执行一次此操作.在我看来,最好使用方法1,因为它更快,并没有创建所有"Windows Installer重新配置产品".事件日志.


使用安装程序的替代方法

如果您的应用程序正在安装,您可以在安装过程中找到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
}
Run Code Online (Sandbox Code Playgroud)

  • +1这是一个彻底的答案!如果OP需要从MATLAB执行此检测,则有相同的函数来查询注册表:http://www.mathworks.com/help/matlab/ref/winqueryreg.html (3认同)