I'm using the WebBrowser control in a C# WPF application. I need to execute the Paste command programmatically, and I do this using the following statement:
WebBrowser.Document.ExecCommand("paste", false, null);
This works perfectly on my local machine; however, it does not work in our production environment. The command simply does nothing. Luckily, I've determined the cause of this problem to be an IE security restriction, based on this post.
The fix is to modify the security level in IE to be medium (Tools > Internet Options > security > Internet > Medium level).
By following the answer from that post, the problem can be fixed. However, in our production environment, the IE security settings are set to high and cannot be modified because of security policies. So this fix cannot be used.
I have seen another post about adding a custom security mananger, and this sounds like a possible fix for this problem.
However, I've been unable to determine exactly which IInternetSecurityManager methods I need to implement or how to implement them. I've defined the interface and I've gotten the methods to be called, but I'm currently just returning INET_E_DEFAULT_ACTION for all of them.
public class MyWebBrowser : WebBrowser
{
protected override WebBrowserSiteBase CreateWebBrowserSiteBase()
{
return new ExtendedWebBrowserSite(this);
}
protected class ExtendedWebBrowserSite : WebBrowserSite, IInternetSecurityManager, IServiceProvider
{
private static readonly Guid SID_IInternetSecurityManager = new Guid("79EAC9EE-BAF9-11CE-8C82-00AA004BA90B");
WebBrowser _host;
public ExtendedWebBrowserSite(WebBrowser host) : base(host)
{
_host = host;
}
public int QueryService(ref Guid guidService, ref Guid riid, out IntPtr ppvObject)
{
if (guidService == SID_IInternetSecurityManager && riid == SID_IInternetSecurityManager)
{
ppvObject = Marshal.GetComInterfaceForObject(this, typeof(IInternetSecurityManager));
return HRESULTS.S_OK;
}
ppvObject = IntPtr.Zero;
return HRESULTS.E_NOINTERFACE;
}
#region IInternetSecurityManager Implementation
public int SetSecuritySite([In] IntPtr pSite)
{
return URLMonikerErrorCodes.INET_E_DEFAULT_ACTION;
}
public int GetSecuritySite([Out] IntPtr pSite)
{
return URLMonikerErrorCodes.INET_E_DEFAULT_ACTION;
}
public int MapUrlToZone([In, MarshalAs(UnmanagedType.LPWStr)] string pwszUrl, out uint pdwZone, uint dwFlags)
{
pdwZone = 0;
return URLMonikerErrorCodes.INET_E_DEFAULT_ACTION;
}
public int GetSecurityId([MarshalAs(UnmanagedType.LPWStr)] string pwszUrl, [MarshalAs(UnmanagedType.LPArray)] byte[] pbSecurityId, ref uint pcbSecurityId, uint dwReserved)
{
return URLMonikerErrorCodes.INET_E_DEFAULT_ACTION;
}
public int ProcessUrlAction([In, MarshalAs(UnmanagedType.LPWStr)] string pwszUrl, uint dwAction, out byte pPolicy, uint cbPolicy, byte pContext, uint cbContext, uint dwFlags, uint dwReserved)
{
pPolicy = 0;
return URLMonikerErrorCodes.INET_E_DEFAULT_ACTION;
}
public int QueryCustomPolicy([In, MarshalAs(UnmanagedType.LPWStr)] string pwszUrl, ref Guid guidKey, ref byte ppPolicy, ref uint pcbPolicy, ref byte pContext, uint cbContext, uint dwReserved)
{
return URLMonikerErrorCodes.INET_E_DEFAULT_ACTION;
}
public int SetZoneMapping(uint dwZone, [In, MarshalAs(UnmanagedType.LPWStr)] string lpszPattern, uint dwFlags)
{
return URLMonikerErrorCodes.INET_E_DEFAULT_ACTION;
}
public int GetZoneMappings(uint dwZone, out IEnumString ppenumString, uint dwFlags)
{
ppenumString = null;
return URLMonikerErrorCodes.INET_E_DEFAULT_ACTION;
}
#endregion IInternetSecurityManager Implementation
}
}
Which methods should I be implementing in order to fix the paste feature, and how?