I Have an activex control project in c# which references a dll file that I built myself.
Now I click a button and I see it failing with this exception:
System.IO.FileNotFoundException: Could not load file or assembly 'MtnLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=111045ceeaeac3e4' or one of its dependencies. The system cannot find the file specified. File name: 'MtnLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=111045ceeaeac3e4'
at CSActiveX.MtnControl.button1_Click(Object sender, EventArgs e)
at System.Windows.Forms.Control.OnClick(EventArgs e) at System.Windows.Forms.Button.OnClick(EventArgs e) at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent) at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks) at System.Windows.Forms.Control.WndProc(Message& m) at System.Windows.Forms.ButtonBase.WndProc(Message& m) at System.Windows.Forms.Button.WndProc(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
I've enabled log and these are the logs:
LOG: DisplayName = MtnLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=111045ceeaeac3e4 (Fully-specified) LOG: Appbase = file:///C:/Program Files (x86)/Internet Explorer/ LOG: Initial PrivatePath = NULL Calling assembly : CSActiveX, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null. === LOG: This bind starts in LoadFrom load context. WRN: Native image will not be probed in LoadFrom context. Native image will only be probed in default load context, like with Assembly.Load(). LOG: No application configuration file found. LOG: Using host configuration file: LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config. LOG: Post-policy reference: MtnLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=111045ceeaeac3e4 LOG: Attempting download of new URL file:///C:/Program Files (x86)/Internet Explorer/MtnLib.DLL. LOG: Attempting download of new URL file:///C:/Program Files (x86)/Internet Explorer/MtnLib/MtnLib.DLL. LOG: Attempting download of new URL file:///C:/Program Files (x86)/Internet Explorer/MtnLib.EXE. LOG: Attempting download of new URL file:///C:/Program Files (x86)/Internet Explorer/MtnLib/MtnLib.EXE. LOG: Attempting download of new URL file:///C:/temp/MtnControl/Debug/MtnLib.DLL. LOG: Attempting download of new URL file:///C:/temp/MtnControl/Debug/MtnLib/MtnLib.DLL. LOG: Attempting download of new URL file:///C:/temp/MtnControl/Debug/MtnLib.EXE. LOG: Attempting download of new URL file:///C:/temp/MtnControl/Debug/MtnLib/MtnLib.EXE.
My project references MtnLib.dll and I do see the file under C:\temp\MtnControl\Debug\MtnLib.dll So I don't understand why IE isn't finding the file.
this is my control:
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
this is my 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.");
}
}
}
I've checked Register for COM Interop
in visual studio and my control is displaying correctly, just the MtnLib.dll cannot be found.
By the way I'm using IE 8 in windows 7 64 bit.