[업데이트] 내가 함께 작업이 대답을 통해 업데이트 인터넷 익스플로러 11 에서, 윈도우 10의 x64 과 비주얼 스튜디오 2017 커뮤니티 . 이 답변의 이전 버전 (Windows 7 x64 및 Visual Studio 2010의 Internet Explorer 8)이이 답변의 맨 아래에 있습니다.
Internet Explorer 11 추가 기능 만들기
내가 사용하고 비주얼 스튜디오 2017 커뮤니티 , C # , 닷넷 프레임 워크 4.6.1 이 단계 중 일부는 당신을 위해 약간 다를 수 있습니다, 그래서.
솔루션을 빌드하려면 Visual Studio를 관리자 로 열어서 빌드 후 스크립트가 BHO를 등록 할 수 있도록해야합니다 (레지스트리 액세스 필요).
클래스 라이브러리를 작성하여 시작하십시오. 내 InternetExplorerExtension 이라고했습니다 .
이 참조를 프로젝트에 추가하십시오.
- Interop.SHDocVw : COM 탭 / 검색
"Microsoft Internet Controls"
- Microsoft.mshtml : 어셈블리 탭 / 검색
"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);
}
}
마지막으로 양식을 작성하여 옵션을 구성하는 데 사용합니다. 이 양식에서 a TextBox
와 Ok를 배치하십시오 Button
. 버튼 의 DialogResult 를 Ok로 설정하십시오 . 이 코드를 양식 코드에 넣으십시오.
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; }
}
}
}
프로젝트 속성에서 다음을 수행하십시오.
- 강력한 키로 어셈블리에 서명하십시오.
- 디버그 탭에서 외부 프로그램 시작 을
C:\Program Files (x86)\Internet Explorer\iexplore.exe
- 디버그 탭에서 명령 줄 인수 를
http://msdn.microsoft.com/en-us/library/ms976373.aspx#bho_getintouch
빌드 이벤트 탭에서 빌드 후 이벤트 명령 행 을 다음으로 설정하십시오 .
"% 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)"
주의 : 내 컴퓨터는 x64이지만 x64가 아닌 경로를 사용 gacutil.exe
했으며 x64의 특정 경로는 다음 과 같습니다.
C : \ Program Files (x86) \ Microsoft SDKs \ Windows \ v10.0A \ bin \ NETFX 4.6.1 도구 \ x64 \ gacutil.exe
64 비트 IE 64 비트 컴파일 및 64 비트 등록 BHO가 필요합니다. 32 비트 IE11 만 사용하여 디버깅 할 수 있었지만 32 비트 등록 된 확장명도 64 비트 IE11을 실행하여 작동했습니다.
이 답변에는 이것에 대한 추가 정보가있는 것으로 보입니다 : https://stackoverflow.com/a/23004613/195417
필요한 경우 64 비트 regasm을 사용할 수 있습니다.
% windir % \ Microsoft.NET \ Framework 64 \ v4.0.30319 \ RegAsm.exe
이 부가 기능의 작동 방식
추가 기능의 동작을 변경하지 않았습니다 ... 설명을 보려면 IE8 섹션을 살펴보십시오.
## IE8에 대한 이전 답변
남자 ... 이것은 많은 일이되었습니다! 나는 이것을하는 방법에 대해 너무 궁금해서 스스로 해냈습니다.
우선 ... 신용이 전부는 아닙니다. 이것은이 사이트에서 내가 찾은 것을 편집 한 것입니다.
그리고 물론, 나는 당신이 요구 한 기능을 갖기 위해 내 대답을 원했습니다.
- 무언가를 찾기위한 DOM 탐색;
- 창을 보여주는 버튼 (필자의 경우 설정)
- 구성을 유지하십시오 (나는 그것을 위해 레지스트리를 사용할 것입니다)
- 마지막으로 자바 스크립트를 실행하십시오.
Windows 7 x64 에서 Internet Explorer 8로 작업하는 방법을 단계별로 설명합니다 ... 다른 구성에서는 테스트 할 수 없습니다. 당신이 이해 희망 =)
Internet Explorer 8 부가 기능 만들기
내가 사용하고 스튜디오 2010 비주얼 , C # 4 , 닷넷 프레임 워크 4 다음 단계 중 일부는 당신을 위해 약간 다를 수 있습니다, 그래서.
클래스 라이브러리를 만들었습니다. 내 InternetExplorerExtension 이라고했습니다 .
이 참조를 프로젝트에 추가하십시오.
- Interop.SHDocVw
- Microsoft.mshtml
참고 : 이러한 참조는 컴퓨터마다 다른 위치에있을 수 있습니다.
이것은 csproj의 내 참조 섹션에 포함 된 내용입니다.
<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 버전과 동일합니다.
마지막으로 양식을 작성하여 옵션을 구성하는 데 사용합니다. 이 양식에서 a TextBox
와 Ok를 배치하십시오 Button
. 버튼 의 DialogResult 를 Ok로 설정하십시오 . 코드는 IE11 애드온과 동일합니다.
프로젝트 속성에서 다음을 수행하십시오.
- 강력한 키로 어셈블리에 서명하십시오.
- 디버그 탭에서 외부 프로그램 시작 을
C:\Program Files (x86)\Internet Explorer\iexplore.exe
- 디버그 탭에서 명령 줄 인수 를
http://msdn.microsoft.com/en-us/library/ms976373.aspx#bho_getintouch
빌드 이벤트 탭에서 빌드 후 이벤트 명령 행 을 다음으로 설정하십시오 .
"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)"
주의: 내 컴퓨터가 x64이므로 내 컴퓨터의 gacutil 실행 파일 경로에 특정 x64가있을 수 있습니다.
64 비트 IE 64 비트 컴파일 및 64 비트 등록 BHO가 필요합니다. 64 비트 RegAsm.exe 사용 (일반적으로 C : \ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ RegAsm.exe에 있음)
이 부가 기능의 작동 방식
버튼을 사용하여 구성된 텍스트를 노란색 배경으로 대체하여 모든 DOM 트리를 통과합니다. 노란색 텍스트를 클릭하면 페이지에 동적으로 삽입 된 자바 스크립트 함수가 호출됩니다. 기본 단어는 'browser'이므로 많은 단어와 일치합니다!
편집 : 강조 표시 할 문자열을 변경 한 후 URL 상자를 클릭하고 Enter 키를 눌러야합니다 ... F5가 작동하지 않습니다. F5가 '탐색'으로 간주되기 때문에 내비게이션 이벤트를 수신해야합니다. (아마도). 나중에 고치려고 노력하겠습니다.
이제 갈 시간입니다. 나는 매우 피곤하다. 궁금한 점은 언제든지 문의하십시오. 여행을 시작한 후 답변을받을 수 없을 수도 있습니다. 3 일 후에 돌아 왔지만 그 동안 여기에 오려고 노력할 것입니다.