Friday, April 27, 2007

Windows Forms Controls in IE Troubleshooting Guide

This post covers troubleshooting information for issues with loading .Net Windows Forms Usercontrols in Internet Explorer. IE in many cases does not provide clear error reporting when something goes wrong with loading a Windows Forms control embedded in a web page; the information here is presented to hopefully act as an aid in troubleshooting such issues.

For information on the general technique of embedding Windows Forms controls in web pages via <object> tags for viewing in Internet Explorer, take a look at these tutorials:

Tip: Viewing Fusion Bind errors from Internet Explorer

When a Windows Forms control fails to initially load properly, one or more "fusion bind errors" with information that may be helpful in diagnosing the problem may be logged.

Viewing fusion bind errors generated from errors loading .Net controls in Internet Explorer:

  • Open the Temporary Internet Files folder in an Explorer window. (One way to do this is from Internet Explorer, select Tools | Options; on the Internet Options dialog, on the General tab, next to "Browsing History", click Settings; on the Temporary Internet Files and History Settings dialog, click "View files".)
  • In the Temporary Internet Files explorer folder, sort by the Last Modified column to bring recent fusion bind error files to the top.
  • Look for files named "?FusionBindError ...". You can't double-click these files to view them; instead, open a new Internet Explorer window, and drag one of the Fusion Bind Error files to the new window to view the contents.

Setting up .Net framework trust to allow Windows Forms controls hosted in a web page on a remote web server to run

For .Net controls embedded in web pages that perform certain types of operations, .Net framework code access security trust must be set up to allow the control to load and run; if this is not done, the security policy of the .Net framework on the client machine will prevent the control from loading.

If a .Net control does fail to load due to load due to .Net trust not being set up properly, the symptom will be an empty rectangle with a "colorful icon" present in the top-left corner displayed on the web page in place of the control. (See the FAQ section below.)

In an internal corporate / LAN environment, trust can be granted to the web server hosting the web page that includes the .Net control. This can be done from the client machine by using the Microsoft .Net Framework Configuration tool (if it is installed), or from the command line by using the caspol.exe utility.

Granting .Net trust to a specific web server with the Microsoft .Net Framework Configuration tool

This tool is not installed on all machines. (I'm not sure when/how the tool does get installed on machines where it is present.) On machines where the tool is present, it can be found in the Administrative Tools folder as "Microsoft .NET 2.0 Configuration", where "2.0" is the actual installed version of the .Net framework.

Be sure to set up trust using the version of the tool that matches the .Net version which Internet Explorer will be using to load and run .Net controls. (In most cases, this will be newest version of the .Net framework installed on the machine.)

Setting up .Net framework trust on a single client machine for controls running on a particular web server:

  • Drill to .NET Framework Configuration | My Computer | Runtime Security Policy | Machine | Code Groups | All_Code.
  • Right-click All_Code and choose New from the context menu.
  • In the Create Code Group dialog that appears, enter a name for the new code group, then click Next. (The name can be anything, but I suggest using the name of the web server machine for which trust is to be established.)
  • In step 2 ("Choose a condition type"), select URL from the dropdown; in the URL field that appears, enter "http://mywebserver/*", where mywebserver is the actual name of the web server to trust. (If you use SSL to connect to the web server, enter "https" instead of "http".)
  • In step 3 ("Assign a Permission Set to the Code Group"), check the "Use existing permission set" radio button and select "FullTrust" from the dropdown. Click Next.
  • Click Finish on the final step of the Wizard.

Granting .Net trust to a specific web server with the caspol.exe command-line utility

Caspol.exe is a command-line code access security policy tool that is installed with the .Net framework. Caspol.exe is located at:

%SystemRoot%\Microsoft.NET\Framework\v2.0.50727\caspol.exe

Where 2.0.50727 is the version number of the .Net framework installed on the client machine that IE is using to load the control. (2.0.50727 is the version number of the commercial release of the 2.0 .Net framework.)

Run the following command to establish .Net framework trust for a web server named serverName:

caspol -machine -addgroup 1 -url http://serverName/* FullTrust -name "http://serverName"

To view existing trust group settings set up on the local client machine, use:

caspol -lg

Regardless of which method is used to establish trust, after setting up trust for the web server, you'll need to close and re-open Internet Explorer to get it to pick up new trust setting.

The remainder of this document takes a FAQ format, with problems/issues in boldface and possible resolutions in plain type.

The "Colorful Icon" Issue

When attempting to load a Windows Forms control, the control does not appear; instead, a white box with a thin black outline appears in place of the control, with a colorful icon in the top-left corner.

A Windows Forms control that has failed to load, showing the "colorful icon"

Q: A Fusion Bind error is logged with this text: "System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Security.VerificationException: Operation could destabilize the runtime."

A: The most common cause of this problem is that the control requires .Net Framework trust to run, but trust has not been granted to the server hosting the control, or to the control itself, by the client machine (the computer where Internet Explorer is running). See "Setting up .Net framework trust" above.

Other general things to check for a control failing to load with the "colorful icon" symptom:

A: The client machine might be configured to not trust unsigned .Net or ActiveX controls in IE | Tools menu | Internet Options | Security tab. (Not sure about the exact setting.) Adding the web server to "Trusted Sites" on the client will generally fix this. (This seems particularly common when the client is Windows 2003 Server.)

A: If the class constructor of the .Net control is throwing an uncaught exception, this behavior will occur. Try stepping through the constructor in a debugger (assuming the control is one you are developing).

A: Try clearing the Temporary Internet Files on the client machine (especially if some .Net components in the browser are working, but not others).

A: If the same browser window was previously used to bring up the same .Net control from a different virtual directory on the server machine, close the browser window and use a new one.

A: There could be something invalid or malformed in the client machine's machine.config file.

A: There could be an invalid or malformed iexplore.exe.config file present in the same folder as the Internet Explorer executable (typically C:\Program Files\Internet Explorer\). Try temporarily renaming the iexplore.exe.config file to something else.

More specific symptoms and resolutions for situations where IE is showing the "colorful icon" in place of the .Net control after the control has failed to load:

Q: Client is connecting to server using SSL (https://...). Connecting to the server using a normal (non-SSL, http://...) connection does load controls correctly (if the server permits non-SSL connections).

A: Ensure that .Net framework trust is set up on the client machine for the web server machine with both the "https://" and "http://" prefixes (2 separate trust entries).

A: In Internet Explorer | Tools | Options | Advanced tab, uncheck "Do not save encrypted pages to disk".

Q: On the server machine, the most recent event in the IIS log is a 401 error trying to load a config file linked from the web page where the .Net control is located using a <LINK REL='Configuration' HREF='/configFile.conf'> tag. No Fusion Bind error is logged on the client.

A: Check the Windows filesystem permissions on the .conf file. Try giving the "Everyone" group full permissions on the file to establish whether or not this is the problem. (If applying "Everyone" permissions does work to resolve the issue, you will probably then wish to remove "Everyone," and apply more fine-grained permissions, to allow IIS to serve the control, but without compromising security.)

A: On the server, in IIS Manager, under File Security for the config file (for that specific file, not the parent virtual directory security), if Anonymous access is checked, ensure that "Allow IIS to control password" is also checked.

Q: Server OS is Windows 2003 Server. Navigating in the browser directly to the config file referenced in the .Net control's web page results in a 404 error (even though the file really is there on the server).

A: In the Internet Information Services Manager utility, open the Properties dialog for the config file's parent virtual directory. In the HTTP Headers tab, click the Mime Types... button, and add the config file's extension (.conf).

Q: A new .Net framework version was recently installed on the client, after which the control started failing to load.

A: Set up trust for the web server machine under the new .Net framework version (as described above).

Q: A Fusion Bind error shows a FileLoadException and error message text that talks about a DLL file version incompatibility. The control may load properly from a different client machine, or when a different user is logged into the OS.

A: Clear the Shadow Cache for the user on the machine where the problem is occurring. (The Shadow Cache is typically located at "C:\Documents and Settings\username\Local Settings\Application Data\assembly\dl?", where ? is a numeral. Delete the entire directory tree under the "dl?" folder to clear the cache. It may be necessary to enable viewing of hidden files/folders to see the cache.)

Q: When using compressed .cab files referenced from a .conf file on the server to deliver the .dll file(s) for the Windows Forms control, a fusion bind error shows "System.IO.FileNotFoundException: File or assembly name ControlType, or one of its dependencies, was not found.

A: This may indicate some problem on the server or client with loading .cab files. One possible cause: The MIME type associated with cabinet files (.cab) is incorrectly set in IIS (HTTP Headers | File Types) to a content type of "application/x-compressed"; the MIME type associated with a .cab file must be "application/octet-stream" for .Net to load the controls from the cab file. In inetmgr, in the HTTP headers tab, click File Types... and fix the setting.

Q: The Fusion Bind Error shows something like "System.TypeLoadException: Could not load type 'Typename' from assembly 'TypeName'"

A: The class name specified in the object tag needs to have correct casing (uppercase/lowercase). In the example above, you would need to change "Typename" to "TypeName".

"Vertical Scrollbar" issues

Q: When attempting to load a Windows Forms control, the control does not appear; instead, a white box with a thin black outline appears in place of the control, with a colorful icon in the top-left corner.

A Windows Forms control that has failed to load, showing the "disabled vertical scrollbar"

A: Check the classid parameter of the control's <object> tag to be sure it is pointing at a valid virtual directory.

A: Make sure that the DLL file referenced in the classid is present in the virtual directory.

A: Rarely, I've seen this issue happen when in on the server, IIS settings (inetmgr), Execute Permissions for the virtual directory is set to "Scripts and Executables". Try setting Execute Permissions to "Scripts only".

A: When debugging an ASP.NET page through Visual Studio 2005, apparently the "ASP.NET Development Server" that Visual Studio 2005 provides for debugging ASP.NET 2.0 apps doesn't support display of Windows Forms controls in the browser. Use the real IIS server on the machine instead. (You can debug the ASP.NET page running in IIS by manually attaching the Visual Studio debugger to the aspnet_wp.exe process once the ASP.NET site has been initially opened in the browser.)

"X" Icon Issues

Q: When attempting to load a .Net control, the control does not appear; instead, a white box with a thin black outline appears in place of the control, with an "X" icon in the top-left corner.

A Windows Forms control that has failed to load, showing the "X" icon

A: Make sure that the .Net framework has been installed on the client machine.

A: Check that a classid parameter is present in the <object> tag in the HTML source of the web page where the control is located.

A: Check the primary DLL file of the assembly that the control is attempting to load. (I've seen this happen in a contrived case when a control was trying to use a .dll file with file size 0.)

Other Issues

Q: When attempting to load a .Net control, an error dialog appears: "Your current security settings prohibit running ActiveX controls on this page. As a result, the page may not display correctly." After the dialog is dismissed, the control does not appear on the page at all.

A: In Internet Explorer, go to Tools | Internet Options | Security tab. Running signed ActiveX controls needs to be allowed for the "zone" that the web server is in; the zone settings can be changed to "Medium", or the web server can be added to a more trusted zone ("Local intranet" or "Trusted sites").

Q: After a .Net control loads, it appears correctly, but the user needs to click the control before it can be interacted with. Before the control is "activated", a tooltip appears when the mouse is hovered over the control with text "Press SPACEBAR or ENTER to activate and use this control" or text "Click to activate and use this control".

A: This issue is caused by a change that Microsoft was forced to introduce in Internet Explorer due to patent litigation between Microsoft and Eolas. For details and workarounds, see the article Activating ActiveX Controls on MSDN.

Q: When attempting to load a .Net control, the control does not appear; instead, a solid gray box with no error message text appears.

A: Check the syntax of the <object> tag in the HTML source. IE is probably not recognizing it as an attempt to show a Windows Forms control.

Scripting Issues

Q: When calling a public API method on a .Net control from Javascript running on the web page, the Javascript error "Object doesn't support this property or method" occurs.

A: The .Net control probably didn't load successfully. (This may be non-obvious if the control is hidden on the page.)

Q: A script call to a .Net control fails with the Javascript error message "Unexpected call to method or property access."

A: Apparently IE doesn't support child windows directly calling methods in Windows Forms controls located in a browser parent window (using syntax like "window.opener.document.ControlID.Method()") . As a workaround, rewrite the script to call a Javascript function on the parent page, then have the new function make the actual call to the .Net control.

Q: A script call to a .Net control fails with the Javascript error message "Invalid procedure call or argument."

A: The script code may be calling the method with an incorrect number of method parameters.

Debugging Issues

Q: After making a code change to the .Net Usercontrol and rebuilding, the changes made are not reflected in the browser window, even after refreshing the page.

A: Close the current browser window, and reopen the web page in a new one.

Q: Can't hit breakpoints in the Visual Studio debugger when debugging a .NET Windows Forms object in the browser.

A: If launching the browser directly from Visual Studio, in Project Properties, on the Debug tab, make sure "Start external program" (pointing to iexplore.exe) is checked, not "Start browser with URL".

A: Make sure the DLL files used in the page being debugged are debug (not release) versions.

Q: When the Visual Studio 2003 .Net debugger is attached to an iexplore.exe instance, as soon as a .Net control starts loading, the browser closes and debugging ends. Both .Net 1.1 and 2.0 (or a later version) are installed on the machine. Q: Can't attach the VS.NET 2003 debugger to an iexplore.exe instance which is already running a .NET control.

A: Visual Studio 2003 can only debug .Net version 1.1 (not 2.0 or later versions), so you need to force IE to load controls using the 1.1 .Net framework. Create a new file named iexplore.exe.config in the Internet Explorer folder (the folder where iexplore.exe is located) with the following content:

<configuration>
 <startup>
   <requiredRuntime version="v1.1.4322"/>
   <supportedRuntime version="v1.1.4322"/>
 </startup>
</configuration>

This will force Internet Explorer to load any .Net controls that it encounters in web pages in the 1.1 version of the .Net framework, beginning with the next time a fresh instance of Internet Explorer is opened.

When finished debugging in Visual Studio .Net 2003, remove the iexplore.exe.config file to permit .Net controls (and possibly also Internet Explorer extensions) which require .Net 2.0 to run properly once again.

The information in this post is current as of Internet Explorer 7 and the .Net framework 2.0.

Please note that this is not a comprehensive guide to all possible issues that may occur with running .Net Usercontrols in Internet Explorer; also, the troubleshooting suggestions here may not work to resolve a given issue in all cases. Please use caution when making configuration changes to your system (particularly security-related changes)!