I have ocx created in VC++ If it is loaded statically it works fine but when I load it dynamically from assembly it gives exception .
public Assembly assembly;
public Form1()
{
InitializeComponent();
assembly = Assembly.LoadFile(Application.StartupPath + "\\abc.ocx");
}
it gives following exception The module was expected to contain an assembly manifest.
(Exception from HRESULT: 0x80131018)
You'll have to perform a number of steps that are normally taken of automatically when you use the toolbox. First and foremost, you have to run the Aximp.exe utility to generate the .NET interop assemblies. Use the Visual Studio Command Prompt to run the tool. You'll get two assemblies, axinterop.foo.dll contains a wrapper class that's derived from AxHost and allows you to put the control on a form. And interop.foo.dll, the interop assembly that makes the COM interfaces implemented by the control callable from a .NET program.
Next you have to ensure these DLLs are present in the build directory. Best thing to do is to add them to your project and set their Copy to Output Directory to "Copy if newer".
Now you can use Assembly.Load("axinterop.foo.dll") in your code to dynamically load the interop assembly.
Next you have to create an instance of the control, use Assembly.CreateInstance() and pass the type name of the AxHost wrapper class. If you have no idea what its name might be, it isn't obvious, then use ildasm.exe to look at the axinterop.foo.dll assembly. Cast the returned object to AxHost.
Next you have to add the control to the form's Controls collection so it is visible and usable. You cannot call any interface methods until the control instance is created, that doesn't happen until you've added the control and the form's Load event has fired.
Next you have to use reflection or the dynamic keyword to obtain a reference to the interfaces implemented by the control, in case you need to set properties or call methods. That's difficult to get right, you'll want to write that code first with the control added from the toolbox so you don't have to guess too hard at the proper names.
This is obviously all quite painful and hard to get right. Improve the odds for a good outcome by adding a class library to your project that uses the OCX directly and exposes its important properties through an interface. And use Assembly.Load() on that one.
Assembly.LoadFile can only load .Net assemblies not native dll/exe/ocx files.
You can add a reference to the ocx file via Solution Explorer-->References and then create an instance of the ocx class.
Related
I'm new to the forum and not a professional programmer, so apologies if I am not using the correct terminology.
I am using a 3rd party DLL in my c# forms application, and it has an interface which (in their example) I specify when creating the class:
public partial class frmMain : Form, PIEHid32Net.PIEDataHandler, PIEHid32Net.PIEErrorHandler
The problem is that the dll, which is added to my project as a reference, may not exist. If it does not exist, the application doesn't start (and in Visual Studio I get a FileNotFoundException as soon as I step into the code, before I could add a try/catch etc.
I can create the DLL from the installer which works fine, but historically I have also added it to the app as an embedded resource and exported it at runtime if it did not exist - which is nice if someone just copies the exe rather than doing a full install. But I've never had a DLL with an "interface" defined in the above way. I guess because the class is referencing it, the app will never run.
So is there a way around this? A way to add the interface reference as being "optional", or adding it at runtime AFTER I have exported the DLL to which they reference?
I need to add reference to another assembly in my c# project based on some compiler switch like #ifdirective. For example I want to add reference to logger DLL in my project only when I need it. Is this possible?
As far as I know, a referenced assembly that isn't used AT ALL, isn't a problem. You can even keep it as reference.
As long as your code doesn't trigger the assembly to be loaded, there is no need to have that file available.
I would suggest though to check whether you really need this, and if you can workaround this by creating interfaces and dynamically load the assembly (using Assembly.LoadFrom).
I have one assembly that's created already, say Static.dll, and a dynamic assembly I'm creating at runtime, say Dynamic. Dynamic creates some IL code to create a new type from Static.dll. When Dynamic is created (it saves successfully), the executable, when ran, errors out because it's unable to load the assembly Static.dll type. I believe this is happening since the Dynamic exe output can't find this dll (or at least this is my guess).
How can accomplish adding in this Static.dll reference so that when someone runs the resulting executable output of Dynamic that it can find the referenced types?
I know about Assembly.Load(), but this alone doesn't change anything. Or at least, I'm not sure what this gives me since I don't need to use the type at runtime, but rather when running the Dynamic executable.
Lastly, I control the Static.dll, so if there is something I can do with the project to fix it, It could be done, however, it does need to remain separate (I don't want to Emit this library for every time I create a dynamic assembly). Basically, I think I want to have my dynamic assembly to have a .assembly extern mscorlib in it's manifest save Static is place of the mscorlib.
Thanks
How can accomplish adding in this Static.dll reference so that when someone runs the resulting executable output of Dynamic that it can find the referenced types?
The reference will be added automatically. Note that normal assembly-probing rules apply when your dynamic assembly executes, so in order to find the assembly. You must (one of):
ship static.dll alongside dynamic.dll
put static.dll in the GAC (but please: don't do this!)
run dynamic.dll in a custom AppDomain with a custom probing-path configuration that lets static.dll be found
handle AppDomain.AssemblyResolve to provide static.dll
use something like ILMerge to fuse static.dll and dynamic.dll
How can I correctly reference a C# DLL that I don't have physical access to? (I actually have the DLL, just not all it's dependencies.)
Background:
On the target computer, there is a program and many interdependent dll files installed in C:\FancyProgram.
I need to write a simple application that will be deployed on the target computer to C:\SimpleProgram.
This simple program will need to make some calls into one of the dll files under C:\FancyProgram. It is a .net managed DLL
On my development machine, I do not have a copy of FancyProgram. I do have that one DLL file, but I do not have any of it's many dependencies. I also can not bundle that DLL into SimpleProgram.
What is the correct method to use and reference this DLL in my Visual Studio project such that my SimpleProgram will correctly compile but load the DLL at runtime from the correct location?
Thank you
My recommendation is to create a Facades for the functionality you want to use from that dll. And don't use (reference) it directly - resolve and load it dynamically:
C# - Correct Way to Load Assembly, Find Class and Call Run() Method
Load Assembly at runtime and create class instance
.Net will do late binding anyway. As long as you don't reference the .dll in any way until you actually mean to load it this will work.
Simply encapsulate all references (fields, properties, methods, instances) into a spearate class or project and make an instance only when you have to. You can then try-catch the load error.
See Visual Studio Output window when your app is run, it will tell you when its is attempting to load what .dll.
You may also want to look at these events to make your app handle errors gracefully:
AppDomain.CurrentDomain.AssemblyLoad += ...;
AppDomain.CurrentDomain.AssemblyResolve += ...;
AppDomain.CurrentDomain.UnhandledException += ...;
AppDomain.CurrentDomain.FirstChanceException += ...;
You may also want to take the MEF approach. It is a framework for doing late loading/binding.
You might want to look at the details of LoadLibrary, GetProcAddress and Marshal.GetDelegateForFunctionPointer.
I would also build dll for testing locally, with the same interface as your external dll. How much functionality yo put in there depends on the complexity of the interface and your SimpleProgram.
There were some excellent answers to my old question about importing external dlls.
Uhhhh, what are you going to do about testing it? Assuming you've figured that out you need to make sure that either the .dll is in the GAC and reference it that way (ideally) or the .dll needs to be in the same place on all computers. Add the .dll in your references and mark it as Copy Local: false, so you don't deploy it. Good luck.
I'm a bit lost with MEF, MAF, Unity ...
This question is about architecture of Winform application.
I've got a main project which contains a Main form and some other forms;
Because i want to include modularity, i'm thinking of using a Plugin System.
What I would like to do is opening each Plugin Dll when the Main Application is opened to reference each with button, toolbar ...
Then i would like to dispose them until they are called.
But i don't want all the plugins to be kept in memory.. just to got a good architecture model.
So first about .NET :
Does dotNet keep only a reference to the dll plugins in memory or all the plugin code ?
I'm thinking of using MEF with LAZY collection of Import, but i need to instantiate them first to get my buttons informations. So second question
If i set the Import Collection to null and lauch the compose() function again, the plugins will be load or wait until call to be load (lazy) ?
Then i would like to dispose them until they are called.
Instead of inspecting imported objects and then throwing them away, you should inspect the import metadata. You can get this metadata by importing Lazy<IFoo,IFooMetadata> or Lazy<IFoo,Dictionary<string,object>>. You can add this metadata to exports with the ExportMetadata attribute.
So first about .NET : Does dotNet keep only a reference to the dll plugins in memory or all the plugin code ?
Once an assembly is loaded it remains in memory, unless you unload the whole AppDomain.
Also, there are no out-of-the-box implementations of ComposablePartCatalog in .NET 4.0 which can be queried without loading the corresponding assembly. But in theory something like that could be done if you store the metadata somewhere outside the assembly. There is a sample of such an implementation in the MEF code on codeplex.
I'm thinking of using MEF with LAZY collection of Import
Using lazy imports will not necessarily prevent assemblies from being loaded. If you have a reference to a Lazy<IFoo> object, then at least the assembly containing IFoo has to be loaded. And as I explained above, the assembly containing the exported IFoo implementation will also have been loaded at that point.
Using Lazy will only postpone the invocation of some constructors, hopefully resulting in faster start-up of your application.