在新的浏览器进程中打开一个URL

我需要在新的浏览器进程中打开一个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”被固定为iexplore,而不是用户的默认Web浏览器。 如何找出用户的默认网页浏览器是什么?

我正在运行Vista->前进。 尽pipe如果可能的话,XP会很好的支持。

更多的上下文:我创build了一个非常小的独立的Web服务器,从本地磁盘提供一些文件。 在启动服务器的最后,我想启动浏览器。 一旦用户完成并closures浏览器,我想退出Web服务器。 上面的代码完美的工作,除了只使用IE浏览器。

提前致谢!

Solutions Collecting From Web of "在新的浏览器进程中打开一个URL"

好。 我现在有工作的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); } } } 

呼! 谢谢大家的帮助,推动我走向正确的答案!

如果您将已知文件类型的路径传递给(文件)浏览器应用程序,它将“ 做正确的事情 ”,例如

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

好吧,我想我可能已经找到了它 – IApplicationAssociationRegistration :: QueryCurrentDefault [1]。 根据文档,这是由ShellExecute使用的。 我会在开始工作时发布代码,但如果其他人认为这是正确的使用方法,我会很感兴趣(顺便说一下,我是Vista或更高版本的操作系统级别)。

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

好。 在会议电路上已经走了一个星期了,现在回到这里。 我现在可以用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#代码!

我已经为一个项目编写了这个代码……它记住了为默认浏览器设置的任何附加参数。 它最初是为了在浏览器中打开HTML文档而创建的,因为我总是把默认的HTML程序设置为编辑器而不是浏览器,而且让我无法看到某些程序在我的文本中打开了它的HTML自述文件编辑。 显然,它也适用于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实例,它将会在同一个firefox.exe进程的另一个窗口或者标签页中打开,甚至在关闭了你的页面之后,退出,直到他们关闭每个窗口和标签。 在这种情况下,由于临时的firefox.exe进程会将URL封送到当前进程,因此您将立即收到进程退出的通知。 (假设这是Firefox的单一实例管理工作)。