HOWTO: Script ActiveX controls from Internet Explorer

Article translations Article translations
Article ID: 555687 - View products that this article applies to.
Author: Alvin Bruney MVP
Expand all | Collapse all

SUMMARY

This article describes the steps needed to automate any application from Internet Explorer using scripting.

Abstract

Any application running on the client computer can be automated from a web page. The following article will provide detailed steps on accomplishing this using ASP.NET and C# and scripting. The approach shows how to fire events inside the ActiveX control and catch and respond to these events in Internet Explorer.



Firing and sinking events in Internet Explorer

When a managed ActiveX control is embedded in a web form, it is important to understand that the events that fire in the ActiveX control do not execute on the server. It may appear to do so because the code is written in the code-behind. However, the code is actually firing on the client inside the ActiveX control. The subtle difference means that sinking, or handling these events in the web browser is possible. The proof of concept will automate Windows Media on the client causing the application to load an incorrect file. The incorrect file will trigger a Windows media error inside the ActiveX control. The code will propagate the error event to Internet Explorer.
 
Create the user control.
     Open Microsoft Visual Studio 2005 (Microsoft Visual Studio 2003 may be used also). Create a Windows Control Library project. Call it ActiveXControl. Add a button named "Fire" with title set to "Start". Add a label above the button. Set the text property to "Press to begin". Here is the complete code.
 
            
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace IEWinEvents
{
         //this class is used to make error messages available on the client
         publicclassErrObject
         {
              privatestring _msg;
 
              public ErrObject(string str)
              {
                      _msg = str;
              }
 
              //public properties enable javascript to access the internal class members on the client
              publicstring Message
              {
                  get { return _msg; }
                  set { _msg = value; }
             }
        }
 
        //delegate to handle error condition
        publicdelegatevoidErrorEventHandler(object e);
        [GuidAttribute("9819EE05-86A4-43a8-AF62-A7AFFA69AB1B")]
        [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)]
        publicinterfaceControlEvents
        {
                  //Add a DispIdAttribute to any members in the source interface to specify the COM DispId.
                  [DispIdAttribute(0x60020000)]
                  void ErrorEvent(object e);
        }
 
        [ClassInterface(ClassInterfaceType.None), ComSourceInterfaces(typeof(ControlEvents))]
        publicpartialclassActiveXControl : UserControl
        {
              event IEWinEvents.ErrorEventHandler ErrorEvent;
              privatestatic WMPLib.WindowsMediaPlayer Player;
              public ActiveXControl() : base()
              {
                   InitializeComponent();
              }
 
              privatevoid Start_Click(object sender, EventArgs e)
              {
                      Player = new WMPLib.WindowsMediaPlayer();
                      Player.MediaError += new WMPLib._WMPOCXEvents_MediaErrorEventHandler(Player_MediaError);
                      Player.URL = "invalidFile.wma";
                      Player.controls.play();
                      Player.uiMode = "mini";
              }
 
              void Player_MediaError(object pMediaObject)
              {
                   //display a message
                   MessageBox.Show("Failed");
 
                   notify all subscribers including IE sinks
                   if (ErrorEvent != null)
                   {
                        ErrorEvent(newErrObject("Invalid file name"));
                   }
               }
        }
}


 
  • Add a reference to the project for Microsoft Windows Media player. To do this, right click the project in Microsoft Visual Studio solutions explorer and choose Add reference. In the COM tab, select Windows Media Player and click OK.
 
  • Run the application in Visual Studio .NET. The ActiveX container will appear with the windows user control embedded in it. Click on the Start button. The application displays a message box indicating "Failed". This is expected behavior. If you examine the code, you will notice that the MediaError event is wired to the Player_MediaError event handler that contains the MessageBox.
 
  • The previous step creates the client application. The next step is to embed this application in a web form. After embedding the control in a web form, the application will execute on the client. It will not execute on the server. It is important to understand this difference. The application does not automate Windows Media on the server.
 
  • Create a web application called IEWinEvents using Microsoft Visual Studio 2005. You may use Microsoft Visual Studio 2003 as well. Accept the defaults. Navigate to the html view of default.aspx and add the following tag.
 

<%@PageLanguage="C#"AutoEventWireup="true"CodeBehind="Default.aspx.cs"Inherits="IEWinEvents._Default" %>
<!DOCTYPEhtmlPUBLIC"-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<htmlxmlns="http://www.w3.org/1999/xhtml">
<headid="Head1"runat="server">
         <title>MMT ActiveX POC</title>
</head>
<body>
<fontface=arialsize=1>
        <OBJECTid="myControl1"name="myControl1" classid="http://localhost/IEWin/ActiveXControl.dll#ActiveXControl.UserControl1"></OBJECT>
</font>
<scriptfor=myControl1event="ErrorEvent(e)"language="javascript">
           function myControl1::ErrorEvent(e)
           {
                    alert('Windows media reports an error: ' + e.Message);
           }
</script>
<formid="form1"runat="server"></form>
</body>
</html>

 
The object tag contains the classid that points to a fully qualified name of the assembly. The fully qualified name is necessary to locate the control when IIS serves the request. Do not use localhost in the fully qualified name otherwise the run-time will not be able to find and load the managed ActiveX control when used from another client computer. For illustration purposes, the code uses localhost.
 
  •  Navigate to the bin\debug folder of ActiveXControl project created in the earlier steps above. Open AssemblyInfo.cs file and set  [assembly: ComVisible(true)]. Rebuild the project. The setting allows .NET assemblies to interact with COM objects. Copy the freshly built assemblies. Paste these assemblies into the same directory of IEWinEvents. It's important that the dll's and default.aspx file reside in the same place. All the *.dll files should be copied. Note: the copied dll's must not be placed in the \bin directory.
 
  •  Create a Virtual directory pointing to the aspx file from IIS manager (inetmgr). Request the page from Internet Explorer. The control should display. If the control does not display, verify that the assemblies are in the same directory as the default.aspx page. Verify also that the classid path points to the assembly. Verify that the virtual directory points to the correct physical directory containing the aspx file and assemblies.
 
  •  Click on the Start button. You should see the "Failed" message box fired from inside the ActiveX control. This is immediately followed by 'Windows media reports an error: Invalid file used".  You'll notice here that messages can be passed from the ActiveX control to the client script as the application demonstrates. This is the reason for the private class ErrObject. Notice also that the events void ErrorEvent(object e); and publicdelegatevoidErrorEventHandler(object e); delegate must match exactly for the events to sink properly. Incorrectly matched events and delegates simply fail to sink, there is no compile time error checking done by Visual Studio.
 
A Few Notes:
  • Use this technique when you are certain that the automated component is available on the end-user system, for instance, all desktops within the enterprise are running Microsoft Windows Media. Also, this technique may be used to automate client side objects without using scripting. However, you may still combine the approach with scripting if you want to automate the control from the web browser.
  • Automating applications may fail if an html file is used instead of an aspx page. This is because the framework is required to handle these automation requests.
  • There may be a file not found error when the Start button is clicked. If you examine the details of the exception, it shows that the CLR is trying to load the Windows Media assembly at http://servername/tester. You must add the Windows Media assembly to that exact location.
  • During development, you may need to purge the download cache occasionally to keep your user interface up to date. Run gacutil /cdl at a Visual Studio .NET 2005 command prompt.
  • By default, Internet Explorer does not allow ActiveX controls to run. From the Internet Explorer tools tab, select options.
          Examine the ActiveX settings and modify appropriately to allow ActiveX controls to execute.
  • Managed ActiveX controls require CAS policy in order to execute. To add the appropriate CAS policy, run mscorcfg.msc from the start > run menu. Note that the security policy setup by default is sufficient to cause the ActiveX control to run. In any case, add the appropriate full trust permissions set to the LocalIntranet_Zone under Code Groups in the Machine Node of the Runtime Security Policy.
  • Security issues can be diagnosed by temporarily turning CAS policy off on the machine. At the command prompt >caspol -s off. Request the page. If the page does not render, the issue is not related to security. In that case, use fusion log viewer - fuslogvw - at a command prompt to diagnose the problem.
  • In a small number of cases, the GUID may not be unique if you copied and pasted the example. Simply use guidgen to generate a new GUID for the application.

Properties

Article ID: 555687 - Last Review: August 9, 2006 - Revision: 1.0
APPLIES TO
  • Microsoft Windows Media Player 7.1
  • Microsoft Office 2000 Professional Edition
  • Microsoft Office Professional Edition 2003
  • Microsoft Office XP Professional Edition
  • Microsoft Windows Media Player 8.01
COMMUNITY SOLUTIONS CONTENT DISCLAIMER
MICROSOFT CORPORATION AND/OR ITS RESPECTIVE SUPPLIERS MAKE NO REPRESENTATIONS ABOUT THE SUITABILITY, RELIABILITY, OR ACCURACY OF THE INFORMATION AND RELATED GRAPHICS CONTAINED HEREIN. ALL SUCH INFORMATION AND RELATED GRAPHICS ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT AND/OR ITS RESPECTIVE SUPPLIERS HEREBY DISCLAIM ALL WARRANTIES AND CONDITIONS WITH REGARD TO THIS INFORMATION AND RELATED GRAPHICS, INCLUDING ALL IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, WORKMANLIKE EFFORT, TITLE AND NON-INFRINGEMENT. YOU SPECIFICALLY AGREE THAT IN NO EVENT SHALL MICROSOFT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, PUNITIVE, INCIDENTAL, SPECIAL, CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF USE, DATA OR PROFITS, ARISING OUT OF OR IN ANY WAY CONNECTED WITH THE USE OF OR INABILITY TO USE THE INFORMATION AND RELATED GRAPHICS CONTAINED HEREIN, WHETHER BASED ON CONTRACT, TORT, NEGLIGENCE, STRICT LIABILITY OR OTHERWISE, EVEN IF MICROSOFT OR ANY OF ITS SUPPLIERS HAS BEEN ADVISED OF THE POSSIBILITY OF DAMAGES.

Give Feedback

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com