Приложение ClickOnce не запускается посредством Процесса. Запустите (“x.abc”) с *.abc, связанного с приложением ClickOnce

Я успешно разработал и развернул приложение ClickOnce, которое регистрирует связанное расширение файла, например *.abc. Когда я нажимаю на названный файл x.abc или если я ввожу x.abc от командной строки запускается приложение ClickOnce, и я могу получить файл через специализированный API. Я могу также запустить приложение программно со следующим кодом:

System.Diagnostics.Process.Start ("x.abc");

Все хорошо работает на моем  поле Windows Vista 64 битов.

Однако, если я пытаюсь сделать точно то же самое в Windows 7 (также 64 бита), у меня есть очень странная проблема. Вот то, что я наблюдаю:

  1. Ручной запуск x.abc путем двойного щелчка по нему от работ Проводника.
  2. Ручной запуск x.abc от работ командной строки.
  3. Process.Start("x.abc") не запускает приложение; однако, объект процесса возвратил шоу, что не было ошибки и что приложение ClickOnce, из которого так или иначе выходят сразу. Но даже a Trace в самом начале ClickOnce никогда не достигается приложение.
  4. Незнакомец все же, Process.Start("x.bat") с файлом x.bat содержа одну строку x.abc не запускает приложение ClickOnce также! То же x.bat запущенный с работ Проводника (конечно).

Попытка проанализировать, что происходит с ProcMon не было очень полезно, поскольку за процессом ClickOnce запуска приложения очень трудно следовать с моей точки зрения. Я наблюдаю rundll32 взятие за работу, но никакое доказательство любого отказа.

Программа, которая делает Process.Start полное доверительное консольное приложение с действительно, ничто не полагает.

Я не вижу то, что изменилось относительно того, как приложения ClickOnce обрабатываются в Windows 7 и почему Process.Start не сделал бы точно того же как запуска файла из Проводника. Стоит, чтобы упомянуть что с помощью большего количества усовершенствованных версий Start метод с ProcessStartInfo и установка UseShellExecute кому: true не помог также.

Запуск cmd с Process.Start и затем попытка запуститься x.abc шоу точно та же проблема. Если я сравниваю параметры среды с a cmd запущенный вручную, я вижу различия в как ProgramFiles определяется (первый указывает на C:\Program Files (x86) тогда как вторые точки к C:\Program Files). Приложения, запущенные с моего приложения.NET, запущены на 32-разрядном уровне (SysWoW64) эмуляции.

Я смог воспроизвести отказ запуска x.abc путем запуска 32-разрядной версии командной строки (то есть, %windir%\SysWoW64\cmd.exe) и затем ввод x.abc при подсказке. Я также нашел ужасное обходное решение, которое должно запустить 64-разрядную командную строку с 32-разрядной среды путем запуска %windir%\Sysnative\cmd.exe /C x.abc вместо x.abc.

Но я использовал бы очевидный способ выполнения его (или сделайте, чтобы представитель Microsoft сказал мне, что это - действительно проблема с Windows 7 и/или ClickOncce и что это будет скоро зафиксировано).

17
задан Peter Mortensen 24 April 2013 в 12:51
поделиться

3 ответа

Похоже, вы создали свое приложение, используя x32 в качестве целевой платформы, что заставляет Process.Start порождать x32-разрядный процесс. И, как я полагаю, Windows 7 хранит ассоциации файлов для 32-битных и 64-битных приложений отдельно.

Если у вас нет COM или неуправляемых 32-битных зависимостей, вы можете попробовать создать свое приложение для целевой платформы «Любая» вместо 'x32'.

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

rundll32.exe dfshim.dll, ShOpenVerbExtension {dce01888-35e8-4df3-af35-cd971f520d8d} %1

Используя Process Monitor , я обнаружил, что 32-разрядная версия не может открыть раздел реестра HKCU \ Software \ Classes \ Wow6432Node \ CLSID \ {dce01888-35e8-4df3-af35-cd971f520d8d} . (64-разрядная версия успешно открывает его по адресу HKCU \ Software \ Classes \ CLSID \ {dce01888-35e8-4df3-af35-cd971f520d8d} .)

Так что для меня это действительно ошибка ClickOnce. На вашем месте я бы использовал этот грязный % WinDir% \ system32 \ cmd.exe / C test.abc обходной путь. (Кажется, что работает - попробовал из диспетчера задач x32.)

Я добавил эту проблему в Microsoft Connect (обновление 2013-02-13: эта ссылка гнилая).

10
ответ дан 30 November 2019 в 14:36
поделиться

That only might start system wide extensions like .bat or even .txt, but it can't always launch correct programs through extensions.

Instead try this API or a similar alternative in .NET:

FindExecutable : shell32.dll Alias : "FindExecutableA" / "FindExecutableW" return type : int parameters : · lpFile Pointer to a null-terminated string specifying a имя файла. Это может быть документ или запускаемый файл. · lpDirectory Указатель на строку с нулевым символом в конце, определяющую каталог по умолчанию. · lpResult Указатель на буфер для получения имени файла, когда функция возвращается. Это имя файла строка с завершающим нулем, определяющая исполняемый файл запускался при «открытии» ассоциация запускается в файле указанный в параметре lpFile.

Это возвращает целое число больше нуля в случае успеха, а значение char будет содержать строку с завершающим нулем , которая указывает на исполняемый файл, который запускает это расширение файла then you can use it like this

System.Diagnostics.Process.Start ("program.exe $:\path\x.abc");

Instead of program.exe, you'll use the result of the API function, and you'll use the path to the file separated with a space just like a command line.

As for the application failure, it might indicate that the program needs administrative rights to run correctly. cmd already got administrative rights, so it can make child applications inherit it, but not windows API. createprocess allows you to use LPSECURITY attributes which can help in launching this program with the correct privileges.

0
ответ дан 30 November 2019 в 14:36
поделиться

Вы пробовали использовать ShellExecute () ; API?

        [DllImport("Shell32.dll",CharSet=CharSet.Auto)]
    public static extern IntPtr ShellExecute(
        IntPtr hwnd, 
        string lpVerb,
        string lpFile, 
        string lpParameters, 
        string lpDirectory,
        int nShowCmd );

ShellExecute(this.Handle,"open","x.abc","","",3);

Вы также можете попробовать функцию Shell (); , которая является частью платформы

0
ответ дан 30 November 2019 в 14:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: