ActiveX控件';的构造函数第二次调用

本文关键字:构造函数 第二次 调用 控件 ActiveX | 更新日期: 2023-09-27 18:28:22

我有几个问题与IIS和ActiveX控件有关。

我正在通过本教程开发一个activeX控件http://haseebakhtar.wordpress.com/2011/05/31/creating-an-activex-control-in-net-using-c/.我使用IE9进行测试,使用VS2010作为IDE。这是代码:

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Drawing;

namespace AxControls
{
    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.None)]
    [Guid("42BBA00A-515E-45b5-9EAF-3827F7AEB4FA")]
    [ProgId("AxControls.HelloWorld")]
    [ComDefaultInterface(typeof(IClip))]
    public class HelloWorld : UserControl, IObjectSafety, IClip
    {
        public HelloWorld()
        {
            MessageBox.Show("Starting");
        }
        [STAThread]
        public Image GetClipboardImage()
        {
            MessageBox.Show("try to get image");
            Image returnImage = null;
            if (Clipboard.ContainsImage())
            {
                MessageBox.Show("getting image");
                returnImage = Clipboard.GetImage();
            }
            return returnImage;
        }
        private void SaveImage(Image image)
        {
            try
            {
                if (image != null)
                {
                    MessageBox.Show("saving image");
                    image.Save("C:''test.jpg");
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.StackTrace);
            }
        }
        public void SaveImgFromClipBoard()
        {
            Image img = GetClipboardImage();
            SaveImage(img);
        }
        #region IObjectSafety Members
        public enum ObjectSafetyOptions
        {
            INTERFACESAFE_FOR_UNTRUSTED_CALLER = 0x00000001,
            INTERFACESAFE_FOR_UNTRUSTED_DATA = 0x00000002,
            INTERFACE_USES_DISPEX = 0x00000004,
            INTERFACE_USES_SECURITY_MANAGER = 0x00000008
        };
        public int GetInterfaceSafetyOptions(ref Guid riid, out int pdwSupportedOptions, out int pdwEnabledOptions)
        {
            ObjectSafetyOptions m_options = ObjectSafetyOptions.INTERFACESAFE_FOR_UNTRUSTED_CALLER | ObjectSafetyOptions.INTERFACESAFE_FOR_UNTRUSTED_DATA;
            pdwSupportedOptions = (int)m_options;
            pdwEnabledOptions = (int)m_options;
            return 0;
        }
        public int SetInterfaceSafetyOptions(ref Guid riid, int dwOptionSetMask, int dwEnabledOptions)
        {
            return 0;
        }
        #endregion
    }
}

这是另一个代码:

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace AxControls
{
    [ComImport()]
    [Guid("5DC2DE9B-8D7D-490e-A904-C8CBFFD38412")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    interface IObjectSafety
    {
        [PreserveSig()]
        int GetInterfaceSafetyOptions(ref Guid riid, out int pdwSupportedOptions, out int pdwEnabledOptions);
        [PreserveSig()]
        int SetInterfaceSafetyOptions(ref Guid riid, int dwOptionSetMask, int dwEnabledOptions);
    }
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace AxControls
{
    [ComVisible(true)]
    [InterfaceType(ComInterfaceType.InterfaceIsDual)]
    [Guid("013BFB31-B3F8-4bae-B5C2-5F6D22B815E3")]
    public interface IClip
    {
        void SaveImgFromClipBoard();
    }
}

我就是这么称呼它的:

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace AxControls
{
    [ComVisible(true)]
    [InterfaceType(ComInterfaceType.InterfaceIsDual)]
    [Guid("013BFB31-B3F8-4bae-B5C2-5F6D22B815E3")]
    public interface IClip
    {
        void SaveImgFromClipBoard();
    }
}

1) 因此,当我刷新页面时,我看到两个带有"开始"的消息框,它们一个接一个地出现。我不明白为什么。我在调试模式下运行它(当然使用IIS+ASP.NET web项目+里面的HTML文件)。这是我构建后的动作

"C:'Program Files (x86)'Microsoft SDKs'Windows'v7.0A'Bin'NETFX 4.0 Tools'x86'gacutil.exe" /f /i "$(TargetDir)$(TargetFileName)"
"C:'Program Files (x86)'Microsoft SDKs'Windows'v7.0A'Bin'NETFX 4.0 Tools'x64'gacutil.exe" /f /i "$(TargetDir)$(TargetFileName)"
"C:'Windows'Microsoft.NET'Framework'v4.0.30319'RegAsm.exe" /unregister "$(TargetDir)$(TargetFileName)"
"C:'Windows'Microsoft.NET'Framework64'v4.0.30319'RegAsm.exe" /unregister "$(TargetDir)$(TargetFileName)"
"C:'Windows'Microsoft.NET'Framework'v4.0.30319'RegAsm.exe" "$(TargetDir)$(TargetFileName)"
"C:'Windows'Microsoft.NET'Framework64'v4.0.30319'RegAsm.exe" "$(TargetDir)$(TargetFileName)"

我甚至尝试在ApacheWeb服务器上使用它,但遇到了同样的情况——构造函数似乎调用了两次。

2) 很多时候,当我在Visual Studio中更改HTML文件并在调试模式下运行时,这些更改在浏览器中是不可见的。我尝试清理IE历史记录和缓存,但没有成功。看起来IIS将其放入缓存中。可以吗?我该如何避免?

3) 我无法理解添加所有IObjectSafety成员的目的。

更新:

<html>
    <head>
        <object name="axHello" style='display:none' id='axHello' classid='CLSID:42BBA00A-515E-45b5-9EAF-3827F7AEB4FA'
 codebase='AxControls.cab#version=1,0,0,0'></object>
      <script language="javascript">
        <!-- Load the ActiveX object  -->
        var x = new ActiveXObject("AxControls.HelloWorld");
        <!-- Display the String in a messagebox ffff-->
        x.SaveImgFromClipBoard();
      </script>
    </head>
    <body>
    </body>
</html>

ActiveX控件';的构造函数第二次调用

现在我们已经看到了您的HTML代码,很明显:您创建了两个独立的对象:一个作为object标记,另一个动态地作为new ActiveXObject("AxControls.HelloWorld")。删除第二个,只需调用:

axHello.SaveImgFromClipBoard();

不要忘记我在评论中对IObjectSafety的注释。最好的做法是将您的控制锁定到您自己的站点。

关于这一点:2)很多时候,当我在Visual Studio中更改HTML文件并在调试模式下运行时,这些更改在浏览器中是不可见的。我尝试清理IE历史记录和缓存,但没有成功。看起来IIS将其放入缓存中。可以吗?我该如何避免

下次发生这种情况时,请关闭所有IE窗口,然后使用Process Explorer检查是否有隐藏的iexplore.exe进程仍在挂起。如果是,请杀死它(所有实例),然后清除缓存。下次它应该加载页面的新版本。

如果发生这种情况,这实际上是一个坏迹象,表明你的控制没有正确关闭(但这将是另一个问题的主题)。