IWebbrowser2 IE=edge and User agent string
Asked Answered
G

1

5

I'm developping a winapi c++ program that uses IWebBrowser2 embedded control.

I'm running Windows 7 + IExplore 11 so when I open IE11 and call to my server I get this User Agent string:

Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko

When making requests from IWebBrowser2 I get this UA String:

Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; Tablet PC 2.0; InfoPath.3; .NET4.0E)

I've managed to append this meta tag to every html page loaded in IWebBrowser2 (EDIT trying to avoid doing Browser Feature Controls -see comments-):

<meta http-equiv="X-UA-Compatible" content="IE=edge"/>


First question: by doing this, do I enable features for the latest installed IExplore version?

Second question: I've seen in Changing the user agent of the WebBrowser control how to change the UA string in IWebBrowser2.

Is there any way to get the latest IE version UA string in a safe user permission? (so even for most permission restricted user accounts I could achieve). I've tried with ObtainUserAgentString() with no luck, always getting "Mozilla/4.0 ... MSIE 7.0 ..."

Great answered 24/1, 2014 at 17:46 Comment(4)
First question: You need to implement Browser Feature Control: https://mcmap.net/q/24368/-c-webbrowser-ajax-call, second question, not sure I fully understand what you're asking, but hopefully the 1st one fixes it too.Aplenty
Thanks, @Noseratio. The Browser FC needs some keys to be written in the registry. I'm not an expert in windows security but I thought that maybe this will require user account rights and this is what I'm trying to avoid with IE=edge. My first question is about if this will have the same effect as Browser FC. Maybe I'm wrong and no account rights are required? I will clarify the questionGreat
no admin rights required for HKEY_CURRENT_USER.Aplenty
What about Question # 2? I am also interested in changing the user agentMccahill
G
8

Finally and thanks to Noseratio comment (+1), I implemented Browser Feature Control as this does not require admin rights. I also opened the keys in the registry as volatile to not leaving registry dirty after possible uninstall.

As the response linked by Noseratio reffers to C#, I leave here the C++ translation if someone needs it with explanations of what each feature is doing:

static bool SetBrowserFeatureControlKey(wstring feature, wchar_t *appName, DWORD value) {
  HKEY key;
  bool success = true;
  wstring featuresPath(L"Software\\Microsoft\\Internet Explorer\\Main\\FeatureControl\\");
  wstring path(featuresPath + feature);

  LONG nError = RegCreateKeyEx(HKEY_CURRENT_USER, path.c_str(), 0, NULL, REG_OPTION_VOLATILE, KEY_WRITE, NULL, &key, NULL);
  if (nError != ERROR_SUCCESS) {
    success = false;

  } else {
    nError = RegSetValueExW(key, appName, 0, REG_DWORD, (const BYTE*) &value, sizeof(value));
    if (nError != ERROR_SUCCESS) {
      success = false;
    }

    nError = RegCloseKey(key);
    if (nError != ERROR_SUCCESS) {
      success = false;
    }
  } 

  return success;
}

static void SetBrowserFeatureControl() {
  // http://msdn.microsoft.com/en-us/library/ee330720(v=vs.85).aspx
  DWORD emulationMode = GetBrowserEmulationMode();

  if (emulationMode > 0) {
    // FeatureControl settings are per-process
    wchar_t fileName[MAX_PATH + 1];
    ZeroMemory(fileName, (MAX_PATH + 1) * sizeof(wchar_t));
    GetModuleFileNameW(NULL, fileName, 256);
    vector<string> splittedFileName = split(WString2string(fileName), '\\');
    ZeroMemory(fileName, (MAX_PATH + 1) * sizeof(wchar_t));
    wstring exeName = String2wstring(splittedFileName.at(splittedFileName.size() - 1));
    memcpy(fileName, exeName.c_str(), sizeof(wchar_t) * exeName.length());

    // make the control is not running inside Visual Studio Designer
    //if (String.Compare(fileName, "devenv.exe", true) == 0 || String.Compare(fileName, "XDesProc.exe", true) == 0) {
    //  return;
    //}

    // Windows Internet Explorer 8 and later. The FEATURE_BROWSER_EMULATION feature defines the default emulation mode for Internet
    // Explorer and supports the following values.
    // Webpages containing standards-based !DOCTYPE directives are displayed in IE10 Standards mode.
    SetBrowserFeatureControlKey(L"FEATURE_BROWSER_EMULATION", fileName, emulationMode);

    // Internet Explorer 8 or later. The FEATURE_AJAX_CONNECTIONEVENTS feature enables events that occur when the value of the online
    // property of the navigator object changes, such as when the user chooses to work offline. For more information, see the ononline
    // and onoffline events.
    // Default: DISABLED
    SetBrowserFeatureControlKey(L"FEATURE_AJAX_CONNECTIONEVENTS", fileName, 1);

    // Internet Explorer 9. Internet Explorer 9 optimized the performance of window-drawing routines that involve clipping regions associated
    // with child windows. This helped improve the performance of certain window drawing operations. However, certain applications hosting the
    // WebBrowser Control rely on the previous behavior and do not function correctly when these optimizations are enabled. The
    // FEATURE_ENABLE_CLIPCHILDREN_OPTIMIZATION feature can disable these optimizations.
    // Default: ENABLED
    // SetBrowserFeatureControlKey(L"FEATURE_ENABLE_CLIPCHILDREN_OPTIMIZATION", fileName, 1);

    // Internet Explorer 8 and later. By default, Internet Explorer reduces memory leaks caused by circular references between Internet Explorer
    // and the Microsoft JScript engine, especially in scenarios where a webpage defines an expando and the page is refreshed. If a legacy
    // application no longer functions with these changes, the FEATURE_MANAGE_SCRIPT_CIRCULAR_REFS feature can disable these improvements.
    // Default: ENABLED
    // SetBrowserFeatureControlKey(L"FEATURE_MANAGE_SCRIPT_CIRCULAR_REFS", fileName, 1);

    // Windows Internet Explorer 8. When enabled, the FEATURE_DOMSTORAGE feature allows Internet Explorer and applications hosting the WebBrowser
    // Control to use the Web Storage API. For more information, see Introduction to Web Storage.
    // Default: ENABLED
    // SetBrowserFeatureControlKey(L"FEATURE_DOMSTORAGE ", fileName, 1);

    // Internet Explorer 9. The FEATURE_GPU_RENDERING feature enables Internet Explorer to use a graphics processing unit (GPU) to render content.
    // This dramatically improves performance for webpages that are rich in graphics.
    // Default: DISABLED
    SetBrowserFeatureControlKey(L"FEATURE_GPU_RENDERING ", fileName, 1);

    // Internet Explorer 9. By default, the WebBrowser Control uses Microsoft DirectX to render webpages, which might cause problems for
    // applications that use the Draw method to create bitmaps from certain webpages. In Internet Explorer 9, this method returns a bitmap
    // (in a Windows Graphics Device Interface (GDI) wrapper) instead of a GDI metafile representation of the webpage. When the
    // FEATURE_IVIEWOBJECTDRAW_DMLT9_WITH_GDI feature is enabled, the following conditions cause the Draw method to use GDI instead of DirectX
    // to create the resulting representation. The GDI representation will contain text records and vector data, but is not guaranteed to be
    // similar to the same represenation returned in earlier versions of the browser:
    //    The device context passed to the Draw method points to an enhanced metafile.
    //    The webpage is not displayed in IE9 Standards mode.
    // By default, this feature is ENABLED for applications hosting the WebBrowser Control. This feature is ignored by Internet Explorer and
    // Windows Explorer. To enable this feature by using the registry, add the name of your executable file to the following setting.
    SetBrowserFeatureControlKey(L"FEATURE_IVIEWOBJECTDRAW_DMLT9_WITH_GDI  ", fileName, 0);

    // Windows 8 introduces a new input model that is different from the Windows 7 input model. In order to provide the broadest compatibility
    // for legacy applications, the WebBrowser Control for Windows 8 emulates the Windows 7 mouse, touch, and pen input model (also known as the
    // legacy input model). When the legacy input model is in effect, the following conditions are true:
    //    Windows pointer messages are not processed by the Trident rendering engine (mshtml.dll).
    //    Document Object Model (DOM) pointer and gesture events do not fire.
    //    Mouse and touch messages are dispatched according to the Windows 7 input model.
    //    Touch selection follows the Windows 7 model ("drag to select") instead of the Windows 8 model ("tap to select").
    //    Hardware accelerated panning and zooming is disabled.
    //    The Zoom and Pan Cascading Style Sheets (CSS) properties are ignored.
    // The FEATURE_NINPUT_LEGACYMODE feature control determines whether the legacy input model is enabled
    // Default: ENABLED
    SetBrowserFeatureControlKey(L"FEATURE_NINPUT_LEGACYMODE", fileName, 0);

    // Internet Explorer 7 consolidated HTTP compression and data manipulation into a centralized component in order to improve performance and
    // to provide greater consistency between transfer encodings (such as HTTP no-cache headers). For compatibility reasons, the original
    // implementation was left in place. When the FEATURE_DISABLE_LEGACY_COMPRESSION feature is disabled, the original compression implementation
    // is used.
    // Default: ENABLED
    // SetBrowserFeatureControlKey(L"FEATURE_DISABLE_LEGACY_COMPRESSION", fileName, 1);

    // When the FEATURE_LOCALMACHINE_LOCKDOWN feature is enabled, Internet Explorer applies security restrictions on content loaded from the
    // user's local machine, which helps prevent malicious behavior involving local files:
    //    Scripts, Microsoft ActiveX controls, and binary behaviors are not allowed to run.
    //    Object safety settings cannot be overridden.
    //    Cross-domain data actions require confirmation from the user.
    // Default: DISABLED
    // SetBrowserFeatureControlKey(L"FEATURE_LOCALMACHINE_LOCKDOWN", fileName, 0);

    // Internet Explorer 7 and later. When enabled, the FEATURE_BLOCK_LMZ_??? feature allows ??? stored in the Local Machine zone to be
    // loaded only by webpages loaded from the Local Machine zone or by webpages hosted by sites in the Trusted Sites list. For more information,
    // see Security and Compatibility in Internet Explorer 7.
    // Default: DISABLED
    //    FEATURE_BLOCK_LMZ_IMG can block images that try to load from the user's local file system. To opt in, add your process name and set 
    //                          the value to 0x00000001.
    //    FEATURE_BLOCK_LMZ_OBJECT can block objects that try to load from the user's local file system. To opt in, add your process name and
    //                          set the value to 0x00000001.
    //    FEATURE_BLOCK_LMZ_SCRIPT can block script access from the user's local file system. To opt in, add your process name and set the value
    //                          to 0x00000001.
    // SetBrowserFeatureControlKey(L"FEATURE_BLOCK_LMZ_OBJECT", fileName, 0);
    // SetBrowserFeatureControlKey(L"FEATURE_BLOCK_LMZ_OBJECT", fileName, 0);
    // SetBrowserFeatureControlKey(L"FEATURE_BLOCK_LMZ_SCRIPT", fileName, 0);

    // Internet Explorer 8 and later. When enabled, the FEATURE_DISABLE_NAVIGATION_SOUNDS feature disables the sounds played when you open a
    // link in a webpage.
    // Default: DISABLED
    SetBrowserFeatureControlKey(L"FEATURE_DISABLE_NAVIGATION_SOUNDS", fileName, 1);

    // Windows Internet Explorer 7 and later. Prior to Internet Explorer 7, href attributes of a objects supported the javascript prototcol;
    // this allowed webpages to execute script when the user clicked a link. For security reasons, this support was disabled in Internet
    // Explorer 7. For more information, see Event 1034 - Cross-Domain Barrier and Script URL Mitigation.
    // When enabled, the FEATURE_SCRIPTURL_MITIGATION feature allows the href attribute of a objects to support the javascript prototcol. 
    // Default: DISABLED
    SetBrowserFeatureControlKey(L"FEATURE_SCRIPTURL_MITIGATION", fileName, 1);

    // For Windows 8 and later, the FEATURE_SPELLCHECKING feature controls this behavior for Internet Explorer and for applications hosting
    // the web browser control (WebOC). When fully enabled, this feature automatically corrects grammar issues and identifies misspelled words
    // for the conditions described earlier.
    //    (DWORD) 00000000 - Features are disabled.
    //    (DWORD) 00000001 - Features are enabled for the conditions described earlier. (This is the default value.)
    //    (DWORD) 00000002 - Features are enabled, but only for elements that specifically set the spellcheck attribute to true.
    SetBrowserFeatureControlKey(L"FEATURE_SPELLCHECKING", fileName, 0);

    // When enabled, the FEATURE_STATUS_BAR_THROTTLING feature limits the frequency of status bar updates to one update every 200 milliseconds.
    // Default: DISABLED
    SetBrowserFeatureControlKey(L"FEATURE_STATUS_BAR_THROTTLING", fileName, 1);

    // Internet Explorer 7 or later. When enabled, the FEATURE_TABBED_BROWSING feature enables tabbed browsing navigation shortcuts and
    // notifications. For more information, see Tabbed Browsing for Developers.
    // Default: DISABLED
    // SetBrowserFeatureControlKey(L"FEATURE_TABBED_BROWSING", fileName, 1);

    // When enabled, the FEATURE_VALIDATE_NAVIGATE_URL feature control prevents Windows Internet Explorer from navigating to a badly formed URL.
    // Default: DISABLED
    SetBrowserFeatureControlKey(L"FEATURE_VALIDATE_NAVIGATE_URL", fileName, 1);

    // When enabled,the FEATURE_WEBOC_DOCUMENT_ZOOM feature allows HTML dialog boxes to inherit the zoom state of the parent window.
    // Default: DISABLED
    SetBrowserFeatureControlKey(L"FEATURE_WEBOC_DOCUMENT_ZOOM", fileName, 1);

    // The FEATURE_WEBOC_POPUPMANAGEMENT feature allows applications hosting the WebBrowser Control to receive the default Internet Explorer
    // pop-up window management behavior.
    // Default: ENABLED
    SetBrowserFeatureControlKey(L"FEATURE_WEBOC_POPUPMANAGEMENT", fileName, 0);

    // Applications hosting the WebBrowser Control should ensure that window resizing and movement events are handled appropriately for the
    // needs of the application. By default, these events are ignored if the WebBrowser Control is not hosted in a proper container. When enabled,
    // the FEATURE_WEBOC_MOVESIZECHILD feature allows these events to affect the parent window of the application hosting the WebBrowser Control.
    // Because this can lead to unpredictable results, it is not considered desirable behavior.
    // Default: DISABLED
    // SetBrowserFeatureControlKey(L"FEATURE_WEBOC_MOVESIZECHILD", fileName, 0);

    // The FEATURE_ADDON_MANAGEMENT feature enables applications hosting the WebBrowser Control
    // to respect add-on management selections made using the Add-on Manager feature of Internet Explorer.
    // Add-ons disabled by the user or by administrative group policy will also be disabled in applications that enable this feature.
    SetBrowserFeatureControlKey(L"FEATURE_ADDON_MANAGEMENT", fileName, 0); 

    // Internet Explorer 10. When enabled, the FEATURE_WEBSOCKET feature allows script to create and use WebSocket objects.
    // The WebSocketobject allows websites to request data across domains from your browser by using the WebSocket protocol.
    // Default: ENABLED
    SetBrowserFeatureControlKey(L"FEATURE_WEBSOCKET", fileName, 1);

    // When enabled, the FEATURE_WINDOW_RESTRICTIONS feature adds several restrictions to the size and behavior of popup windows:
    //    Popup windows must appear in the visible display area.
    //    Popup windows are forced to have status and address bars.
    //    Popup windows must have minimum sizes.
    //    Popup windows cannot cover important areas of the parent window.
    // When enabled, this feature can be configured differently for each security zone by using the URLACTION_FEATURE_WINDOW_RESTRICTIONS URL
    // action flag. 
    // Default: ENABLED
    SetBrowserFeatureControlKey(L"FEATURE_WINDOW_RESTRICTIONS", fileName, 0);

    // Internet Explorer 7 and later. The FEATURE_XMLHTTP feature enables or disables the native XMLHttpRequest object.
    // Default: ENABLED
    // SetBrowserFeatureControlKey(L"FEATURE_XMLHTTP", fileName, 1);
  }
}

static LONG GetDWORDRegKey(HKEY hKey, const std::wstring &strValueName, DWORD &nValue, DWORD nDefaultValue) {
  nValue = nDefaultValue;
  DWORD dwBufferSize(sizeof(DWORD));
  DWORD nResult(0);
  LONG nError = ::RegQueryValueExW(hKey, strValueName.c_str(), 0, NULL, reinterpret_cast<LPBYTE>(&nResult), &dwBufferSize);
  if (ERROR_SUCCESS == nError) {
    nValue = nResult;
  }

  return nError;
}

static LONG GetStringRegKey(HKEY hKey, const std::wstring &strValueName, std::wstring &strValue, const std::wstring &strDefaultValue) {
  strValue = strDefaultValue;
  WCHAR szBuffer[512];
  DWORD dwBufferSize = sizeof(szBuffer);
  ULONG nError;
  nError = RegQueryValueExW(hKey, strValueName.c_str(), 0, NULL, (LPBYTE)szBuffer, &dwBufferSize);
  if (ERROR_SUCCESS == nError) {
    strValue = szBuffer;
  }
  return nError;
}

static DWORD GetBrowserEmulationMode() {
  int browserVersion = 7;
  wstring sBrowserVersion;
  HKEY key;
  bool success = true;
  BYTE data[256];
  wstring path(L"SOFTWARE\\Microsoft\\Internet Explorer");
  LONG nError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, path.c_str(), 0, KEY_QUERY_VALUE, &key);
  DWORD mode = 10000; // Internet Explorer 10. Webpages containing standards-based !DOCTYPE directives are displayed in IE10 Standards mode. Default value for Internet Explorer 10.

  if (nError != ERROR_SUCCESS) {
    success = false;
  } else {
    nError = GetStringRegKey(key, L"svcVersion", sBrowserVersion, L"7");
    if (nError != ERROR_SUCCESS) {
      nError = GetStringRegKey(key, L"version", sBrowserVersion, L"7");
      if (nError != ERROR_SUCCESS) {
        success = false;
      }
    }

   if (RegCloseKey(key) != ERROR_SUCCESS) {
      success = false;
    }
  }

  if (success) {
    browserVersion = std::atoi(split(WString2string(sBrowserVersion), '.').at(0).c_str()); // convert base 16 number in s to int

    switch (browserVersion) {
    case 7:
      mode = 7000; // Webpages containing standards-based !DOCTYPE directives are displayed in IE7 Standards mode. Default value for applications hosting the WebBrowser Control.
      break;
    case 8:
      mode = 8000; // Webpages containing standards-based !DOCTYPE directives are displayed in IE8 mode. Default value for Internet Explorer 8
      break;
    case 9:
      mode = 9000; // Internet Explorer 9. Webpages containing standards-based !DOCTYPE directives are displayed in IE9 mode. Default value for Internet Explorer 9.
      break;
    default:
      // use IE10 mode by default
      break;
    }

  } else {
    mode = -1;
  }

  return mode;
}
Great answered 27/1, 2014 at 13:17 Comment(4)
Would this apply to all applications that are run, not just yours?Ashworth
// FeatureControl settings are per-processGreat
Ahh, my bad, I just barely skimmed it the first time, for those playing at home, it's the GetModuleFileNameW part, I also read some other articles about it, we reference our app with something like "myapp.exe".Ashworth
You're right, in case you're in a dll, maybe you could pass it as a function argument and even create a sepparate function to get the name... This was a little straight forward case :)Great

© 2022 - 2024 — McMap. All rights reserved.