Issue With WPF WebBrowser Control When Emulation >

2019-08-15 19:02发布

问题:

I have a C#/WPF application that uses a WebBrowser control that presents a website as it's primary interface (for a kiosk). The website can call a C# method via javascript for some native processing. Everything works fine until I set the 'FEATURE_BROWSER_EMULATION' above IE7 (using the code below). When I do the javascript call to the native method does not get called unless I run the website from 'http://localhost' which works fine.

I'm assuming this is a security issue. I've messed with all of the security settings in IE (including setting the site as a 'Trusted Site'), but I can't seem to get it working.

Coding I'm using the set the emulation:

private void SetBrowserCompatibilityMode()
    {
        // http://msdn.microsoft.com/en-us/library/ee330720(v=vs.85).aspx

        // FeatureControl settings are per-process
        var fileName = System.IO.Path.GetFileName( Process.GetCurrentProcess().MainModule.FileName );

        if ( String.Compare( fileName, "devenv.exe", true ) == 0 ) // make sure we're not running inside Visual Studio
            return;

        using ( var key = Registry.CurrentUser.CreateSubKey( @"Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION",
            RegistryKeyPermissionCheck.ReadWriteSubTree ) )
        {
            // Webpages containing standards-based !DOCTYPE directives are displayed in IE10 Standards mode.
            UInt32 mode = 11000; // 11000 = IE11, 10000 = IE10, 9000 = IE9, 8000 = IE8, 7000 = IE7; 
            key.SetValue( fileName, mode, RegistryValueKind.DWord );
        }

        using ( var key = Registry.CurrentUser.CreateSubKey( @"Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ZONE_ELEVATION",
            RegistryKeyPermissionCheck.ReadWriteSubTree ) )
        {
            // disable zone elevation prevention
            UInt32 mode = 0;
            key.SetValue( fileName, mode, RegistryValueKind.DWord );
        }

        using ( var key = Registry.CurrentUser.CreateSubKey( @"Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BLOCK_LMZ_SCRIPT",
            RegistryKeyPermissionCheck.ReadWriteSubTree ) )
        {
            // enable <scripts> in local machine zone
            UInt32 mode = 0;
            key.SetValue( fileName, mode, RegistryValueKind.DWord );
        }

        using ( var key = Registry.CurrentUser.CreateSubKey( @"Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_NINPUT_LEGACYMODE",
            RegistryKeyPermissionCheck.ReadWriteSubTree ) )
        {
            // disable Legacy Input Model
            UInt32 mode = 0;
            key.SetValue( fileName, mode, RegistryValueKind.DWord );
        }

    }

回答1:

Disable FEATURE_LOCALMACHINE_LOCKDOWN, FEATURE_BLOCK_LMZ_SCRIPT, FEATURE_BLOCK_LMZ_OBJECT features. You can adapt the working C# code from here. Alternatively, I believe you can use "Mark of Web" to make your scripts run again.



回答2:

try one of these: 1- run your program as administrator. 2- check that your JavaScript is compatible with the version you are emulating as some JavaScript code run on IE7 but not above.

Update: This is how I set the emulation, please note that this code will not work if you do not run it as administrator:

    private static void SetIEVersioneKeyforWebBrowserControl(string appName, int ieval)
    {
        RegistryKey Regkey = null;
        try
        {
            Regkey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION", true);

            //If the path is not correct or 
            //If user't have priviledges to access registry 
            if (Regkey == null)
            {
                _logger.Error("Application FEATURE_BROWSER_EMULATION Failed - Registry key Not found");
                return;
            }

            string FindAppkey = Convert.ToString(Regkey.GetValue(appName));

            //Check if key is already present 
            if (FindAppkey == ieval.ToString())
            {
                _logger.Debug("Application FEATURE_BROWSER_EMULATION already set to " + ieval);
                Regkey.Close();
                return;
            }

            //If key is not present or different from desired, add/modify the key , key value 
            Regkey.SetValue(appName, unchecked((int)ieval), RegistryValueKind.DWord);

            //check for the key after adding 
            FindAppkey = Convert.ToString(Regkey.GetValue(appName));

            if (FindAppkey == ieval.ToString())
            {
                _logger.Info("Application FEATURE_BROWSER_EMULATION changed to " + ieval + "; changes will be visible at application restart");
            }
            else
            {
                _logger.Error("Application FEATURE_BROWSER_EMULATION setting failed; current value is  " + ieval);
            }
        }
        catch (Exception ex)
        {
            _logger.Error("Application FEATURE_BROWSER_EMULATION setting failed; " + ex.Message);
        }
        finally
        {
            //Close the Registry 
            if (Regkey != null) Regkey.Close();
        }
    }

and to use the function:

        var targetApplication = Process.GetCurrentProcess().ProcessName + ".exe";
        int ie_emulation = 9000;