I'm looking into registering a directshow filter at runtime and probably need to use reflection to do this and then call regsvr32 somehow on binary data. Not sure if this is possible, sounds tricky. Basically I have a dll file that is a filter and I added it to the solution as an embedded resource but after this I'm stuck... not sure how to go about registering it. Does anybody have any insight? Is this possible to do or do I have to have the file existent to register it? Thanks.
Cheers.
Are you sure you need to register it? You only need to do it if it is to participate in Intelligent Connect. Otherwise you might just LoadLibrary the DLL and create an instance of the filter via DllGetClassObject bypassing COM instantiation. Good news you don't have to be administrator with elevated privileges to do this, as opposed to registering the filter DLL.
Then see also:
Embedding unmanaged dll into a managed C# dll
How can a C++ windows dll be merged into a C# application exe?
Related
I am working on an application that imports an unmanaged dll into C#. It has a wrapper class that loads the methods so it can be called. The methods work fine in the program from the dll. I want to add saving the version of the dll that is being used. I found that I need to use FileVersionInfo.GetVersionInfo("my.dll") thanks to C# getting version of unmanaged dll. However, when running this function it exceptions saying it can't find "my.dll". The dll is in a folder off the root of the c:. This folder is in the PATH and according to http://msdn.microsoft.com/en-us/library/ms682586(VS.85).aspx#search_order_for_desktop_applications it should find it.
Knowing that the my.dll file is loaded and working why can't I also call GetVersionInfo() inside the same wrapper class and find my.dll so I can get the same file's version number? Thanks for the help as I have been looking for a couple of days.
It requires the full path, it won't search for the DLL. That's too risky, the Windows search rules for a DLL are intricate and subject to configuration. If you need to do this before pinvoking any function then the best way is by pinvoking SearchPath(). Which uses the same algorithm as LoadLibrary uses if you set the first argument to null.
If you need to do this after pinvoking a function then the best way is by using the loaded DLL. Iterate Process.GetCurrentProcess().Modules to retrieve the ProcessModule.FileName.
From MSDN, the parameter for GetVersionInfo is:
The fully qualified path and name of the file to retrieve the version
information for.
So it's pretty clear. You need to pass the full path, as it seems this function relies on it. Otherwise it will most likely look for the file in the current directory (so your app's dir).
As a side note, keeping the native DLL in C:\ is bad practice.
You should store it in your application's folder. Then this function would work and your app would be more self contained. No files spread around the disk.
Of course, this is true unless you have a good reason for storing it in the root of your C drive.
I've got a problem which I hope you can help me with.
I created ASP.NET 4.0 web application. I've also got .cpp file generated in some other app. This .cpp file contains functions, which always returns the same number of variables and which always takes the same number of parameters.
What I need to do is being able to use this functions in my web application.
But what is real problem is that I need to be able to replace this functions while running app. What I mean is administrator should be able to login, upload new cpp file, which will replace old functions with new ones. New ones will have the same names, parameters and result number, but will make calculations in a different way.
Is there any way this can be achieved?
Thanks for any help!
MattheW
Precompile the cpp code into dlls and let admin upload dll. Reference dll's from c# app using [DllImport("")] directive.
C++ will need to be compiled in some way or another. You can use a compiled dll written in C++ in your ASP.NET application but the code will still need to be compiled for ASP to be able to use it.
The compiled DLL can then be loaded and unloaded to accommodate changes to the function. You could perhaps even make the ASP.NET server compile the file somehow, but the code still needs to be compileable to a DLL to make it executable.
You need to expose the C++ code via another dll.
The first choice is pinvoke. See:
How to set up a C++ function so that it can be used by p/invoke?
It's also covered here:
http://msdn.microsoft.com/en-us/library/aa446538.aspx
Technically you could also expose via COM or write in managed C++ but those are both overkill if you're just trying to expose a few C++ functions.
I am trying to write a program in c#. Part of it needs to be be able to detect if a file(mostly dlls, but some other aswell) is registered. And the user must then be able to select a file(or files) that he/she wants to register and the program must register it. It shouldnt just register all the files, the user must decide which to register
So mainly I am wonder how to detect if its registered, and how to register it
Thank you in advance for your help
EDIT: OK, so how do you detect if a .net assembly is registered from within a C# program?
You should define what does it mean "to be registered". Standard DLL files are NOT registered anywhere. (That's why can see chaos called "DLL Hell".)
Or is it COM?
COM components are registered using regsvr32.exe. You can call it to register your files. This is the simplest way. If you for some reason think you don't want this simple way, you can do it manually - read COM documentation on information how the component can register itself. (You load the file into your address space and let it register itself by calling the registering function in it.)
I don't know how to legally detect if a particular file is registered as a COM component host if you don't know what component is inside. But if you know the component, you can try to create the component. If the creation fails, the file is not registered yet.
Or are they .NET assembly files?
In .NET you are not allowed to "register" files at your will, you need administrator rights. (The process must run in elevated mode.) But again, you normally use these .NET DLL files without registration. Normally only well trusted core system components are registered in GAC. I think it can be a security hole if you try to add your private files into GAC. So I would ask if it is relly so important to have them registered there.
Say we have an existing process (or application) that calls a COM object from an ocx file such as "MyCOMLibrary.ocx".
Is there a way to write a C# library to exactly replicate the ocx file? So that the original application can call your C# code rather than the original COM object?
You would, of course, have to use identical CLSID and ProgIDs as the original ocx. And assuming there is no signing involved, such as a SNK in the .Net world.
Also, are there any tools that exist to automate this? Something that takes in an ocx and spits out a C# file with methods to implement.
EDIT: I want to add that the original application is VB6, and does not use .Net at all. They are most likely loading the ocx as a VB6 app would (ProgId or Guid). Does this cause any issues?
We also have no problem with completely rewriting the ocx--we will most likely just return success error codes for all methods and only use methods/events required by our situation.
EDIT: You would think this would not be too difficult to accomplish. Can we make a VB6 ocx file that could replace the old ocx, and just pass all calls to a .Net assembly?
EDIT: I tried using the following open source library: EasyHook
But it seems like this question should still be viable. VB6 seems to load COM objects in a way that prevents hooking. I don't see a way to hook instance methods on a class/interface or a class's constructor with EasyHook.
You can use ActiveX Import AxImp to import the OCX, create a wrapper class and then call that. The program is described here: http://msdn.microsoft.com/en-us/library/8ccdh774(VS.80).aspx
Basically, what you need to do is execute the following on the commandprompt:
c:/>AxImp MyControl.ocx
result is a MyControl.dll and an AxMyControl.dll. The first you can use as a normal .NET DLL in your projects (i.e., without a graphical user interface), the second can be used to be drawn on a form as you normally would with any other control like a TextBox or a Label.
To use it, go to Visual Studio, rightclick your project and select Add Reference. Browse to the newly created DLL and add it. That's all.
Our Deviare Hook Library can be used for hooking COM objects. You can see an article from our blog related to this topic: Hooking Outlook COM objects with Deviare
Apparently VBMigration Partner can automatically upgrade a VB6 COM component to a VB.Net component that has binary compatibility with the original VB6 component. I don't know whether it supports OCXs. If it does, I'd suggest use that first and then try to go to C# later (if necessary).
Not really a complete answer to the question, but something I think might be useful. If you add a key called 'TreatAs' under the CLSID of the object you want to replace and set the default value to the CLSID of the object you want to create instead, this instructs the COM runtime to create your object instead of the original one. No need then to force your new, replacement object to have the same CLSID and ProgID of the old one.
For example, if your original object had ProgID "MyComLibrary.Object" and CLSID "{ABC}", and your new object has ProgID "MyDotNet.Object" and CLSID "{123}", then under HKLM/CLSID/{ABC} add a key called TreatAs with a default value of {123}. Then any request for "MyComLibrary.Object" or "MyDotNet.Object" will get a copy of the new object (assuming they implement the same interfaces).
does somebody know how can I embedd an exe file into a dll ?
I have a tool which is an exe file that I call from c# code.
The thing is that I want to have 1 dll containing this tool (exe file) and the dll containg my c# code.
Is it possible to embedd this exe file within the resources?
Thx in advance
Sure it is. You can add any file as RC_DATA in application as resource. But I believe you will need to extract it to disk first before calling it!
Which IDE/Language you are using?
[EDIT]
Sorry! you did mention that you are using C#.
Add a resource file to you application (right click application in IDE and select "Add new item".
Use the toolbar in resource editor to add an existing file.
Then extract the exe whenever required by calling code something like:
System.IO.File.WriteAllBytes (#"C:\MyEXE\", Resource1.MyEXE);
It's worth baring in mind that your uses may not be too happy about you doing this. Embedding an executable that they've got no control over into a DLL that you'll extract and run will probably make people worry about the running a Trojan on their machine.
It's better to leave the .EXE in the filesystem and be transparent about what your application is doing.
You can load an Assembly from a byte[]. This can be obtained via the ManifestResourceStream of an embedded resource.
An alternative may be to not embed the .exe itself, but rather include its functionality in the dll, and use rundll32[1] to execute it.
On a side note, remember that when you pull a file from your resources to disk and then execute code on it, you may trigger Windows Data Execution Prevention - basically, Windows tries to automatically detect if something is supposed to be code or data, and if it looks like data (which a resource would), then it will prevent that data from being executed as code.
This becomes a particularly sticky issue if your .NET assembly is going to be used over a network instead of from a local drive - there are all sorts of .NET security configurations that might prevent this from working correctly.
Another option, and not knowing the details of your project, take this with a grain of salt: add a .exe.readme file to your install that describes to any curious users or IT people why there is an executable they weren't expecting in the installation directory :)