4

新しいブラウザ プロセスで URL を開く必要があります。そのブラウザ プロセスが終了したときに通知を受ける必要があります。私が現在使用しているコードは次のとおりです。

        Process browser = new Process();
        browser.EnableRaisingEvents = true;
        browser.StartInfo.Arguments = url;
        browser.StartInfo.FileName = "iexplore";

        browser.Exited += new EventHandler(browser_Exited);

        browser.Start();

「FileName」がユーザーのデフォルトの Web ブラウザーではなく、iexplore に固定されているため、明らかに、これは原因ではありません。ユーザーの既定の Web ブラウザーを確認するにはどうすればよいですか?

私はVista-> forwardで実行しています。可能であれば、XP をサポートすることをお勧めします。

もう少しコンテキスト: ローカル ディスクからいくつかのファイルを提供する非常に小さなスタンドアロンの Web サーバーを作成しました。サーバーの起動の最後に、ブラウザを起動したいと思います。ユーザーが完了してブラウザを閉じたら、Web サーバーを終了したいと思います。上記のコードは、IE のみを使用する以外は完全に機能します。

前もって感謝します!

4

7 に答える 7

6

Ok。私は今、私がやりたいことをするための作業中のC#コードを持っています。これにより、現在のデフォルト ブラウザをロードするために実行する必要がある「コマンド ライン」が返されます。

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Linq;
using System.Text;

namespace testDefaultBrowser
{
    public enum ASSOCIATIONLEVEL
    {
        AL_MACHINE,
        AL_EFFECTIVE,
        AL_USER,
    };

    public enum ASSOCIATIONTYPE
    {
        AT_FILEEXTENSION,
        AT_URLPROTOCOL,
        AT_STARTMENUCLIENT,
        AT_MIMETYPE,
    };

    [Guid("4e530b0a-e611-4c77-a3ac-9031d022281b"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IApplicationAssociationRegistration
    {
        void QueryCurrentDefault([In, MarshalAs(UnmanagedType.LPWStr)] string pszQuery,
        [In, MarshalAs(UnmanagedType.I4)] ASSOCIATIONTYPE atQueryType,
        [In, MarshalAs(UnmanagedType.I4)] ASSOCIATIONLEVEL alQueryLevel,
        [Out, MarshalAs(UnmanagedType.LPWStr)] out string ppszAssociation);

        void QueryAppIsDefault(
            [In, MarshalAs(UnmanagedType.LPWStr)] string pszQuery,
            [In] ASSOCIATIONTYPE atQueryType,
            [In] ASSOCIATIONLEVEL alQueryLevel,
            [In, MarshalAs(UnmanagedType.LPWStr)] string pszAppRegistryName,
            [Out] out bool pfDefault);

        void QueryAppIsDefaultAll(
            [In] ASSOCIATIONLEVEL alQueryLevel,
            [In, MarshalAs(UnmanagedType.LPWStr)] string pszAppRegistryName,
            [Out] out bool pfDefault);

        void SetAppAsDefault(
            [In, MarshalAs(UnmanagedType.LPWStr)] string pszAppRegistryName,
            [In, MarshalAs(UnmanagedType.LPWStr)] string pszSet,
            [In] ASSOCIATIONTYPE atSetType);

        void SetAppAsDefaultAll(
            [In, MarshalAs(UnmanagedType.LPWStr)] string pszAppRegistryName);

        void ClearUserAssociations();
    }

    [ComImport, Guid("591209c7-767b-42b2-9fba-44ee4615f2c7")]//
    class ApplicationAssociationRegistration
    {
    }

    class Program
    {
        static void Main(string[] args)
        {
            IApplicationAssociationRegistration reg = 
                (IApplicationAssociationRegistration) new ApplicationAssociationRegistration();

            string progID;
            reg.QueryCurrentDefault(".txt",
                ASSOCIATIONTYPE.AT_FILEEXTENSION,
                ASSOCIATIONLEVEL.AL_EFFECTIVE,
                out progID);
            Console.WriteLine(progID);

            reg.QueryCurrentDefault("http",
                ASSOCIATIONTYPE.AT_URLPROTOCOL,
                ASSOCIATIONLEVEL.AL_EFFECTIVE,
                out progID);
            Console.WriteLine(progID);
        }
    }
}

うわー!正しい答えに向かって私を押してくれてありがとう!

于 2009-05-03T06:32:08.530 に答える
3

既知のファイル タイプのパスを (ファイル) エクスプローラー アプリケーションに渡すと、「正しいことを行います」、たとえば

 Process.Start("explorer.exe", @"\\path.to\filename.pdf");

PDFリーダーでファイルを開きます。

しかし、URLで同じことを試してみると、たとえば

Process.Start("explorer.exe", @"http://www.stackoverflow.com/");

IE が起動します (これは私のマシンのデフォルトのブラウザーではありません)。

質問に答えていないことはわかっていますが、興味深い補足事項だと思いました。

于 2009-04-22T08:40:17.203 に答える
1

わかりました、私はそれを見つけたかもしれないと思います - IApplicationAssociationRegistration::QueryCurrentDefault [1]。ドキュメントによると、これは ShellExecute で使用されるものです。動作するようになったらコードを投稿しますが、他の人がこれを使用するのが正しいと思うかどうか興味があります (ところで、私は OS レベルで Vista 以上です)。

[1]: http://msdn.microsoft.com/en-us/library/bb776336(VS.85).aspx QueryCurrentDefault

于 2009-04-22T08:01:27.470 に答える
1

Ok。カンファレンス サーキットに 1 週​​間参加していませんでしたが、ここで話を戻します。私はこれを C++ で実行できるようになりました。ただし、これを C# (または .NET) に変換する試みはすべて失敗しました ( Post On Question )。

この質問に出くわした他の人のための C++ コードは次のとおりです。

#include "stdafx.h"
#include <iostream>
#include <shobjidl.h>
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS      // some CString constructors will be explicit

#include <atlbase.h>
#include <atlstr.h>
#include <AtlDef.h>
#include <AtlConv.h>

using namespace std;
using namespace ATL;

int _tmain(int argc, _TCHAR* argv[])
{
    HRESULT hr = CoInitialize(NULL);
    if (!SUCCEEDED(hr)) {
        cout << "Failed to init COM instance" << endl;
        cout << hr << endl;
    }

    IApplicationAssociationRegistration *pAAR;
    hr = CoCreateInstance(CLSID_ApplicationAssociationRegistration,
        NULL, CLSCTX_INPROC, __uuidof(IApplicationAssociationRegistration),
        (void**) &pAAR);
    if (!SUCCEEDED(hr))
    {
        cout << "Failed to create COM object" << endl;
        cout << hr << endl;
        return 0;
    }

    LPWSTR progID;
    //wchar_t *ttype = ".txt";
    hr = pAAR->QueryCurrentDefault (L".txt", AT_FILEEXTENSION, AL_EFFECTIVE, &progID);
    if (!SUCCEEDED(hr)) {
        cout << "Failed to query default for .txt" << endl;
        cout << hr << endl;
    }
    CW2A myprogID (progID);
    cout << "Result is: " << static_cast<const char*>(myprogID) << endl;

    /// Now for http

    hr = pAAR->QueryCurrentDefault (L"http", AT_URLPROTOCOL, AL_EFFECTIVE, &progID);
    if (!SUCCEEDED(hr)) {
        cout << "Failed to query default for http" << endl;
        cout << hr << endl;
    }
    CW2A myprogID1 (progID);
    cout << "Result is: " << static_cast<const char*>(myprogID1) << endl;

    return 0;
}

最終的に動作するようになったら、C# コードを投稿します。

于 2009-05-03T06:11:32.310 に答える
1

デフォルトのブラウザを決定する方法は、次のブログ投稿で説明されています。

http://ryanfarley.com/blog/archive/2004/05/16/649.aspx

上記のブログ投稿から:

private string getDefaultBrowser()
{
    string browser = string.Empty;
    RegistryKey key = null;
    try
    {
        key = Registry.ClassesRoot.OpenSubKey(@"HTTP\shell\open\command", false);

        //trim off quotes
        browser = key.GetValue(null).ToString().ToLower().Replace("\"", "");
        if (!browser.EndsWith("exe"))
        {
            //get rid of everything after the ".exe"
            browser = browser.Substring(0, browser.LastIndexOf(".exe")+4);
        }
    }
    finally
    {
        if (key != null) key.Close();
    }
    return browser;
}
于 2009-04-12T23:12:26.307 に答える
1

プロジェクト用にこのコードを書いたことがあります...デフォルトのブラウザに設定された追加のパラメータを念頭に置いています。元々、ブラウザで HTML ドキュメントを開くために作成されました。単純な理由は、私が常に HTML 用のデフォルト プログラムをブラウザではなくエディタに設定しているためです。一部のプログラムが自分のテキストで HTML の readme を開くのを見ると、際限なく悩まされます。編集者。明らかに、URL に対しても完全に機能します。

    /// <summary>
    ///     Opens a local file or url in the default web browser.
    /// </summary>
    /// <param name="path">Path of the local file or url</param>
    public static void openInDefaultBrowser(String pathOrUrl)
    {
        pathOrUrl = "\"" + pathOrUrl.Trim('"') + "\"";
        RegistryKey defBrowserKey = Registry.ClassesRoot.OpenSubKey(@"http\shell\open\command");
        if (defBrowserKey != null && defBrowserKey.ValueCount > 0 && defBrowserKey.GetValue("") != null)
        {
            String defBrowser = (String)defBrowserKey.GetValue("");
            if (defBrowser.Contains("%1"))
            {
                defBrowser = defBrowser.Replace("%1", pathOrUrl);
            }
            else
            {
                defBrowser += " " + pathOrUrl;
            }
            String defBrowserProcess;
            String defBrowserArgs;
            if (defBrowser[0] == '"')
            {
                defBrowserProcess = defBrowser.Substring(0, defBrowser.Substring(1).IndexOf('"') + 2).Trim();
                defBrowserArgs = defBrowser.Substring(defBrowser.Substring(1).IndexOf('"') + 2).TrimStart();
            }
            else
            {
                defBrowserProcess = defBrowser.Substring(0, defBrowser.IndexOf(" ")).Trim();
                defBrowserArgs = defBrowser.Substring(defBrowser.IndexOf(" ")).Trim();
            }
            if (new FileInfo(defBrowserProcess.Trim('"')).Exists)
                Process.Start(defBrowserProcess, defBrowserArgs);
        }
    }
于 2011-01-05T04:02:59.527 に答える
0

短い答え、できません。

デフォルトのブラウザーが Firefox で、ユーザーが既に Firefox インスタンスを実行している場合、同じ firefox.exe プロセスの別のウィンドウまたはタブで開かれ、ページを閉じた後でも、プロセスは実行されません。すべてのウィンドウとタブを閉じるまで終了しないでください。この場合、URL を現在のプロセスにマーシャリングする一時的な firefox.exe プロシージャにより、プロセスを開始するとすぐに終了するという通知を受け取ります。(これが Firefox の単一インスタンス管理のしくみであると仮定します)。

于 2009-05-03T06:18:00.500 に答える