كيفية العثور على دليل التثبيت من تطبيق طرف ثالث، مثل برنامج Google Earth، باستخدام C #؟

StackOverflow https://stackoverflow.com/questions/191250

  •  08-07-2019
  •  | 
  •  

سؤال

ولدي جزء التعليمات البرمجية التالية التي يبدأ عملية جوجل إيرث باستخدام مسار ضمني:

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();

وأريد أن جلب موقع التثبيت من برمجيا <م> برنامج GoogleEarth.exe من مكان ما (على الأرجح التسجيل).

هل كانت مفيدة؟

المحلول

وبالطبع اذا كنت فتح ملف معين المرتبطة بالبرنامج ثم تطلق عليه عبر الملف هو الأفضل (على سبيل المثال، قد يكون لدى المستخدم على البرنامج المقترن نوع الملف أنها تفضل استخدام).

وهنا هو أسلوب لقد استعملت في الماضي لإطلاق التطبيق المقترن نوع ملف معين، ولكن من دون فتح ملف في الواقع. قد يكون هناك طريقة أفضل للقيام بذلك.

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

وعلى الرغم من بعض الأحيان هناك حالات عندما تريد إطلاق برنامج معين دون فتح الملف. عادة (أمل) والبرنامج يحتوي على إدخال التسجيل مع موقع التثبيت. وفيما يلي مثال لكيفية تشغيل برنامج Google Earth في مثل هذه الطريقة.

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

نصائح أخرى

ومن المثال الذي يمكنك قياس أنني في الواقع محاولة لتمرير ملف KML إلى برنامج Google Earth. وبسبب هذا، وأبسط طريقة لحل هذه المشكلة هو الاعتماد على اقتران ملف KML لمع برنامج Google Earth واستخدام ما يلي كبديل للمثال كامل:

Process.Start(kmlPath);

وكان العثور على هذا من خلال مراجعة إجابات ل هذا المسألة.

وهذا من شأنه أن يعمل أيضا: (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);
            }
        }

وإليك C ++ الإصدار أود فقط أن أكتب. مأخوذة مباشرة من 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 مع الإسناد
لا تنتمي إلى StackOverflow
scroll top