【发布时间】:2018-02-18 15:13:44
【问题描述】:
我在 c# 中有一个 activex 控件项目,它引用了我自己构建的 dll 文件。
现在我点击一个按钮,我发现它失败了,但出现了这个异常:
System.IO.FileNotFoundException:无法加载文件或程序集 'MtnLib,版本=1.0.0.0,文化=中性, PublicKeyToken=111045ceeaeac3e4' 或其依赖项之一。这 系统找不到指定的文件。文件名:'MtnLib, 版本=1.0.0.0,文化=中性,PublicKeyToken=111045ceeaeac3e4'
在 CSActiveX.MtnControl.button1_Click(对象发送者,EventArgs e)
在 System.Windows.Forms.Control.OnClick(EventArgs e) 在 System.Windows.Forms.Button.OnClick(EventArgs e) 在 System.Windows.Forms.Button.OnMouseUp(MouseEventArgs 事件) 在 System.Windows.Forms.Control.WmMouseUp(消息和 m,鼠标按钮 按钮,Int32 点击)在 System.Windows.Forms.Control.WndProc(Message& m) 在 System.Windows.Forms.ButtonBase.WndProc(Message& m) 在 System.Windows.Forms.Button.WndProc(Message& m) 在 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(消息& m) 在 System.Windows.Forms.Control.ControlNativeWindow.WndProc(消息& m) 在 System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
我已启用日志,这些是日志:
日志:DisplayName = MtnLib,版本=1.0.0.0,文化=中性, PublicKeyToken=111045ceeaeac3e4(完全指定)日志:Appbase = file:///C:/Program Files (x86)/Internet Explorer/ LOG: Initial PrivatePath = NULL 调用程序集:CSActiveX,版本=1.0.0.0, 文化=中性,PublicKeyToken=null。 === LOG:此绑定在 LoadFrom 加载上下文中开始。警告:将不会在 LoadFrom 上下文中探测本机图像。本机图像只会 在默认加载上下文中进行探测,例如使用 Assembly.Load()。日志:没有 找到应用程序配置文件。 LOG:使用主机配置 文件:LOG:使用来自的机器配置文件 C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config。 日志:政策后参考:MtnLib,版本=1.0.0.0,文化=中性, PublicKeyToken=111045ceeaeac3e4 日志:尝试下载新 URL file:///C:/Program Files (x86)/Internet Explorer/MtnLib.DLL。日志: 正在尝试下载新的 URL file:///C:/Program Files (x86)/Internet 资源管理器/MtnLib/MtnLib.DLL。日志:尝试下载新 URL file:///C:/Program Files (x86)/Internet Explorer/MtnLib.EXE。日志: 正在尝试下载新的 URL file:///C:/Program Files (x86)/Internet 资源管理器/MtnLib/MtnLib.EXE。日志:尝试下载新 URL file:///C:/temp/MtnControl/Debug/MtnLib.DLL。日志:尝试下载 新 URL 文件:///C:/temp/MtnControl/Debug/MtnLib/MtnLib.DLL。日志: 正在尝试下载新 URL file:///C:/temp/MtnControl/Debug/MtnLib.EXE。日志:尝试下载 新 URL 文件:///C:/temp/MtnControl/Debug/MtnLib/MtnLib.EXE。
我的项目引用了 MtnLib.dll,我确实在 C:\temp\MtnControl\Debug\MtnLib.dll 下看到了该文件所以我不明白为什么 IE 找不到该文件。
这是我的控制:
using System;
using System.ComponentModel;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using MtnLib;
namespace CSActiveX
{
#region Interfaces
/// <summary>
/// AxCSActiveXCtrl describes the COM interface of the coclass
/// </summary>
[Guid("D4B8539E-3839-3913-8B1A-C551A9930864")]
public interface AxCSActiveXCtrl
{
#region Properties
bool Visible { get; set; } // Typical control property
bool Enabled { get; set; } // Typical control property
#endregion
#region Methods
void Refresh();
#endregion
}
#endregion
[ClassInterface(ClassInterfaceType.None)]
[Guid("80B59B58-98EA-303C-BE83-D26E5D8D6794")]
public partial class MtnControl : UserControl, AxCSActiveXCtrl
{
#region ActiveX Control Registration
// These routines perform the additional COM registration needed by
// ActiveX controls
[EditorBrowsable(EditorBrowsableState.Never)]
[ComRegisterFunction()]
public static void Register(Type t)
{
try
{
ActiveXCtrlHelper.RegasmRegisterControl(t);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message); // Log the error
throw; // Re-throw the exception
}
}
[EditorBrowsable(EditorBrowsableState.Never)]
[ComUnregisterFunction()]
public static void Unregister(Type t)
{
try
{
ActiveXCtrlHelper.RegasmUnregisterControl(t);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message); // Log the error
throw; // Re-throw the exception
}
}
#endregion
private void button1_Click(object sender, EventArgs e)
{
//call a function from MtnLib
}
}
} // namespace CSActiveX
这是我的 ActiveXCtrlHelper:
[ComVisible(false)]
internal class ActiveXCtrlHelper : AxHost
{
internal ActiveXCtrlHelper()
: base(null)
{
}
#region ActiveX Control Registration
#region OLEMISC Enumeration
// Ref: http://msdn.microsoft.com/en-us/library/ms678497.aspx
const int OLEMISC_RECOMPOSEONRESIZE = 1;
const int OLEMISC_CANTLINKINSIDE = 16;
const int OLEMISC_INSIDEOUT = 128;
const int OLEMISC_ACTIVATEWHENVISIBLE = 256;
const int OLEMISC_SETCLIENTSITEFIRST = 131072;
#endregion
/// <summary>
/// Register the control as an ActiveX control.
/// </summary>
/// <param name="t"></param>
public static void RegasmRegisterControl(Type t)
{
// Check the argument
GuardNullType(t, "t");
GuardTypeIsControl(t);
// Open the CLSID key of the control
using (RegistryKey keyCLSID = Registry.ClassesRoot.OpenSubKey(
@"CLSID\" + t.GUID.ToString("B"), /*writable*/true))
{
RegistryKey subkey = null;
// Set "InprocServer32" to register a 32-bit in-process server.
// InprocServer32 = <path to 32-bit inproc server>
// Ref: http://msdn.microsoft.com/en-us/library/ms683844.aspx
subkey = keyCLSID.OpenSubKey("InprocServer32", /*writable*/true);
if (subkey != null)
// .NET runtime engine (mscoree.dll) for .NET assemblies
subkey.SetValue(null, Environment.SystemDirectory + @"\mscoree.dll");
// Create "Control" to identify it as an ActiveX Control.
// Ref: http://msdn.microsoft.com/en-us/library/ms680056.aspx
using (subkey = keyCLSID.CreateSubKey("Control")) { };
// Create "MiscStatus" to specify how to create/display an object.
// MiscStatus = <combination of values from OLEMISC enumeration>
// Ref: http://msdn.microsoft.com/en-us/library/ms683733.aspx
using (subkey = keyCLSID.CreateSubKey("MiscStatus"))
{
int nMiscStatus = OLEMISC_RECOMPOSEONRESIZE +
OLEMISC_CANTLINKINSIDE + OLEMISC_INSIDEOUT +
OLEMISC_ACTIVATEWHENVISIBLE + OLEMISC_SETCLIENTSITEFIRST;
subkey.SetValue("", nMiscStatus.ToString(), RegistryValueKind.String);
}
// Create "ToolBoxBitmap32" to identify the module name and the resource
// ID for a 16 x 16 bitmap as the toolbar button face.
// ToolBoxBitmap32 = <filename>.<ext>, <resourceID>
// Ref: http://msdn.microsoft.com/en-us/library/ms687316.aspx
using (subkey = keyCLSID.CreateSubKey("ToolBoxBitmap32"))
{
// If you want different icons for each control in the assembly you
// can modify this section to specify a different icon each time.
// Each specified icon must be embedded as a win32 resource in the
// assembly; the default one is at the index 101, but you can use
// additional ones.
subkey.SetValue("", Assembly.GetExecutingAssembly().Location + ", 101",
RegistryValueKind.String);
}
// Create "TypeLib" to specify the typelib GUID associated with the class.
using (subkey = keyCLSID.CreateSubKey("TypeLib"))
{
Guid libId = Marshal.GetTypeLibGuidForAssembly(t.Assembly);
subkey.SetValue("", libId.ToString("B"), RegistryValueKind.String);
}
// Create "Version" to specify the version of the control.
// Ref: http://msdn.microsoft.com/en-us/library/ms686568.aspx
using (subkey = keyCLSID.CreateSubKey("Version"))
{
int nMajor, nMinor;
Marshal.GetTypeLibVersionForAssembly(t.Assembly, out nMajor, out nMinor);
subkey.SetValue("", String.Format("{0}.{1}", nMajor, nMinor));
}
}
}
/// <summary>
/// Unregister the control.
/// </summary>
/// <param name="t"></param>
public static void RegasmUnregisterControl(Type t)
{
// Check the argument
GuardNullType(t, "t");
GuardTypeIsControl(t);
// Delete the CLSID key of the control
Registry.ClassesRoot.DeleteSubKeyTree(@"CLSID\" + t.GUID.ToString("B"));
}
private static void GuardNullType(Type t, String param)
{
if (t == null)
{
throw new ArgumentException("The CLR type must be specified.", param);
}
}
private static void GuardTypeIsControl(Type t)
{
if (!typeof(Control).IsAssignableFrom(t))
{
throw new ArgumentException(
"Type argument must be a Windows Forms control.");
}
}
}
我在 Visual Studio 中检查了Register for COM Interop,我的控件显示正确,只是找不到 MtnLib.dll。
顺便说一句,我在 windows 7 64 位中使用 IE 8。
【问题讨论】:
标签: c# internet-explorer dll activex