سؤال

أحتاج إلى فتح عنوان URL في عملية متصفح جديدة. أحتاج إلى إخطار عند إنهاء عملية المستعرض هذا. الرمز الذي أستخدمه حاليا هو ما يلي:

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

        browser.Exited += new EventHandler(browser_Exited);

        browser.Start();

من الواضح أن هذا لن يرجع ذلك لأنه تم إصلاح "اسم الملف" إلى iExplore، وليس متصفح الويب الافتراضي للمستخدم. كيف يمكنني معرفة ما هو متصفح الويب الافتراضي للمستخدم هو؟

أنا أركض على Vista-> إلى الأمام. على الرغم من أن XP سيكون من الجميل أن يدعم إذا كان ذلك ممكنا.

سياق أكثر قليلا: لقد أنشأت خادم ويب صغير مستقل للغاية يخدم بعض الملفات من قرص محلي. في نهاية بدء تشغيل الخادم أريد أن أبدأ المتصفح. بمجرد الانتهاء من المستخدم ويغلق المتصفح الذي أود إنهاء خادم الويب. يعمل الرمز أعلاه تماما، بخلاف استخدام أي فقط.

شكرا مقدما!

هل كانت مفيدة؟

المحلول

نعم. لقد عملت الآن رمز 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);
        }
    }
}

يا عجب! شكرا للجميع للمساعدة في دفع لي نحو الإجابة الصحيحة!

نصائح أخرى

إذا قمت بتمرير مسار من نوع الملف المعروف إلى تطبيق Explorer (الملف)، فسوفإفعل الصواب"، على سبيل المثال

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

وفتح الملف في قارئ PDF.

ولكن إذا حاولت نفس الشيء مع عنوان URL، على سبيل المثال

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

إنه يطلق IE (الذي ليس المتصفح الافتراضي على جهازي).

أعلم أنني لا أجيب على السؤال، لكنني اعتقدت أنه كان جانبا مثيرا للاهتمام.

يتم شرح طريقة تحديد المتصفح الافتراضي في منشور المدونة هذا:

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;
}

حسنا، أعتقد أنني ربما وجدت ذلك - IiaPplicationCassIationRegistration :: QueryCurrentDefault [1]. وفقا للمثيمات هذا هو ما يستخدم من قبل shelllexecute. سأقوم بنشر الرمز عندما أحصل عليه للعمل، لكنني سأكون مهتما إذا اعتقد البعض الآخر أن هذا هو الشيء الصحيح الذي يجب استخدامه (راجع للشغل، وأنا فيستا أو أكبر لنظام التشغيل).

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

نعم. كان بعيدا عن دائرة المؤتمر لمدة أسبوع، والعودة الآن إلى هذا. يمكنني أن أفعل هذا مع C ++ الآن - ويبدو أنه يتصرف بشكل صحيح! فشل محاولاتي لترجمة هذا إلى C # (أو .NET) جميعها (نشر على السؤال).

هنا رمز 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 # عندما أحصل عليه أخيرا!

لقد كتبت هذا الرمز لمشروع مرة واحدة ... إنه يحتفظ في الاعتبار أي معلمات إضافية محددة للمتصفح الافتراضي. تم إنشاؤه أصلا لفتح وثائق 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);
        }
    }

إجابة قصيرة، لا يمكنك ذلك.

إذا كان المتصفح الافتراضي، فقل، فايرفوكس، والمستخدم يحتوي بالفعل على مثيل Firefox قيد التشغيل، وسوف يتم فتحه فقط في نافذة أو علامة تبويب أخرى من عملية Firefox.exe نفسها، وحتى بعد إغلاق صفحتك، فازت العملية " تخرج حتى يغلقون كل نافذة وعلامة تبويب. في هذه الحالة، ستتلقى إشعارا بالعملية المخرجة بمجرد أن تبدأ ذلك، نظرا ل Firefox.exe المؤقتة التي من شأنها أن تنظر إليها عنوان URL بالعملية الحالية. (على افتراض أن هذا هو كيفية عمل إدارة المثيل الفردي Firefox).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top