我需要在新的浏览器进程中打开一个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浏览器。如何确定用户的默认Web浏览器是什么?
我正在运行Vista->前进。虽然如果可能的话XP会很好的支持。
更多上下文:我创建了一个非常小的独立Web服务器,它可以从本地磁盘上提供一些文件。在启动服务器结束时,我想启动浏览器。用户完成并关闭浏览器后,我想退出Web服务器。除了仅使用IE之外,上述代码完美无缺。
提前致谢!
答案 0 :(得分:5)
确定。我现在有工作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);
}
}
}
呼!感谢大家的帮助,帮助我找到正确的答案!
答案 1 :(得分:2)
如果您将已知文件类型的路径传递给(文件)资源管理器应用程序,它将“做正确的事情”,例如
Process.Start("explorer.exe", @"\\path.to\filename.pdf");
并在PDF阅读器中打开该文件。
但是,如果您使用网址尝试相同的操作,例如
Process.Start("explorer.exe", @"http://www.stackoverflow.com/");
它会激活IE(这不是我机器上的默认浏览器)。
我知道不回答这个问题,但我认为这是一个有趣的旁注。
答案 2 :(得分: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;
}
答案 3 :(得分:1)
好吧,我想我可能已经找到了它 - IApplicationAssociationRegistration :: QueryCurrentDefault [1]。根据文档,这是ShellExecute使用的。当我开始使用它时我会发布代码,但是如果其他人认为这是正确的选择(BTW,我是Vista或更高级别的操作系统级别),我会感兴趣。
[1]:http://msdn.microsoft.com/en-us/library/bb776336(VS.85).aspx QueryCurrentDefault
答案 4 :(得分: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#代码!
答案 5 :(得分:1)
我为项目编写了一次代码...它记住了为默认浏览器设置的任何其他参数。它最初是为了在浏览器中打开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);
}
}
答案 6 :(得分:0)
简短回答,你不能。
如果默认浏览器是Firefox,并且用户已经运行了Firefox实例,则只会在同一个firefox.exe进程的另一个窗口或选项卡中打开它,即使它们关闭了您的页面,在关闭每个窗口和选项卡之前,进程不会退出。在这种情况下,由于临时firefox.exe proc会将URL封送到当前进程,因此一旦启动它就会收到退出进程的通知。 (假设Firefox的单实例管理工作正常)。