41
41
#define IE_FRAME_WINDOW_CLASS " IEFrame"
42
42
#define SHELL_DOCOBJECT_VIEW_WINDOW_CLASS " Shell DocObject View"
43
43
#define IE_SERVER_CHILD_WINDOW_CLASS " Internet Explorer_Server"
44
+ #define ANDIE_FRAME_WINDOW_CLASS " Chrome_WidgetWin_1"
44
45
45
46
#define IE_CLSID_REGISTRY_KEY L" SOFTWARE\\ Classes\\ InternetExplorer.Application\\ CLSID"
46
47
#define IE_SECURITY_ZONES_REGISTRY_KEY L" Software\\ Microsoft\\ Windows\\ CurrentVersion\\ Internet Settings\\ Zones"
50
51
51
52
#define IELAUNCHURL_ERROR_MESSAGE " IELaunchURL() returned HRESULT %X ('%s') for URL '%s'"
52
53
#define CREATEPROCESS_ERROR_MESSAGE " CreateProcess() failed for command line '%s'"
54
+ #define CREATEPROCESS_EDGE_ERROR " CreateProcess() failed for edge with the following command: "
53
55
#define NULL_PROCESS_ID_ERROR_MESSAGE " successfully launched Internet Explorer, but did not return a valid process ID."
54
56
#define PROTECTED_MODE_SETTING_ERROR_MESSAGE " Protected Mode settings are not the same for all zones. Enable Protected Mode must be set to the same value (enabled or disabled) for all zones."
55
57
#define ZOOM_SETTING_ERROR_MESSAGE " Browser zoom level was set to %d%%. It should be set to 100%%"
@@ -95,6 +97,7 @@ BrowserFactory::BrowserFactory(void) {
95
97
this ->GetExecutableLocation ();
96
98
this ->GetIEVersion ();
97
99
this ->oleacc_instance_handle_ = NULL ;
100
+ this ->edge_ie_mode_ = false ;
98
101
}
99
102
100
103
BrowserFactory::~BrowserFactory (void ) {
@@ -121,7 +124,10 @@ void BrowserFactory::Initialize(BrowserFactorySettings settings) {
121
124
this ->clear_cache_ = settings.clear_cache_before_launch ;
122
125
this ->browser_command_line_switches_ = StringUtilities::ToWString (settings.browser_command_line_switches );
123
126
this ->initial_browser_url_ = StringUtilities::ToWString (settings.initial_browser_url );
124
-
127
+ this ->edge_ie_mode_ = settings.attach_to_edge_ie ;
128
+ LOG (DEBUG) << " path before was " << settings.edge_executable_path << " \n " ;
129
+ this ->edge_executable_location_ = StringUtilities::ToWString (settings.edge_executable_path );
130
+ LOG (DEBUG) << " path after was " << this ->edge_executable_location_ .c_str () << " \n " ;
125
131
this ->html_getobject_msg_ = ::RegisterWindowMessage (HTML_GETOBJECT_MSG);
126
132
127
133
// Explicitly load MSAA so we know if it's installed
@@ -180,7 +186,9 @@ DWORD BrowserFactory::LaunchBrowserProcess(std::string* error_message) {
180
186
PROCESS_INFORMATION proc_info;
181
187
::ZeroMemory (&proc_info, sizeof (proc_info));
182
188
183
- if (!use_createprocess_api) {
189
+ if (this ->edge_ie_mode_ ) {
190
+ this ->LaunchEdgeInIEMode (&proc_info, error_message);
191
+ } else if (!use_createprocess_api) {
184
192
this ->LaunchBrowserUsingIELaunchURL (&proc_info, error_message);
185
193
} else {
186
194
this ->LaunchBrowserUsingCreateProcess (&proc_info, error_message);
@@ -327,6 +335,55 @@ void BrowserFactory::LaunchBrowserUsingCreateProcess(PROCESS_INFORMATION* proc_i
327
335
delete[] command_line;
328
336
}
329
337
338
+ void BrowserFactory::LaunchEdgeInIEMode (PROCESS_INFORMATION* proc_info,
339
+ std::string* error_message) {
340
+ LOG (TRACE) << " Entering BrowserFactory::LaunchEdgeInIEMode" ;
341
+ LOG (DEBUG) << " Starting Edge Chromium from the command line" ;
342
+
343
+ STARTUPINFO start_info;
344
+ ::ZeroMemory (&start_info, sizeof (start_info));
345
+ start_info.cb = sizeof (start_info);
346
+
347
+ std::wstring executable_and_url = this ->edge_executable_location_ ;
348
+ if (executable_and_url == L" " ) {
349
+ executable_and_url = L" msedge.exe" ; // Assume it's on the path if it's not passed
350
+ }
351
+
352
+ // These flags force Edge into a mode where it will only run MSHTML
353
+ executable_and_url.append (L" --ie-mode-force" );
354
+ executable_and_url.append (L" --internet-explorer-integration=iemode" );
355
+
356
+ executable_and_url.append (L" " );
357
+ executable_and_url.append (this ->initial_browser_url_ );
358
+
359
+ LOG (TRACE) << " IE starting command line is: '"
360
+ << LOGWSTRING (executable_and_url) << " '." ;
361
+
362
+ LPWSTR command_line = new WCHAR[executable_and_url.size () + 1 ];
363
+ wcscpy_s (command_line,
364
+ executable_and_url.size () + 1 ,
365
+ executable_and_url.c_str ());
366
+ command_line[executable_and_url.size ()] = L' \0 ' ;
367
+ BOOL create_process_result = ::CreateProcess (NULL ,
368
+ command_line,
369
+ NULL ,
370
+ NULL ,
371
+ FALSE ,
372
+ 0 ,
373
+ NULL ,
374
+ NULL ,
375
+ &start_info,
376
+ proc_info);
377
+
378
+
379
+ if (!create_process_result) {
380
+ *error_message = CREATEPROCESS_EDGE_ERROR + StringUtilities::ToString (command_line);
381
+ }
382
+
383
+ delete[] command_line;
384
+ }
385
+
386
+
330
387
bool BrowserFactory::GetDocumentFromWindowHandle (HWND window_handle,
331
388
IHTMLDocument2** document) {
332
389
LOG (TRACE) << " Entering BrowserFactory::GetDocumentFromWindowHandle" ;
@@ -411,11 +468,13 @@ bool BrowserFactory::AttachToBrowser(ProcessWindowInfo* process_window_info,
411
468
return attached;
412
469
}
413
470
471
+
414
472
bool BrowserFactory::IsBrowserProcessInitialized (DWORD process_id) {
415
473
ProcessWindowInfo info;
416
474
info.dwProcessId = process_id;
417
475
info.hwndBrowser = NULL ;
418
476
info.pBrowser = NULL ;
477
+
419
478
::EnumWindows (&BrowserFactory::FindBrowserWindow,
420
479
reinterpret_cast <LPARAM>(&info));
421
480
return info.hwndBrowser != NULL ;
@@ -431,8 +490,15 @@ bool BrowserFactory::AttachToBrowserUsingActiveAccessibility
431
490
if (this ->browser_attach_timeout_ > 0 && (clock () > end)) {
432
491
break ;
433
492
}
434
- ::EnumWindows (&BrowserFactory::FindBrowserWindow,
435
- reinterpret_cast <LPARAM>(process_window_info));
493
+ if (!this ->edge_ie_mode_ ) {
494
+ ::EnumWindows (&BrowserFactory::FindBrowserWindow,
495
+ reinterpret_cast <LPARAM>(process_window_info));
496
+ } else {
497
+ // If we're in edge_ie_mode, we need to look for different windows
498
+ ::EnumWindows (&BrowserFactory::FindEdgeWindow,
499
+ reinterpret_cast <LPARAM>(process_window_info));
500
+ }
501
+
436
502
if (process_window_info->hwndBrowser == NULL ) {
437
503
::Sleep (250 );
438
504
}
@@ -940,21 +1006,37 @@ void BrowserFactory::InvokeClearCacheUtility(bool use_low_integrity_level) {
940
1006
BOOL CALLBACK BrowserFactory::FindBrowserWindow (HWND hwnd, LPARAM arg) {
941
1007
// Could this be an IE instance?
942
1008
// 8 == "IeFrame\0"
943
- // 21 == "Shell DocObject View\0";
1009
+ // 21 == "Shell DocObject View\0"
1010
+ // 19 == "Chrome_WidgetWin_1"
944
1011
char name[21 ];
945
1012
if (::GetClassNameA (hwnd, name, 21 ) == 0 ) {
946
1013
// No match found. Skip
947
1014
return TRUE ;
948
1015
}
949
1016
950
- if (strcmp (IE_FRAME_WINDOW_CLASS, name) != 0 &&
1017
+ if (strcmp (IE_FRAME_WINDOW_CLASS, name) != 0 &&
951
1018
strcmp (SHELL_DOCOBJECT_VIEW_WINDOW_CLASS, name) != 0 ) {
952
1019
return TRUE ;
953
1020
}
954
1021
955
1022
return EnumChildWindows (hwnd, FindChildWindowForProcess, arg);
956
1023
}
957
1024
1025
+ BOOL CALLBACK BrowserFactory::FindEdgeWindow (HWND hwnd, LPARAM arg) {
1026
+ // Could this be an EdgeChrome window?
1027
+ // 19 == "Chrome_WidgetWin_1"
1028
+ char name[20 ];
1029
+ if (::GetClassNameA (hwnd, name, 20 ) == 0 ) {
1030
+ // No match found. Skip
1031
+ return TRUE ;
1032
+ }
1033
+
1034
+ // continue if it is not "Chrome_WidgetWin_1"
1035
+ if (strcmp (ANDIE_FRAME_WINDOW_CLASS, name) != 0 ) return TRUE ;
1036
+
1037
+ return EnumChildWindows (hwnd, FindEdgeChildWindowForProcess, arg);
1038
+ }
1039
+
958
1040
BOOL CALLBACK BrowserFactory::FindChildWindowForProcess (HWND hwnd, LPARAM arg) {
959
1041
ProcessWindowInfo *process_window_info = reinterpret_cast <ProcessWindowInfo*>(arg);
960
1042
@@ -971,6 +1053,7 @@ BOOL CALLBACK BrowserFactory::FindChildWindowForProcess(HWND hwnd, LPARAM arg) {
971
1053
} else {
972
1054
DWORD process_id = NULL ;
973
1055
::GetWindowThreadProcessId (hwnd, &process_id);
1056
+ LOG (DEBUG) << " Looking for " << process_window_info->dwProcessId ;
974
1057
if (process_window_info->dwProcessId == process_id) {
975
1058
// Once we've found the first Internet Explorer_Server window
976
1059
// for the process we want, we can stop.
@@ -982,6 +1065,33 @@ BOOL CALLBACK BrowserFactory::FindChildWindowForProcess(HWND hwnd, LPARAM arg) {
982
1065
return TRUE ;
983
1066
}
984
1067
1068
+ BOOL CALLBACK BrowserFactory::FindEdgeChildWindowForProcess (HWND hwnd, LPARAM arg) {
1069
+ ProcessWindowInfo* process_window_info = reinterpret_cast <ProcessWindowInfo*>(arg);
1070
+
1071
+ // Could this be an Internet Explorer Server window?
1072
+ // 25 == "Internet Explorer_Server\0"
1073
+ char name[25 ];
1074
+ if (::GetClassNameA (hwnd, name, 25 ) == 0 ) {
1075
+ // No match found. Skip
1076
+ return TRUE ;
1077
+ }
1078
+
1079
+ if (strcmp (IE_SERVER_CHILD_WINDOW_CLASS, name) != 0 ) {
1080
+ return TRUE ;
1081
+ }
1082
+ else {
1083
+ DWORD process_id = NULL ;
1084
+ ::GetWindowThreadProcessId (hwnd, &process_id);
1085
+ LOG (DEBUG) << " Looking for " << process_window_info->dwProcessId ;
1086
+ // Once we've found the first Internet Explorer_Server window
1087
+ // for the process we want, we can stop.
1088
+ process_window_info->hwndBrowser = hwnd;
1089
+ return FALSE ;
1090
+ }
1091
+
1092
+ return TRUE ;
1093
+ }
1094
+
985
1095
BOOL CALLBACK BrowserFactory::FindDialogWindowForProcess (HWND hwnd, LPARAM arg) {
986
1096
ProcessWindowInfo* process_win_info = reinterpret_cast <ProcessWindowInfo*>(arg);
987
1097
@@ -1243,5 +1353,8 @@ bool BrowserFactory::IsWindowsVistaOrGreater() {
1243
1353
return IsWindowsVersionOrGreater (HIBYTE (_WIN32_WINNT_VISTA), LOBYTE (_WIN32_WINNT_VISTA), 0 );
1244
1354
}
1245
1355
1356
+ bool BrowserFactory::IsEdgeMode () const {
1357
+ return this ->edge_ie_mode_ ;
1358
+ }
1246
1359
1247
1360
} // namespace webdriver
0 commit comments