ClickOnce アプリケーションに *.abc が関連付けられている Process.Start(“x.abc”) を通じて ClickOnce アプリケーションが起動しない
-
19-09-2019 - |
質問
関連するファイル拡張子を登録する ClickOnce アプリケーションの開発と展開に成功しました。たとえば、 *.abc
. 。という名前のファイルをクリックすると、 x.abc
または入力すると x.abc
コマンド プロンプトから ClickOnce アプリケーションが起動し、専用 API を通じてファイルを取得できます。次のコードを使用して、プログラムでアプリケーションを起動することもできます。
System.Diagnostics.Process.Start ("x.abc");
私の Windows Vista 64 ビット ボックスではすべて正常に動作します。
ただし、まったく同じことを Windows 7 (64 ビット版) で実行しようとすると、非常に奇妙な問題が発生します。私が観察したことは次のとおりです。
- 手動で開始
x.abc
エクスプローラーからダブルクリックすると動作します。 - 手動で開始
x.abc
コマンドプロンプトからは機能します。 Process.Start("x.abc")
アプリケーションは起動しません。ただし、返されたプロセス オブジェクトには、エラーはなく、ClickOnce アプリケーションが何らかの理由ですぐに終了したことが示されています。しかし、たとえTrace
ClickOnce アプリケーションの最初の部分には到達しません。- まだ見知らぬ人ですが、
Process.Start("x.bat")
ファイル付きx.bat
単一行を含むx.abc
ClickOnce アプリケーションも起動しません。同じx.bat
エクスプローラーの作品からスタートしました(もちろん)。
で何が起こったのかを分析しようとしています ProcMon
私の観点からすると、アプリケーションを起動する ClickOnce プロセスに従うのが非常に難しいため、あまり役に立ちませんでした。私は観察します rundll32
作業に取り掛かりましたが、失敗した形跡はありません。
を行っているプログラムは、 Process.Start
は完全に信頼できるコンソール アプリケーションで、特別なことは何もありません。
Windows 7 での ClickOnce アプリケーションの処理方法に関して何が変わったのか、またその理由がわかりません。 Process.Start
エクスプローラーからファイルを起動するのとまったく同じことはできません。より高度なバージョンの Start
を使用したメソッド ProcessStartInfo
そして設定 UseShellExecute
に true
どちらも役に立ちませんでした。
起動 cmd
と Process.Start
そして起動しようとしています x.abc
まったく同じ問題を示しています。環境設定を比較してみると、 cmd
手動で開始しましたが、方法の違いがわかります ProgramFiles
が定義されています (最初の定義は C:\Program Files (x86)
一方、2番目は次を指します C:\Program Files
)。.NET アプリケーションから起動されたアプリケーションは、32 ビット エミュレーション層 (SysWoW64) で起動されます。
の起動失敗を再現できました x.abc
32 ビット バージョンのコマンド プロンプトを起動します (つまり、 %windir%\SysWoW64\cmd.exe
) を入力してから、 x.abc
プロンプトで。また、醜い回避策も見つけました。それは、 を起動して 32 ビット環境から 64 ビットのコマンド プロンプトを起動することです。 %windir%\Sysnative\cmd.exe /C x.abc
の代わりに x.abc
.
しかし、私はそれを行うクリーンな方法を使用することを望んでいます (または、Microsoft の担当者に、これは実際に Windows 7 および/または ClickOncce の問題であり、すぐに修正されると教えてもらいます)。
解決 3
私は、実装が容易である.BATベースのソリューション、を作ってみました。そして、あなたは、単に同じ名前のファイルを置くが、同じフォルダに*.abc
拡張子を持つ、そして、代わりにバッチファイルを実行し、あなたが*.bat
ファイルに関連付けられたClickOnceアプリケーションを起動したいと言います。ここでは、バッチスクリプトがあります:
if exist "%windir%\sysnative\cmd.exe" goto :mode64bit
rem For a file named "C:\foo\xyz.bat", this will generate the corresponding
rem "C:\foo\xyz.abc" file, built as the concatenation of the drive (%~d0),
rem the folder (%~p0) and the file name (%~n0), plus ".abc":
"%~d0%~p0%~n0.abc"
goto :end
:mode64bit
rem When running in a 32-bit emulation environment on a real 64-bit system,
rem start the 64-bit version of CMD.EXE, and make if start the ".abc" file
rem for us:
C:\Windows\sysnative\cmd.exe /c "%~d0%~p0%~n0.xgen"
:end
...これは
*.abc
ファイルの呼び出し元に直接実装することができ、時にはバッチファイルを移行するのに役立ちます 他のヒント
Process.Start
は、X32ビットのプロセスを生成せ、ターゲットプラットフォームとして「X32」を使用してアプリケーションをビルドしてきたように、に見えます。そして私は、32ビットおよび64ビットのアプリケーションのためのWindows 7店舗のファイルの関連付けを推測として別途ます。
あなたはCOMまたは管理対象外の32ビットの依存関係を持っていない場合は、あなたの代わりに「X32」の「任意」ターゲットプラットフォーム用にアプリケーションを構築しようとすることができます。
私は(GUIDは、アプリケーションごとに固有である)さらにいくつかの調査とのClickOnceインストーラは、関連するファイル拡張子に対して次のオープン動詞を作成することが判明します:
rundll32.exe dfshim.dll, ShOpenVerbExtension {dce01888-35e8-4df3-af35-cd971f520d8d} %1
プロセスモニタを使用し、私は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のタスクマネージャから試してみました)
私は<ストライキ> にこの問題を追加しましたマイクロソフト接続する ストライキが>(2013年2月13日更新:そのリンクが腐っている)。
は、のの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);
また、のシェルを()しようとすることができ; のフレームワークの一部である関数
これは、次のようなシステム全体の拡張機能を開始する可能性があるだけです .bat
あるいは .txt
, ただし、拡張機能を介して常に正しいプログラムを起動できるわけではありません。
代わりに、この API または同様の代替手段を試してください。 。ネット:
FindExecutable : シェル32.dll エイリアス: 「実行可能ファイルの検索」 / 「実行可能ファイルの検索」 戻り値の型: 整数 パラメーター : · lpファイル ファイル名を指定するヌル終端文字列へのポインタ。これは、ドキュメントまたは実行可能ファイルです。 · lpディレクトリ null で終わる文字列へのポインタで、 default ディレクトリです。 · lp結果 ファイル名を受け取るバッファへのポインタは、 関数が戻ります。このファイル名は null で終わる文字列で、 実行可能ファイルは「開く」ときに開始されます アソシエーションはファイルに対して実行されます lpFile パラメーターで指定します。
成功した場合、これはゼロより大きい整数を返し、char 値には NULL で終わる文字列 これは、このファイル拡張子を起動する実行可能ファイルを指します その後、次のように使用できます
System.Diagnostics.Process.Start ("program.exe $:\path\x.abc");
の代わりに program.exe
, 、API 関数の結果を使用し、コマンド ラインと同じようにスペースで区切られたファイルへのパスを使用します。
アプリケーションの失敗に関しては、プログラムを正しく実行するには管理者権限が必要であることを示している可能性があります。 cmd
すでに管理者権限を取得しているため、子アプリケーションにそれを継承させることはできますが、Windows API には継承させません。 createprocess
使用できるようにします LPSセキュリティ このプログラムを正しい権限で起動するのに役立つ属性。