【问题标题】:Menu item clicked ... No reaction单击菜单项...没有反应
【发布时间】:2012-08-06 11:30:27
【问题描述】:

这是一个全新的问题,因为我的领域是 Java 而不是 C#,但我得到了构建 BHO 的任务,并且已经到了需要一个菜单​​项(在工具菜单内)来调用我的函数的地步代码。

我读到我必须声明和实现 IOleCommandTarget 接口,我确实这样做了。现在我需要将同一个类注册为 COM 对象。

显然要做到这一点,我需要使用 [ComRegisterFunction] 声明几个函数,但即使这样做了,我也无法使用 regsvr32 注册它们。并且在使用 DLL 导出查看器进行进一步检查时,这些功能似乎不存在 :(

我做错了什么?

提前谢谢你

编辑:

好的,所以从我得到的 cmets 中,我想我的 COM 对象已正确注册,但我的问题仍然存在:当我单击新创建的菜单项时,我没有反应或无法调试真正发生的事情。

这是我目前的代码:

using System;
using System.Runtime.InteropServices;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SHDocVw;
using MSHTML;
using Microsoft.Win32;
using System.Windows;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.Drawing;
using System.Diagnostics;
using System.Threading;


[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct OLECMDTEXT {
    public uint cmdtextf;
    public uint cwActual;
    public uint cwBuf;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
    public char rgwz;
}

[StructLayout(LayoutKind.Sequential)]
public struct OLECMD {
    public uint cmdID;
    public uint cmdf;
}

// Interop definition for IOleCommandTarget. 
[ComImport,
Guid("b722bccb-4e68-101b-a2bc-00aa00404770"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IOleCommandTarget {
    //IMPORTANT: The order of the methods is critical here. You
    //perform early binding in most cases, so the order of the methods
    //here MUST match the order of their vtable layout (which is determined
    //by their layout in IDL). The interop calls key off the vtable ordering,
    //not the symbolic names. Therefore, if you switched these method declarations
    //and tried to call the Exec method on an IOleCommandTarget interface from your
    //application, it would translate into a call to the QueryStatus method instead.
    void QueryStatus(ref Guid pguidCmdGroup, UInt32 cCmds,
        [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] OLECMD[] prgCmds, ref OLECMDTEXT CmdText);
    void Exec(ref Guid pguidCmdGroup, uint nCmdId, uint nCmdExecOpt, ref object pvaIn, ref object pvaOut);
}

namespace ANAISBHO {

    [
    ComVisible(true),
    Guid("8a194578-81ea-4850-9911-13ba2d71efbd"),
    ClassInterface(ClassInterfaceType.None)
    ]
    public class BHO : IObjectWithSite, IOleCommandTarget {

        public SHDocVw.WebBrowser webBrowser;

        public HTMLDocument document;

        public static string BHOKEYNAME = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Browser Helper Objects";

        private Guid cmdGuid = new Guid("ED016940-BD5B-11CF-BA4E-00C04FD70816");

        private static Bitmap bmpScreenshot;

        private static Graphics gfxScreenshot;


        public void OnDocumentComplete(object pDisp, ref object URL) {
            document = (HTMLDocument) webBrowser.Document;
        }

        //HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Extensions\{GUID}\CLSID
        private static void RegisterCiteNPLMenuEntry() {
            Console.WriteLine("Registrying the CiteNPL menu entry");
            RegistryKey MicrosoftKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Default).OpenSubKey("Software").OpenSubKey("Microsoft");
            RegistryKey ExtensionsKey = MicrosoftKey.OpenSubKey("Internet Explorer").OpenSubKey("Extensions", RegistryKeyPermissionCheck.ReadWriteSubTree);
            String GUID = @"{C3E1CD69-3928-4b69-ABEC-936CA3A3BAAA}";

            ExtensionsKey.CreateSubKey(GUID);
            RegistryKey GUIDKey = ExtensionsKey.OpenSubKey(GUID, RegistryKeyPermissionCheck.ReadWriteSubTree);
            String CLSID_Shell_ToolbarExtExec = @"{1FBA04EE-3024-11d2-8F1F-0000F87ABD16}";
            GUIDKey.SetValue("CLSID", CLSID_Shell_ToolbarExtExec, RegistryValueKind.String);
            GUIDKey.SetValue("MenuText", "CiteNPL", RegistryValueKind.String);
            GUIDKey.SetValue("ClsidExtension", "{c4127d56-7114-46da-a853-6ea1b8a199f7}", RegistryValueKind.String);

            GUIDKey.Close();
            ExtensionsKey.Close();
            MicrosoftKey.Close();
        }


        public void QueryStatus(ref Guid pguidCmdGroup, UInt32 cCmds, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] OLECMD[] prgCmds, ref OLECMDTEXT CmdText) {
            MessageBox.Show("query");
        }

        public void Exec(ref Guid pguidCmdGroup, uint nCmdId, uint nCmdExecOpt, ref object pvaIn, ref object pvaOut) {
            MessageBox.Show("Exec");
        }

        private void TakeScreenshot() {
            int height = 1024; //webBrowser.Document.Body.ScrollRectangle.Height;
            int width = 1024;  //webBrowser.Document.Body.ScrollRectangle.Width;
            //int left = 0;      //webBrowser.Document.Body.ScrollRectangle.Left;
            //int right = 1024;  //webBrowser.Document.Body.ScrollRectangle.Right;
            System.Drawing.Size browserSize = new System.Drawing.Size(width, height);

            bmpScreenshot = new Bitmap(width, height, PixelFormat.Format32bppArgb);
            gfxScreenshot = Graphics.FromImage(bmpScreenshot);
            gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);
            bmpScreenshot.Save("c:\\temp.png", ImageFormat.Png);
        }

        public int SetSite(object site) {
            if(site != null) {
                webBrowser = (SHDocVw.WebBrowser) site;
                webBrowser.DocumentComplete += new DWebBrowserEvents2_DocumentCompleteEventHandler(this.OnDocumentComplete);
            } else {
                webBrowser.DocumentComplete -= new DWebBrowserEvents2_DocumentCompleteEventHandler(this.OnDocumentComplete);
                webBrowser = null;
            }

            return 0;
        }

        public int GetSite(ref Guid guid, out IntPtr ppvSite) {
            IntPtr punk = Marshal.GetIUnknownForObject(webBrowser);
            int hr = Marshal.QueryInterface(punk, ref guid, out ppvSite);
            Marshal.Release(punk);

            return hr;
        }

        [ComRegisterFunction]
        public static void RegisterBHO(Type type) {
            Console.WriteLine("Registering the BHO");

            RegisterCiteNPLMenuEntry();
            RegisterBHOInWindowsRegistry(type);
        }

        [ComUnregisterFunction]
        public static void UnregisterBHO(Type type) {
            Console.WriteLine("Unregistering the BHO");
            UnRegisterBHOFromWindowsRegistry(type);
        }

        private static void UnRegisterBHOFromWindowsRegistry(Type type) {
            RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(BHOKEYNAME, true);
            string guid = type.GUID.ToString("B");

            if(registryKey != null) {
                registryKey.DeleteSubKey(guid, false);
            }
        }

        private static void RegisterBHOInWindowsRegistry(Type type) {
            RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(BHOKEYNAME, true);

            if(registryKey == null) {
                registryKey = Registry.LocalMachine.CreateSubKey(BHOKEYNAME);
            }

            string guid = type.GUID.ToString("B");
            RegistryKey ourKey = registryKey.OpenSubKey(guid);

            if(ourKey == null) {
                ourKey = registryKey.CreateSubKey(guid);
            }

            ourKey.SetValue("Alright", 1);
            registryKey.Close();
            ourKey.Close();
        }
    }
}

【问题讨论】:

    标签: c# internet-explorer com bho regsvr32


    【解决方案1】:

    由于这是一个托管 dll,您不能使用 regsvr32 或“DLL Export Viewer”。

    要为 COM 互操作注册您的 .Net dll,请使用 Regasm

    【讨论】:

    • 好的 regasm 工作,我不太确定它做了什么,但它说它说“类型注册成功”。但是后来我的 Exec 函数没有被调用。由于我使用的是 VS express,因此我无法真正调试代码并弄清楚单击该菜单项按钮时会发生什么:(
    • @Ricky:- 设置regasm所在的路径..一般在安装目录工具部分。
    • 很抱歉,我不太明白你的意思...我已经这样做了,但使用 /codebase: C:\Documents and Settings\RE86508\My Documents \Visual Studio 2010\Projects\ANAISBHO\ANAISBHO\bin\Release>c:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe ANAISBHO.dll
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多