I've read that it's unwise to implement a shell extension using managed code.
But if I go ahead and implement the shell extension using unmanaged code (C++ or Delphi), is it then ok for that unmanaged shell extension to call methods in managed (C#) assemblies? Or must the entire shell extension and everything it calls be unmanaged?
Related
I am writing an Excel VSTO add-in. This add-in loads and runs unmanaged code.
In the startup code of the unmanaged dll, an invisible window for request handling is created. This function call causes a managed exception (LoaderLock) and if I remove it, everything works. I want to avoid creating an extra version just because of this. Is there a way for the unmanaged code to find out at runtime whether it is running in a managed thread? In this case, I could add a runtime check. The window is only needed in a fully unmanaged environment.
Note 1: The issue only occurs in this Excel add-in; a stand-alone managed console application using the unmanaged dll does not show this problem.
Note 2: I know that there are many things that should not be done from within DllMain. What I am doing has been working for more than a decade in managed and unmanaged environments and I want to keep code changes as small as possible.
Checking if mscoree.dll has been loaded has done the trick for me:
if (::GetModuleHandleW(L"mscoree.dll") == nullptr)
This: Checking if a WIN32 / Unmanaged DLL is loaded from a COM module on runtime and this: What does it mean when code "runs on" the .NET CLR? helped.
As exposed in the comments below, this does not tell which type of thread has loaded the dll, but only whether there is any managed component in the process. A more precise check would still be preferred. For the moment, I can live with this solution.
I'm currently having issues figuring out what calls an application is making, and was thinking of implementing a way to hook all of the exports inside of a dll, for example user32.dll, instead of having to hook them one by one in hopes of hooking the correct export that an application is calling. I would be using this code for debugging purposes so then I can add the exports that are getting called to my main code.
I was thinking of implementing this by:
Using Visual Studio's dumpbin and calling /EXPORTS from it to get all of the exports names inside of a dll.
Parsing winuser.h to find the functions from the export names that I obtained earlier from Step 1 and then saving their parameters.
Hooking every export from Step 1 with their corresponding parameter from Step 2.
My question is if this is a good way to go about this, or if this method will work at all?
I need to call .dll file from AutoHotkey but can not while I can access dll from vb6 as follows
//spaceCalculator.dll
Dim obj As New spaceCalculator.calculate
msgbox obj.getData("shapes",2,100,100);
I want to call it from AutoHotkey as follows but throws error -3/-4. .dll in root folder of Script.
DllCall("spaceCalculator.dll\getUsageData","Str","Shapes","Float",2,"Float",100,"Float",100)
Your VBScript uses COM. Your Autothing uses dynamic linking. This is what help says.
VBScript, JScript, and Component Object Model (COM)
VBScript and JScript may be embedded in a script via Windows Scripting for AutoHotkey, which also provides access to COM.
Also, COM may be used directly via DllCall as demonstrated at www.autohotkey.com/wiki/index.php?title=COM_Wrappers.
I have a new ID. While help says you can use DllCall for COM it is very fiddly using COM via DLL function calls (and there's a lot you have to call like CoInitilize and GetClassObject) rather than the runtime doing all the grunt work.
Put your VBScript into your Autoit script as help suggests.
Note in VBScript you have to use late binding so
Dim obj As New spaceCalculator.calculate
Becomes
Set obj = CreateObject("spaceCalculator.calculate")
Although your objects looks wrong. Calculate looks like a method not an object itself.
I found solution that AutoHotKey can dll in which classes are defined like Vb6 and C# as follows
obj:=CreateObject("projectName.ClassName"); // using CLSID
obj.FunctionName(Parameters);
Thanks all
I have a TCL application that is intented to run on Windows only and uses twapi to access some Windows-specific functions.
Now I need to call some C function that are in a custom DLL.
I know I can load the DLL with twapi::load_library (should be the same as LoadLibraryEx()) but I can't understand how to call a function within the DLL itself!
What did I miss?
I would prefer to avoid other dependencies (like critcl, for example) and to avoid to have to transform the current dll in a tcl extension (e.g. via SWIG) so a twapi only solution would be really helpful!
TWAPI doesn't seem to provide any public binding of GetProcAddress (the Windows API function for getting from the name to the address of a function in a DLL).
Use ffidl for simple APIs (i.e., where there are no callbacks) or critcl (for all kinds of APIs, including those with callbacks, because it can do much more extensive code generation; more effort to use though).
twapi's load_library command is there for manipulating the resources in a dll (string tables, icon etc.). It's not intended for calling functions in the dll since that, as Donal points out, requires marshalling and some code generation.
Looks like you'll have to use ffidl to do the job.
For example, if writing a shell extension, is it necessary to register the typelib with CComModule::RegisterServer (i.e., I'm wondering if calling it with FALSE will cause some issues).
Hardly ever.
In theory typelibs would be used by IDEs that wan't to display lists of properties and methods on an object. OleSpy++ or whatever the tool is called can use typelibs to generate quite a lot of important information about the ActiveX
In MSVC you can use #import on a ActiveX with embedded typelib and header files describing the interfaces and types will be automatically generated.
When dealing with well-known interfaces - published in the platform sdk - or if the header files are already supplied for C & C++ bindings, then typelibs are a tad useless.
Even when used from script languages, IDispatchEx now seems to be preferred as a discovery mechanism for the IDE or code to query an IDispatch supporting object at runtime for its methods.
In general, it's fine to say FALSE unless you need a typelib because someone is going to be calling your IDispatch implementation. For most shell extensions I don't think you need a typelib.