One of our Windows client applications, which uses some Microsoft Active Document / ActiveX technology, requires that users use the IE browser. The application displays in the IE browser tab, but it runs in its own process, not in the IE browser tab process. It performs document editing, and sometimes needs to make HTTP requests back the server application to get additional resources. For customers using Single Sign On products, like SiteMinder, our client application may need to send back one or more cookies (like SMSESSION) that were initially sent by the server application.
In IE, the client application is able to "find" its IE tab by using Microsoft's SHDocVw::ShellWindows collection, and is also able to get the cookies from that tab. As IE has now been retired as of June 2022, customers are trying to run the application in Edge in IE mode. The SHDocVw::ShellWindows collection does not seem to find these "IE mode" tab windows that are running on Edge. Though we can locate the client window(s) using EnumWindows, just having the client window's HWND doesn't seem to let us get the cookies. As a result, our client application's HTTP request to the server does not send the cookies back to the server and the Single Sign On software on the server side then sends a Sign On HTML page in the response, rather than the document resource the client application requested.
I've tried to create a sample program below to demonstrate the problem. One way to build this sample with Visual Studio is to create a new C Win32 project, choose Win32 Console Application, check the checkbox "Add common header files for MFC", Finish, then paste the code below into the resulting starter source file.
If you open IE and go to http://microsoft.com , then run the program with IE open, the program should find the IE browser window and display some information like the title, pid, and cookie info. If you then close IE and open Edge, and go to http://microsoft.com in IE mode (enabling IE mode on Edge), the program does not seem to find this tab in Edge that is running in IE mode.
Is there any additional setup that needs to be done to get the SHDocVw::ShellWindows collection to find these Edge in IE mode tabs? Or, is there another way to be able to locate these tabs and get the associated cookies so that we can return these cookies to the server in the next HTTP request? Thanks.
#include "stdafx.h"
#include "afxctl.h"
#import <mshtml.tlb>
#import <shdocvw.dll>
#include "mshtml.h"
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
SHDocVw::IShellWindowsPtr m_spSHWinds;
IDispatchPtr spDisp;
IWebBrowser2Ptr m_webBrowser;
char *pszLocName;
char *pszTitle;
char *pszCookie;
HWND iehwnd;
DWORD iepid;
DWORD ietid;
_bstr_t bStrLocname;
_bstr_t bStrTitle;
_bstr_t bStrCookie;
DWORD rc;
IHTMLDocument2 *pdoc2 = NULL;
BSTR bptr;
BSTR ck;
char info[4096];
int cntIEtabs = 0;
CoInitialize(NULL);
HRESULT hr = m_spSHWinds.CreateInstance(__uuidof(SHDocVw::ShellWindows));
long nCount = m_spSHWinds->GetCount();
for (long i = 0; i < nCount; i )
{
_variant_t va(i, VT_I4);
spDisp = m_spSHWinds->Item(va);
SHDocVw::IWebBrowser2Ptr spBrowser(spDisp);
if (spBrowser != NULL)
{
bStrLocname = spBrowser->GetLocationName();
pszLocName = bStrLocname;
spBrowser->get_Name(&bptr);
bStrTitle = bptr;
pszTitle = bStrTitle;
try {
iehwnd = (HWND)spBrowser->GetHWND();
}
catch (const _com_error &e) {
// if GetHWND() fails
continue;
}
ietid = GetWindowThreadProcessId(iehwnd, &iepid);
// cookie stuff
m_webBrowser = (IWebBrowser2Ptr)spBrowser;
rc = m_webBrowser->get_Document(&spDisp);
if (spDisp->QueryInterface(IID_IHTMLDocument2,
(void**)&pdoc2) == S_OK)
{
pdoc2->get_cookie(&ck);
bStrCookie = ck;
pszCookie = bStrCookie;
sprintf_s(info,
"LocationName: %s\n\n"
"PID: %d\n\n"
"Title: %s\n\n"
"Cookie string: %s",
pszLocName, iepid, pszTitle, pszCookie);
MessageBox(NULL, CA2T(info), _T("Browser tab info:"), MB_OK);
cntIEtabs ;
}
}
}
if (cntIEtabs == 0) {
MessageBox(NULL, _T("No IE browser tabs found."), _T("Browser tab info:"), MB_OK);
}
return 0;
}
CodePudding user response:
It's a known issue in Edge IE mode and it's by design. The window list is disabled in IE mode because it would otherwise share state with real IE and cause other issues. For example, the first process to initialize the window list would own it (IE or IE mode), and if that process is closed then the window list will stop working for the other process.
The only way to fix this is enabling this policy EnableGlobalWindowListInIEMode to allow the IE Mode windows to show up in the global window list. This policy requires IE to be disabled as a standalone application, and IE Mode to be enabled. You can refer to this doc to disable IE 11. Then you can enable this policy by editing the registry in below path:
Registry Path: HKLM\Software\Policies\Microsoft\Internet Explorer\Main\EnterpriseMode
Value Name: EnableGlobalWindowListInIEMode
Value Type: REG_DWORD
Enabled Value: 1
Disabled Value: 0