gpt4 book ai didi

c# - 如何强制 Internet Explorer 打开它当前运行的实例而不是创建一个新实例?

转载 作者:太空狗 更新时间:2023-10-29 21:05:21 31 4
gpt4 key购买 nike

如何以编程方式启动 IE (iexplore.exe) 并在当前运行的实例中导航(通过打开新选项卡或替换当前 URL)而不是创建新实例。

我搜索了一个命令行开关,并尝试使用 InternetExplorer.Application,但无济于事。

这是我需要的(IE6-IE9 会很好):

ShellExecute(Handle, 'open', 'iexplore.exe',
'"http://google.com" -single_instance',
nil, SW_RESTORE);

下面是一些代码来演示我的尝试。 Delphi 中的代码(部分基于 How to get IHTMLDocument2 from a HWND ):

implementation

uses ShellApi, ComObj, ActiveX, SHDocVw, MSHTML;

function GetIEFromHWND(WHandle: HWND; var IE: IWebbrowser2): Boolean;
type
TObjectFromLResult = function(LRESULT: lResult; const IID: TIID;
wParam: WPARAM; out pObject): HRESULT; stdcall;
var
hInst: HMODULE;
lRes: Cardinal;
Msg: UINT;
pDoc: IHTMLDocument2;
ObjectFromLresult: TObjectFromLresult;
begin
Result := False;
hInst := LoadLibrary('oleacc.dll');
if hInst <> 0 then
try
@ObjectFromLresult := GetProcAddress(hInst, 'ObjectFromLresult');
if @ObjectFromLresult <> nil then
begin
Msg := RegisterWindowMessage('WM_HTML_GETOBJECT');
if SendMessageTimeOut(WHandle, Msg, 0, 0, SMTO_ABORTIFHUNG, 1000, lRes) <> 0 then
if ObjectFromLresult(lRes, IHTMLDocument2, 0, pDoc) = S_OK then
begin
(pDoc.parentWindow as IServiceprovider).QueryService(
IWebbrowserApp, IWebbrowser2, IE);
Result := IE <> nil;
end;
end;
finally
FreeLibrary(hInst);
end;
end;

function GetActiveIEServerWindow(const Activate: Boolean=True): HWND;
var
Wnd, WndChild: HWND;
begin
Result := 0;
Wnd := FindWindow('IEFrame', nil); // top level IE
if Wnd <> 0 then
begin
WndChild := FindWindowEx(Wnd, 0, 'Shell DocObject View', nil);
if WndChild <> 0 then
begin
WndChild := FindWindowEx(WndChild, 0, 'Internet Explorer_Server', nil);
if WndChild <> 0 then
begin
Result := WndChild;
if Activate then
begin
if IsIconic(Wnd) then
ShowWindow(Wnd, SW_RESTORE)
else
SetForegroundWindow(Wnd);
end;
end;
end;
end;
end;

// Method 1
procedure TForm1.Button1Click(Sender: TObject);
const
navOpenInNewTab = $800;
var
IEServerWnd: HWND;
IE: IWebBrowser2;
begin
IEServerWnd := GetActiveIEServerWindow;
if (IEServerWnd <> 0) and GetIEFromHWnd(IEServerWnd, IE) then
begin
// *** this opens the Default browser, e.g Google Chrome
// *** if IE is the Default browser, an empty new window is opened.
OleVariant(IE).Navigate('http://www.yahoo.com', Longint(navOpenInNewTab));
end
else
begin
ShellExecute(Handle, 'open', 'iexplore.exe',
'"http://google.com"',
nil, SW_RESTORE);
end;
end;

procedure InternetExplorerNavigate(URL: WideString);
const
navOpenInNewTab = $800;
var
IE: OleVariant;
begin
try
// *** this always fails (security constraints?)
IE := GetActiveOleObject('InternetExplorer.Application');
except
IE := CreateOleObject('InternetExplorer.Application');
end;
IE.Visible := True;
IE.Navigate(URL, Longint(navOpenInNewTab));
end;

// Method 2
procedure TForm1.Button2Click(Sender: TObject);
begin
InternetExplorerNavigate('http://google.com');
end;

最佳答案

您的方法“1”确实有效。至少在这里,问题是“Shell DocObject View”窗口不是顶级 ie 窗口的直接子窗口。对于 IE8,“Internet Explorer_Server”窗口是“Shell DocObject View”的子窗口,“TabWindowClass”窗口是“Frame Tab”的子窗口。如果您可以确认“FindWindowEx”在方法 1 中返回 0,这就是它失败的原因。下面是修改为使用 EnumChildWindows 的代码:

function EnumChilds(hwnd: HWND; lParam: LPARAM): BOOL; stdcall;
const
Server = 'Internet Explorer_Server';
var
ClassName: array[0..24] of Char;
begin
GetClassName(hwnd, ClassName, Length(ClassName));
Result := ClassName <> Server;
if not Result then
PLongWord(lParam)^ := hwnd;
end;

function GetActiveIEServerWindow(const Activate: Boolean=True): HWND;
var
Wnd, WndChild: HWND;
begin
Result := 0;
Wnd := FindWindow('IEFrame', nil); // top level IE
if Wnd <> 0 then
begin

// WndChild := FindWindowEx(Wnd, 0, 'Shell DocObject View', nil);
// if WndChild <> 0 then
// begin
// WndChild := FindWindowEx(WndChild, 0, 'Internet Explorer_Server', nil);

WndChild := 0;
EnumChildWindows(Wnd, @EnumChilds, LongWord(@WndChild));

if WndChild <> 0 then
begin
Result := WndChild;
if Activate then
begin
if IsIconic(Wnd) then
ShowWindow(Wnd, SW_RESTORE)
else
SetForegroundWindow(Wnd);
end;
end;
// end;
end;
end;

至于方法“2”,我在网上看到一些链接指出 IE 不支持为其事件对象返回引用,但我没有任何官方引用。

关于c# - 如何强制 Internet Explorer 打开它当前运行的实例而不是创建一个新实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10139727/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com