简体   繁体   English

如何使用C#查找第三方应用程序(如Google Earth)的安装目录?

[英]How to find the installation directory of a third-party application, such as Google Earth, using C#?

I have the following code fragment that starts a Google Earth process using a hardcoded path: 我有以下代码片段,它使用硬编码路径启动Google Earth进程:

var process =
    new Process
        {
            StartInfo =
                {
                    //TODO: Get location of google earth executable from registry
                    FileName = @"C:\Program Files\Google\Google Earth\googleearth.exe",
                    Arguments = "\"" + kmlPath + "\""
                }
        };
process.Start();

I want to programmatically fetch the installation location of googleearth.exe from somewhere (most likely the registry). 我想以编程方式从某个地方(很可能是注册表)获取googleearth.exe的安装位置。

From the example given you can gauge that I'm actually trying to pass a KML file to Google Earth. 从给出的示例中,您可以判断我实际上是在尝试将KML文件传递给Google地球。 Because of this, the simplest way of resolving this problem is relying on the file association of KML with Google Earth and using the following as a replacement for the entire example: 因此,解决此问题的最简单方法是依靠KML与Google Earth的文件关联,并使用以下内容替代整个示例:

Process.Start(kmlPath);

This was found by reviewing the answers to this question. 通过回顾这个问题的答案找到了这个

Obviously if you're opening a specific file associated with the program then launching it via the file is preferable (for instance, the user might have a program associated with the file type they prefer to use). 显然,如果您打开与该程序关联的特定文件,则最好通过该文件启动它(例如,用户可能有一个与他们喜欢使用的文件类型相关联的程序)。

Here is a method I've used in the past to launch an application associated with a particular file type, but without actually opening a file. 这是我过去用来启动与特定文件类型相关联的应用程序但不实际打开文件的方法。 There may be a better way to do it. 可能有更好的方法来做到这一点。

static Regex pathArgumentsRegex = new Regex(@"(%\d+)|(""%\d+"")", RegexOptions.ExplicitCapture);
static string GetPathAssociatedWithFileExtension(string extension)
{
    RegistryKey extensionKey = Registry.ClassesRoot.OpenSubKey(extension);
    if (extensionKey != null)
    {
        object applicationName = extensionKey.GetValue(string.Empty);
        if (applicationName != null)
        {
            RegistryKey commandKey = Registry.ClassesRoot.OpenSubKey(applicationName.ToString() + @"\shell\open\command");
            if (commandKey != null)
            {
                object command = commandKey.GetValue(string.Empty);
                if (command != null)
                {
                    return pathArgumentsRegex.Replace(command.ToString(), "");
                }
            }
        }
    }
    return null;
}

Sometimes though there are cases when you want to launch a specific program without opening a file. 有时虽然有时您想在不打开文件的情况下启动特定程序。 Usually (hopefully) the program has a registry entry with the install location. 通常(希望)程序有一个带有安装位置的注册表项。 Here is an example of how to launch Google Earth in such a manner. 以下是如何以这种方式启动Google地球的示例。

private static string GetGoogleEarthExePath()
{
    RegistryKey googleEarthRK = Registry.CurrentUser.OpenSubKey(@"Software\Google\Google Earth Plus\");
    if (googleEarthRK != null)
    {
        object rootDir = googleEarthRK.GetValue("InstallLocation");
        if (rootDir != null)
        {
            return Path.Combine(rootDir.ToString(), "googleearth.exe");
        }
    }

    return null;
}

This would also work: (C# code) 这也可以:(C#代码)

        Type type = Type.GetTypeFromProgID("WindowsInstaller.Installer");
        Installer msi = (Installer)Activator.CreateInstance(type);
        foreach (string productcode in msi.Products)
        {
            string productname = msi.get_ProductInfo(productcode, "InstalledProductName");
            if (productname.Contains("Google Earth"))
            {
                string installdir = msi.get_ProductInfo(productcode, "InstallLocation");
                Console.WriteLine("{0}: {1} @({2})", productcode, productname, installdir);
            }
        }

Here's a C++ version I just had to write. 这是我刚刚编写的C ++版本。 Taken directly from ICR's C# version. 直接取自ICR的C#版本。

void PrintString(CString string)
{
    std::wcout << static_cast<LPCTSTR>(string) << endl;
}

CString GetClassesRootKeyValue(const wchar_t * keyName)
{
    HKEY hkey;
    TCHAR keyNameCopy[256] = {0};
    _tcscpy_s(keyNameCopy, 256, keyName);
    BOOL bResult = SUCCEEDED(::RegOpenKey(HKEY_CLASSES_ROOT, keyNameCopy, &hkey));
    CString hkeyValue = CString("");
    if (bResult) {
        TCHAR temporaryValueBuffer[256];
        DWORD bufferSize = sizeof (temporaryValueBuffer);
        DWORD type;
        bResult = SUCCEEDED(RegQueryValueEx(hkey, _T(""), NULL, &type, (BYTE*)temporaryValueBuffer, &bufferSize)) && (bufferSize > 1);
        if (bResult) {
            hkeyValue = CString(temporaryValueBuffer);
        }
        RegCloseKey(hkey);
        return hkeyValue;
    }
    return hkeyValue;
}


int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
    int nRetCode = 0;

    // initialize MFC and print and error on failure
    if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
    {
        // TODO: change error code to suit your needs
        _tprintf(_T("Fatal Error: MFC initialization failed\n"));
        nRetCode = 1;
    }
    else
    {

        CString dwgAppName = GetClassesRootKeyValue(_T(".dwg"));
        PrintString(dwgAppName);

        dwgAppName.Append(_T("\\shell\\open\\command"));
        PrintString(dwgAppName);

        CString trueViewOpenCommand = GetClassesRootKeyValue(static_cast<LPCTSTR>(dwgAppName));
        PrintString(trueViewOpenCommand);

        //  Shell open command usually ends with a "%1" for commandline params.  We don't want that,
        //  so strip it off.
        int firstParameterIndex = trueViewOpenCommand.Find(_T("%"));
        PrintString(trueViewOpenCommand.Left(firstParameterIndex).TrimRight('"').TrimRight(' '));


        cout << "\n\nPress <enter> to exit...";
        getchar();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在包含第三方DLL文件的同时部署C#应用程序? - How to deploy a C# application while including third-party DLL files? 如何使用C#在Outlook加载项中使用第三方dll? - how to use third-party dll in outlook add-in using c#? 如何仅在 C# 中使用 WhatsApp API 发送 WhatsApp 消息(不应使用任何第三方 API 链接) - how to send WhatsApp message using WhatsApp API only in C#(should not use any third-party API links) C#查找应用程序的安装目录 - C# find installation directory of application Visual Studio 中是否有针对 C# 的第三方分析工具? - Are there any third-party profiling tools for C# in Visual Studio? 需要由第三方实现的C#接口 - C# Interface that needs to be implemented by a third-party C#-将类似结构的行为转换为第三方函数 - C# - behavior of similar structures into a third-party function 检查第三方应用程序安装 - Check For Third-Party App Installation 如何正确地将字符串从非托管第三方dll返回到C#? - How do I properly return a string from an unmanaged third-party dll to C#? 如何在我的客户端应用程序中处理第三方站点上的recaptcha - How to handle recaptcha on third-party site in my client application
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM