Как правильно найти место установки EXE?

Я делаю программное обеспечение на C # и MATLAB, которое вызывает другое программное обеспечение (CMG) для некоторой обработки. Моя проблема в том, что адрес программного обеспечения, который я указал в своей программе, правильный только на моем персональном компьютере, а не на компьютерах клиентов (я не знаю, какой путь к программному обеспечению CMG будет на их компьютере).

Как я могу предоставить общую форму адреса, чтобы он работал на каждом компьютере?

Ниже приведен путь, который я вызываю из своего программного обеспечения MATLAB:

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

Как вы видите, он находится на диске C и имеет версию 2011.10. Так что, если у клиента другая версия и она установлена ​​на других дисках, этот путь не имеет смысла.


person Sandbad    schedule 28.10.2014    source источник
comment
Должен быть способ получить эту информацию из реестра, но я точно не знаю, как ее получить.   -  person Kamran Bigdely    schedule 28.10.2014
comment
вы также можете отобразить диалоговое окно uigetfile (или его эквивалент в C#) чтобы предложить пользователю выбрать исполняемый файл CMG самостоятельно.   -  person Amro    schedule 01.11.2014
comment
что касается идеи реестра, это зависит от приложения, но вы можете проверить этот вопрос: stackoverflow.com/q/429738/97160   -  person Amro    schedule 01.11.2014


Ответы (1)


Способ 1

Разделы реестра SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall содержат список мест, где установлено большинство приложений:

введите здесь описание изображения

Примечание. В нем перечислены не все приложения EXE на ПК, поскольку некоторые из них не требуют установки.

В вашем случае я почти уверен, что CMG STARS будет в списке, и вы сможете найти его, перебирая все подразделы, просматривая значение DisplayName и извлекая InstallLocation. .

Также обратите внимание, что этот раздел реестра Uninstall существует в 3 местах реестра:
1. SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall внутри CurrentUser
2. SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall внутри LocalMachine
3. ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ\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;
    }
}

Вот как вы это называете:

string installPath = InstalledApplications.GetApplictionInstallPath(nameOfAppToFind);

Чтобы получить nameOfAppToFind, вам нужно посмотреть в реестре DisplayName:

введите описание изображения здесь

ССЫЛКА: я изменил приведенный выше код из здесь, чтобы вернуть путь установки.


Способ 2

Вы также можете использовать .Net DLL для управления системой, чтобы получить InstallLocation, хотя это намного медленнее и создает сообщения журнала событий «Установщик Windows изменил конфигурацию продукта» для каждого установленного продукта в вашей системе.

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 для инвентаризации продуктов и исправлений:

Перечисление продуктов
Используйте MsiEnumProductsEx для перечисления приложений установщика Windows, установленных в системе. Эта функция может найти все установки приложений для каждого компьютера и пользователя (управляемые и неуправляемые) для текущего пользователя и других пользователей в системе. Используйте параметр dwContext, чтобы указать контекст установки, который необходимо найти. Вы можете указать любой один или любую комбинацию возможных контекстов установки. Используйте параметр szUserSid, чтобы указать пользовательский контекст искомых приложений.

Во время установки вы найдете путь к exe-файлу CMG STARS и сохраните ключ реестра со значением.

Я обсуждаю использование этого подхода сохранение пути установки EXE в реестре для обновления приложений здесь .


Подсказка

Как упоминалось в комментариях, стоит выполнить поиск в реестре имени EXE-файла st201110.exe и посмотреть, предоставляют ли уже авторы приложения CMG STAR эту информацию в ключе реестра, который вы можете доступ напрямую.


План б

Если ничего не помогает, предоставьте пользователю FileOpenDialog и попросите его указать путь к exe вручную.


Что делать, если стороннее приложение удалено или обновлено?

Я упомянул, что нужно хранить путь установки и имя исполняемого файла в реестре (или базе данных, файле конфигурации и т. д.), и вы всегда должны проверять существование исполняемого файла, прежде чем делать какие-либо внешние вызовы, например:

if (!File.Exists(installPath + exeName))
{
//Run through the process to establish where the 3rd party application is installed
}
person Jeremy Thompson    schedule 01.11.2014
comment
@JeremyThompson Метод № 1 обнаруживает, что приложение установлено для меня, но нет ключа InstallLocation, из которого можно получить exe. Ключ DisplayIcon имеет путь exe, но я не знаю, надежно ли его использовать? - person Heinrich; 10.10.2015
comment
Этот ответ во многом зависит от программного обеспечения, которое вы пытаетесь найти - это не универсальное решение, поэтому я включаю метод planB. Использование DisplayIcon должно быть приемлемым, если это то, что доступно, и разработчики редко меняют такие вещи в своих установщиках. Интересно, что приложение, которое вы пытаетесь найти, использует DisplayIcon, возможно, они используют его, чтобы запретить/разрешить людям изменять значок приложения. - person Jeremy Thompson; 11.10.2015
comment
Так как же использовать первый метод, чтобы определить, установлено ли приложение, а также отобразить его местоположение? - person Burgo855; 12.06.2018
comment
@JeremyThompson Я хотел нажать на голосование, извините, промахнулся. Будет обновляться по прошествии 16 часов. - person Burgo855; 13.06.2018
comment
@ Burgo855 Я отредактировал ответ, чтобы показать, как его использовать. Поскольку он отредактирован, вы можете изменить свой голос. Ваше здоровье - person Jeremy Thompson; 13.06.2018