Google Chrome が ShellExecute() を壊した?
-
02-07-2019 - |
質問
私は何年もの間、アプリケーション内からデフォルトの Web ブラウザを起動するために ShellExecute() API を使用してきました。このような:
ShellExecute( hwnd, _T("open"),
_T("http://www.winability.com/home/"),
NULL, NULL, SW_NORMAL );
Google が Chrome ブラウザをリリースした数週間前までは正常に動作していました。Chrome がコンピュータにインストールされている場合、ShellExecute API は Web ページを開けなくなります。
この問題を解決する方法をまだ考えている人はいますか?(Chrome を検出して、Chrome のせいであることをユーザーに伝えるメッセージを表示しないのでしょうか?)
編集:Sergey が提供したコードは機能するようですので、それを「」答えとして受け入れます。WinExec の呼び出しが気に入らない点を除いて:MSDN によると、WinExec は 16 ビット アプリケーションとの互換性のためにのみ提供されています。ああ、どの Service Pack でも動作しなくなる可能性があります。私は試しませんでしたが、Windows x64 は 16 ビット アプリケーションをまったくサポートしていないため、すでに Windows x64 での動作を停止していても不思議ではありません。そこで、WinExec の代わりに、Sergey のコードのようにレジストリから取得したパスと引数として URL を使用して ShellExecute を使用します。ありがとう!
解決
すべてのブラウザで動作するコードは次のとおりです。コツは、ShellExecute が失敗した場合に WinExec を呼び出すことです。
HINSTANCE GotoURL(LPCTSTR url, int showcmd)
{
TCHAR key[MAX_PATH + MAX_PATH];
// First try ShellExecute()
HINSTANCE result = 0;
CString strURL = url;
if ( strURL.Find(".htm") <0 && strURL.Find("http") <0 )
result = ShellExecute(NULL, _T("open"), url, NULL, NULL, showcmd);
// If it failed, get the .htm regkey and lookup the program
if ((UINT)result <= HINSTANCE_ERROR) {
if (GetRegKey(HKEY_CLASSES_ROOT, _T(".htm"), key) == ERROR_SUCCESS) {
lstrcat(key, _T("\\shell\\open\\command"));
if (GetRegKey(HKEY_CLASSES_ROOT,key,key) == ERROR_SUCCESS) {
TCHAR *pos;
pos = _tcsstr(key, _T("\"%1\""));
if (pos == NULL) { // No quotes found
pos = strstr(key, _T("%1")); // Check for %1, without quotes
if (pos == NULL) // No parameter at all...
pos = key+lstrlen(key)-1;
else
*pos = '\0'; // Remove the parameter
}
else
*pos = '\0'; // Remove the parameter
lstrcat(pos, _T(" \""));
lstrcat(pos, url);
lstrcat(pos, _T("\""));
result = (HINSTANCE) WinExec(key,showcmd);
}
}
}
return result;
}
他のヒント
少数のシステムで ShellExecute が失敗するという報告を聞いた後、私は Sergey Kornilov が示した例と同様の関数を実装しました。これは約1年前のことです。同じ前提 - .HTM ファイル ハンドラーの直接 HKCR ルックアップを実行します。
ただし、一部のユーザーはエディターを持っていることが判明しました (例:UltraEdit) は、.htm ファイルを (「編集」するのではなく) 「開く」ように登録します。したがって、 もし ShellExecute は失敗します。そのような場合、この 2 番目のメソッドも失敗します。シェル関連付けの誤った指示に従って、エディタが開きます。
したがって、ユーザーは代わりに HTTP ハンドラーを使用するか、少なくとも HTML ハンドラーよりも優先して使用する必要があります。