如何开始开发Internet Explorer扩展?

在座有人有开发IE扩展的经验吗?这将包括代码示例,或链接到好的示例,或关于流程的文档,或任何东西。

我真的很想这么做,但我碰到了一堵巨大的墙,里面有糟糕的文档、糟糕的代码/示例代码/缺乏它们。你能提供的任何帮助/资源都将不胜感激。

具体来说,我想从如何从IE扩展中访问/操作DOM开始。

编辑,甚至更多的细节:

理想情况下,我想种植一个工具栏按钮,当点击时,弹出一个菜单,其中包含到外部网站的链接。我还想根据某些条件访问DOM并在页面上植入JavaScript。

在IE扩展中保存信息的最好方法是什么?在Firefox/Chrome/大多数现代浏览器中,您使用window.localStorage,但显然在IE8/IE7中,这不是一个选项。也许是SQLite DB之类的?可以假设。net 4.0将安装在用户的计算机上吗?

我不想使用Spice IE,因为我想构建一个与IE9兼容的IE。我也为这个问题添加了c++标签,因为如果用c++构建一个更好的话,我可以这样做。

86071 次浏览
IE扩展的状态实际上很糟糕。你有IE5浏览器帮助对象的老模型(是的,那些臭名昭著的bho,每个人都喜欢阻止过去的一天),工具栏和新的IE加速器。 即使这样,兼容性有时也会破裂。我曾经维护过一个IE6的扩展,它与IE7不兼容,所以有一些东西已经改变了。在大多数情况下,据我所知(我已经很多年没有接触过bho了),你仍然需要使用活动模板库(有点像微软COM的STL)来编码它们,而且这只适用于c++。 你可以用c#来实现COM互操作,也可以用c#来实现,但这对它的价值来说可能太难了。 无论如何,如果你对为IE编写自己的扩展感兴趣(如果你想让你的扩展在所有主流浏览器上可用,这是合理的),这里是官方的微软资源

http://msdn.microsoft.com/en-us/library/aa753587(v=vs.85).aspx

至于IE8中新增的加速器,你可以看看这个。

http://msdn.microsoft.com/en-us/library/cc289775(v=vs.85).aspx

我同意它的文档很糟糕,api也很过时。不过,我希望这能有所帮助。

编辑:我想我可以在这里抛出最后一个信息来源。当我在研究bho的时候,我在看我的笔记。这篇文章让我开始研究他们。它有点老,但有一个很好的ATL接口的解释,你将使用与IE bho(例如IObjectWithSite)。我认为它解释得很好,当时对我帮助很大。 http://msdn.microsoft.com/en-us/library/bb250436.aspx 我还检查了GregC发布的示例。它至少可以在IE8上工作,并且它与VS 2010兼容,所以如果你想使用c#,你可以从那里开始,看看Jon Skeet的书。第13章有很多关于c# 4中的新特性的信息,你可以使用这些新特性来更好地与COM进行交互。(我仍然建议你用c++做插件)

开发c# bho是一件非常痛苦的事情。它涉及大量烦人的COM代码和p/invoke调用。

我有一个基本完成的c# BHO 在这里,你可以自由地使用为任何你想要的。我说“主要”,因为我从来没有弄清楚如何在IE保护模式下保存appdata

我已经使用IE的web浏览器控件很多年了,在这期间,有一个名字一次又一次地出现在有用的帖子中:Igor Tandetnik

如果我正在开发一个扩展,我会瞄准一个BHO,并开始谷歌:

BHO Igor Tandetnik

浏览器帮助对象Igor Tandetnik

他的帖子通常非常详细,他知道自己在说什么。

你会发现自己在COM和ATL编程上忙得不可开交。 要查看示例演练,请查看: http://msdn.microsoft.com/en-us/library/ms976373.aspx < / p >

我同意Robert Harvey的观点,c# 4.0改进了COM互操作。这是一段非常需要重写的旧c#代码。

http://www.codeproject.com/KB/cs/Attach_BHO_with_C_.aspx

这是通过避免ATL和使用Spartan COM来简化事情的尝试:

c++和COM得到BHOs去

如果你不打算重新发明轮子,你可以尝试为IE添加快捷方式。我已经使用了VSTO东西的产品,它很好。此外,他们有一个有用的论坛和快速的支持。

[UPDATE]我正在更新这个答案以使用Internet Explorer 11,在Windows 10 x64中使用Visual Studio 2017社区。 这个答案的前一个版本(适用于Internet Explorer 8, Windows 7 x64和Visual Studio 2010)在这个答案的底部

创建一个工作的Internet Explorer 11附加组件

我使用的是Visual Studio 2017社区c#.Net Framework 4.6.1,所以这些步骤中的一些可能对你略有不同。

你需要以管理员身份打开Visual Studio来构建解决方案,以便构建后的脚本可以注册BHO(需要注册表访问)。

首先创建一个类库。 我调用我的InternetExplorerExtension.

将这些引用添加到项目中:

  • 交互操作。SHDocVw: COM标签/搜索"Microsoft Internet Controls"
  • 微软。mshtml: Assemblies选项卡/搜索"Microsoft.mshtml"

注意:不知为何MSHTML没有在我的系统中注册,即使我可以在添加引用窗口中找到。这在构建时导致了一个错误:

找不到类型库“MSHTML”的包装程序集

修复可以在http://techninotes.blogspot.com/2016/08/fixing-cannot-find-wrapper-assembly-for.html找到 或者,您可以运行这个批处理脚本:

"%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Community\Common7\Tools\VsDevCmd.bat"
cd "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Community\Common7\IDE\PublicAssemblies"
regasm Microsoft.mshtml.dll
gacutil /i Microsoft.mshtml.dll

创建以下文件:

IEAddon.cs

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Microsoft.Win32;
using mshtml;
using SHDocVw;


namespace InternetExplorerExtension
{
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[Guid("D40C654D-7C51-4EB3-95B2-1E23905C2A2D")]
[ProgId("MyBHO.WordHighlighter")]
public class WordHighlighterBHO : IObjectWithSite, IOleCommandTarget
{
const string DefaultTextToHighlight = "browser";


IWebBrowser2 browser;
private object site;


#region Highlight Text
void OnDocumentComplete(object pDisp, ref object URL)
{
try
{
// @Eric Stob: Thanks for this hint!
// This was used to prevent this method being executed more than once in IE8... but now it seems to not work anymore.
//if (pDisp != this.site)
//    return;


var document2 = browser.Document as IHTMLDocument2;
var document3 = browser.Document as IHTMLDocument3;


var window = document2.parentWindow;
window.execScript(@"function FncAddedByAddon() { alert('Message added by addon.'); }");


Queue<IHTMLDOMNode> queue = new Queue<IHTMLDOMNode>();
foreach (IHTMLDOMNode eachChild in document3.childNodes)
queue.Enqueue(eachChild);


while (queue.Count > 0)
{
// replacing desired text with a highlighted version of it
var domNode = queue.Dequeue();


var textNode = domNode as IHTMLDOMTextNode;
if (textNode != null)
{
if (textNode.data.Contains(TextToHighlight))
{
var newText = textNode.data.Replace(TextToHighlight, "<span style='background-color: yellow; cursor: hand;' onclick='javascript:FncAddedByAddon()' title='Click to open script based alert window.'>" + TextToHighlight + "</span>");
var newNode = document2.createElement("span");
newNode.innerHTML = newText;
domNode.replaceNode((IHTMLDOMNode)newNode);
}
}
else
{
// adding children to collection
var x = (IHTMLDOMChildrenCollection)(domNode.childNodes);
foreach (IHTMLDOMNode eachChild in x)
{
if (eachChild is mshtml.IHTMLScriptElement)
continue;
if (eachChild is mshtml.IHTMLStyleElement)
continue;


queue.Enqueue(eachChild);
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
#endregion
#region Load and Save Data
static string TextToHighlight = DefaultTextToHighlight;
public static string RegData = "Software\\MyIEExtension";


[DllImport("ieframe.dll")]
public static extern int IEGetWriteableHKCU(ref IntPtr phKey);


private static void SaveOptions()
{
// In IE 7,8,9,(desktop)10 tabs run in Protected Mode
// which prohibits writes to HKLM, HKCU.
// Must ask IE for "Writable" registry section pointer
// which will be something like HKU/S-1-7***/Software/AppDataLow/
// In "metro" IE 10 mode, tabs run in "Enhanced Protected Mode"
// where BHOs are not allowed to run, except in edge cases.
// see http://blogs.msdn.com/b/ieinternals/archive/2012/03/23/understanding-ie10-enhanced-protected-mode-network-security-addons-cookies-metro-desktop.aspx
IntPtr phKey = new IntPtr();
var answer = IEGetWriteableHKCU(ref phKey);
RegistryKey writeable_registry = RegistryKey.FromHandle(
new Microsoft.Win32.SafeHandles.SafeRegistryHandle(phKey, true)
);
RegistryKey registryKey = writeable_registry.OpenSubKey(RegData, true);


if (registryKey == null)
registryKey = writeable_registry.CreateSubKey(RegData);
registryKey.SetValue("Data", TextToHighlight);


writeable_registry.Close();
}
private static void LoadOptions()
{
// In IE 7,8,9,(desktop)10 tabs run in Protected Mode
// which prohibits writes to HKLM, HKCU.
// Must ask IE for "Writable" registry section pointer
// which will be something like HKU/S-1-7***/Software/AppDataLow/
// In "metro" IE 10 mode, tabs run in "Enhanced Protected Mode"
// where BHOs are not allowed to run, except in edge cases.
// see http://blogs.msdn.com/b/ieinternals/archive/2012/03/23/understanding-ie10-enhanced-protected-mode-network-security-addons-cookies-metro-desktop.aspx
IntPtr phKey = new IntPtr();
var answer = IEGetWriteableHKCU(ref phKey);
RegistryKey writeable_registry = RegistryKey.FromHandle(
new Microsoft.Win32.SafeHandles.SafeRegistryHandle(phKey, true)
);
RegistryKey registryKey = writeable_registry.OpenSubKey(RegData, true);


if (registryKey == null)
registryKey = writeable_registry.CreateSubKey(RegData);
registryKey.SetValue("Data", TextToHighlight);


if (registryKey == null)
{
TextToHighlight = DefaultTextToHighlight;
}
else
{
TextToHighlight = (string)registryKey.GetValue("Data");
}
writeable_registry.Close();
}
#endregion


[Guid("6D5140C1-7436-11CE-8034-00AA006009FA")]
[InterfaceType(1)]
public interface IServiceProvider
{
int QueryService(ref Guid guidService, ref Guid riid, out IntPtr ppvObject);
}


#region Implementation of IObjectWithSite
int IObjectWithSite.SetSite(object site)
{
this.site = site;


if (site != null)
{
LoadOptions();


var serviceProv = (IServiceProvider)this.site;
var guidIWebBrowserApp = Marshal.GenerateGuidForType(typeof(IWebBrowserApp)); // new Guid("0002DF05-0000-0000-C000-000000000046");
var guidIWebBrowser2 = Marshal.GenerateGuidForType(typeof(IWebBrowser2)); // new Guid("D30C1661-CDAF-11D0-8A3E-00C04FC9E26E");
IntPtr intPtr;
serviceProv.QueryService(ref guidIWebBrowserApp, ref guidIWebBrowser2, out intPtr);


browser = (IWebBrowser2)Marshal.GetObjectForIUnknown(intPtr);


((DWebBrowserEvents2_Event)browser).DocumentComplete +=
new DWebBrowserEvents2_DocumentCompleteEventHandler(this.OnDocumentComplete);
}
else
{
((DWebBrowserEvents2_Event)browser).DocumentComplete -=
new DWebBrowserEvents2_DocumentCompleteEventHandler(this.OnDocumentComplete);
browser = null;
}
return 0;
}
int IObjectWithSite.GetSite(ref Guid guid, out IntPtr ppvSite)
{
IntPtr punk = Marshal.GetIUnknownForObject(browser);
int hr = Marshal.QueryInterface(punk, ref guid, out ppvSite);
Marshal.Release(punk);
return hr;
}
#endregion
#region Implementation of IOleCommandTarget
int IOleCommandTarget.QueryStatus(IntPtr pguidCmdGroup, uint cCmds, ref OLECMD prgCmds, IntPtr pCmdText)
{
return 0;
}
int IOleCommandTarget.Exec(IntPtr pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
{
try
{
// Accessing the document from the command-bar.
var document = browser.Document as IHTMLDocument2;
var window = document.parentWindow;
var result = window.execScript(@"alert('You will now be allowed to configure the text to highlight...');");


var form = new HighlighterOptionsForm();
form.InputText = TextToHighlight;
if (form.ShowDialog() != DialogResult.Cancel)
{
TextToHighlight = form.InputText;
SaveOptions();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}


return 0;
}
#endregion


#region Registering with regasm
public static string RegBHO = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Browser Helper Objects";
public static string RegCmd = "Software\\Microsoft\\Internet Explorer\\Extensions";


[ComRegisterFunction]
public static void RegisterBHO(Type type)
{
string guid = type.GUID.ToString("B");


// BHO
{
RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(RegBHO, true);
if (registryKey == null)
registryKey = Registry.LocalMachine.CreateSubKey(RegBHO);
RegistryKey key = registryKey.OpenSubKey(guid);
if (key == null)
key = registryKey.CreateSubKey(guid);
key.SetValue("Alright", 1);
registryKey.Close();
key.Close();
}


// Command
{
RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(RegCmd, true);
if (registryKey == null)
registryKey = Registry.LocalMachine.CreateSubKey(RegCmd);
RegistryKey key = registryKey.OpenSubKey(guid);
if (key == null)
key = registryKey.CreateSubKey(guid);
key.SetValue("ButtonText", "Highlighter options");
key.SetValue("CLSID", "{1FBA04EE-3024-11d2-8F1F-0000F87ABD16}");
key.SetValue("ClsidExtension", guid);
key.SetValue("Icon", "");
key.SetValue("HotIcon", "");
key.SetValue("Default Visible", "Yes");
key.SetValue("MenuText", "&Highlighter options");
key.SetValue("ToolTip", "Highlighter options");
//key.SetValue("KeyPath", "no");
registryKey.Close();
key.Close();
}
}


[ComUnregisterFunction]
public static void UnregisterBHO(Type type)
{
string guid = type.GUID.ToString("B");
// BHO
{
RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(RegBHO, true);
if (registryKey != null)
registryKey.DeleteSubKey(guid, false);
}
// Command
{
RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(RegCmd, true);
if (registryKey != null)
registryKey.DeleteSubKey(guid, false);
}
}
#endregion
}
}

Interop.cs

using System;
using System.Runtime.InteropServices;
namespace InternetExplorerExtension
{
[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("FC4801A3-2BA9-11CF-A229-00AA003D7352")]
public interface IObjectWithSite
{
[PreserveSig]
int SetSite([MarshalAs(UnmanagedType.IUnknown)]object site);
[PreserveSig]
int GetSite(ref Guid guid, [MarshalAs(UnmanagedType.IUnknown)]out IntPtr ppvSite);
}




[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;
}


[ComImport(), ComVisible(true),
Guid("B722BCCB-4E68-101B-A2BC-00AA00404770"),
InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
public interface IOleCommandTarget
{


[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int QueryStatus(
[In] IntPtr pguidCmdGroup,
[In, MarshalAs(UnmanagedType.U4)] uint cCmds,
[In, Out, MarshalAs(UnmanagedType.Struct)] ref OLECMD prgCmds,
//This parameter must be IntPtr, as it can be null
[In, Out] IntPtr pCmdText);


[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int Exec(
//[In] ref Guid pguidCmdGroup,
//have to be IntPtr, since null values are unacceptable
//and null is used as default group!
[In] IntPtr pguidCmdGroup,
[In, MarshalAs(UnmanagedType.U4)] uint nCmdID,
[In, MarshalAs(UnmanagedType.U4)] uint nCmdexecopt,
[In] IntPtr pvaIn,
[In, Out] IntPtr pvaOut);
}
}

最后是一个表单,我们会用它来配置选项。在这个表单中放置TextBox和Ok Button。将按钮的DialogResult设置为好吧。将以下代码放入表单代码:

using System.Windows.Forms;
namespace InternetExplorerExtension
{
public partial class HighlighterOptionsForm : Form
{
public HighlighterOptionsForm()
{
InitializeComponent();
}


public string InputText
{
get { return this.textBox1.Text; }
set { this.textBox1.Text = value; }
}
}
}

在项目属性中,执行以下操作:

  • 使用强键为程序集签名;
  • 在Debug选项卡中,将启动外部项目设置为C:\Program Files (x86)\Internet Explorer\iexplore.exe
  • 在Debug选项卡中,将命令行参数设置为http://msdn.microsoft.com/en-us/library/ms976373.aspx#bho_getintouch
  • 在Build Events选项卡中,将构建后事件命令行设置为:

    "%ProgramFiles(x86)%\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\gacutil.exe" /f /i "$(TargetDir)$(TargetFileName)"
    
    
    "%windir%\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe" /unregister "$(TargetDir)$(TargetFileName)"
    
    
    "%windir%\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe" "$(TargetDir)$(TargetFileName)"

Attention: even though my computer is x64, I used the path of the non-x64 gacutil.exe and it worked... the one specific for x64 is at:

C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\x64\gacutil.exe

64位即需要64位编译和64位注册的BHO。虽然我只能使用32位的IE11进行调试,但32位的注册扩展也可以通过运行64位的IE11工作。

这个答案似乎有一些关于https://stackoverflow.com/a/23004613/195417的额外信息

如果需要,你可以使用64位regasm:

%windir%\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe

How this add-on works

I didn't change the behavior of the add-on... take a look at IE8 section bellow for description.


## Previous Answer for IE8

Man... this has been a lot of work! I was so curious about how to do this, that I did it myself.

First of all... credit is not all mine. This is a compilation of what I found, on these sites:

And of course, I wanted my answer to have the features you asked:

  • DOM traversal to find something;
  • a button that shows a window (in my case to setup)
  • persist the configuration (I will use registry for that)
  • and finally execute javascript.

I will describe it step by step, how I managed to do it working with Internet Explorer 8, in Windows 7 x64... note that I could not test in other configurations. Hope you understand =)

Creating a Working Internet Explorer 8 Add-on

I am using Visual Studio 2010, C# 4, .Net Framework 4, so some of these steps might be slightly different for you.

Created a class library. I called mine InternetExplorerExtension.

Add these references to the project:

  • Interop.SHDocVw
  • Microsoft.mshtml

Note: These references may be in different places in each computer.

this is what my references section in csproj contains:

<Reference Include="Interop.SHDocVw, Version=1.1.0.0, Culture=neutral, PublicKeyToken=90ba9c70f846762e, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<EmbedInteropTypes>True</EmbedInteropTypes>
<HintPath>C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\PrivateAssemblies\Interop.SHDocVw.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="Microsoft.mshtml, Version=7.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<EmbedInteropTypes>True</EmbedInteropTypes>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />

按照IE11更新文件的方法创建文件。

IEAddon.cs

你可以从IE11版本中取消注释以下行:

...
// @Eric Stob: Thanks for this hint!
// This was used to prevent this method being executed more than once in IE8... but now it seems to not work anymore.
if (pDisp != this.site)
return;
...

Interop.cs

IE11版本相同。

最后是一个表单,我们会用它来配置选项。在这个表单中放置TextBox和Ok Button。将按钮的DialogResult设置为好吧。该代码是相同的IE11插件。

在项目属性中,执行以下操作:

  • 使用强键为程序集签名;
  • 在Debug选项卡中,将启动外部项目设置为C:\Program Files (x86)\Internet Explorer\iexplore.exe
  • 在Debug选项卡中,将命令行参数设置为http://msdn.microsoft.com/en-us/library/ms976373.aspx#bho_getintouch
  • 在Build Events选项卡中,将构建后事件命令行设置为:

    "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\Framework\v4.0.30319\RegAsm.exe" "$(TargetDir)$(TargetFileName)"

Attention: as my computer is x64, there is a specific x64 inside the path of gacutil executable on my machine that may be different on yours.

64bit IE Needs 64bit-compiled and 64bit-registered BHO. Use 64bit RegAsm.exe (usually lives in C:\Windows\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe)

How this add-on works

It traverses all DOM tree, replacing the text, configured using the button, by itself with a yellow background. If you click on the yellowed texts, it calls a javascript function that was inserted on the page dynamically. The default word is 'browser', so that it matches a lot of them! EDIT: after changing the string to be highlighted, you must click the URL box and press Enter... F5 will not work, I think that it is because F5 is considered as 'navigation', and it would require to listen to navigate event (maybe). I'll try to fix that later.

Now, it is time to go. I am very tired. Feel free to ask questions... may be I will not be able to answer since I am going on a trip... in 3 days I'm back, but I'll try to come here in the meantime.

另一个很酷的方法是查看:

http://www.crossrider.org

这是一个基于JS和jquery的框架,它可以让你用一个简单的JS代码为IE, FF和Chrome开发浏览器扩展。 基本上,框架做了所有烦人的工作,剩下的就是编写应用程序代码
这显然是解决了,但对于其他用户,我会推荐SpicIE框架。我在此基础上做了自己的扩展。它只支持Internet Explorer 7/8官方,但我在Internet Explorer 6-10上测试(从Windows XP到Windows 8消费者预览)和它工作正常。 不幸的是,在最新的版本中有一些bug,所以我不得不修复它们,并发布了自己的版本: http://archive.msdn.microsoft.com/SpicIE/Thread/View.aspx?ThreadId=5251 < / p >

enter image description here

在Build Events选项卡中,将Post-build Events命令行设置为:(x64)如下所示

"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\x64\gacutil.exe" /if "$(TargetDir)$(TargetFileName)"
"C:\Windows\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe" /u "$(TargetDir)$(TargetFileName)"
"C:\Windows\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe" "$(TargetDir)$(TargetFileName)"

我想要构建事件选项卡,将构建后事件命令行设置为(32位操作系统)

"C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\gacutil.exe" /if "$(TargetDir)$(TargetFileName)"
"C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe" /u "$(TargetDir)$(TargetFileName)"
"C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe" "$(TargetDir)$(TargetFileName)"

我热情地向你推荐帕维尔·佐尔尼科夫在2002年发表的这篇文章!

http://www.codeproject.com/Articles/2219/Extending-Explorer-with-Band-Objects-using-NET-and

它基于Band对象的使用,并使用. net 2.0编译。 提供了源代码,并使用Visual Studio 2013很好地打开和编译。 正如你将在帖子评论中读到的,它在IE 11和Windows 7和Windows 10上运行得非常好。 它在Windows 7 + SP1和IE 11上运行得非常好 享受吧!< / p >

这个问题是从2013年开始,现在是2020年,但这可能对未来的游客有帮助。

我试着执行米格尔·安吉洛的回答,一开始并没有成功。

还有一些设置需要定义。

在internet explorer(我使用IE-11)去Tools-->Internet Options-->Advanced: enter image description here < / p >

enter image description here

也可以参见这个SO问题这个例子来自github