0
这是一个完全新手的问题,因为我的领域是Java而不是C#,但我得到了构建BHO的任务,并且达到了我需要菜单项的地步(在工具内部菜单)在我的代码中调用一个函数。菜单项被点击...没有反应
我读到我必须声明并实现IOleCommandTarget接口,我这样做了。现在我需要将这个类注册为一个COM对象。
显然要做到这一点,我需要用[ComRegisterFunction]声明几个函数,但即使如此,我也无法在regsvr32中注册它们。而uppon与DLL导出进一步检查查看器的功能似乎并不在那里:(
我在做什么错
预先感谢您
编辑:
好了,所以从我得到的评论我想,我的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();
}
}
}
好regasm作品,我真的不知道它做什么,但它说,它说:“成功注册类型”。但是我的Exec函数没有被调用。因为我使用VS express,所以我没有真正的代码调试方式,并找出当我点击该菜单项按钮时会发生什么:( – ricardoespsanto 2012-08-09 09:13:10
@Ricky: - 设置regasm所在的路径..通常在安装目录工具中部分 – perilbrain 2012-08-09 09:15:39
对不起,但我不太明白你的意思...我已经完成了这一步,但也使用了/ 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 – ricardoespsanto 2012-08-09 09:23:36