Where do I need to switch the Activation Context? - winapi

The problem I'm facing is essentially described here, that is:
I have a DLL that is using a 3rd party in-process COM component dll.
I want to use registration free COM with that in-process component.
I want to embed and use a manfest into this DLL (not into the main EXE) so that I can use the 3rd party component in a reg free way.
The Interface I use from the component is activated through a call to CoCreateInstance.
The 3rd party COM component hasn't got any further (COM) dependencies and doesn't rely on or need isolation.
I see that simply embedding a manifest into my DLL doesn't work, as as is described in the linked question, I will need to switch the Activation Context manually.
What I do not understand is where and when I need to switch the Activation Context: Do I only need to wrap my call to CoCreateInstance in something like CActCtxActivator ScopedContext(*), or would I need to wrap all calls into the 3rd party component? (Which, as far as I understand is what ISOLATION_AWARE_ENABLED is supposed to help with.)
So, when using registration free COM, where do you need to switch the Activation Context?
(*) : Or AFX_MANAGE_STATE(AfxGetStaticModuleState());(**) or whatever.
(**): Actually, AFX_MANAGE_STATE used to work, but does no longer in "newer" MFC versions. See, e.g. VS2012: Removed support for active contexts switching in MFC?:
We removed all the activation context support from MFC because we
.... We use the Windows
isolation aware APIs internally in MFC itself.
// posted by: Pat Brenner, Visual C++ Libraries Development: Wednesday, June 05, 2013 11:10 PM

You only need to wrap your call to CoCreateInstance, given that the 3rd party component has no other dependencies.
If it had other dependencies, then you would need to wrap the calls into the 3rd party component.

Related

Is it correct to load the assembly manifest directly into the application context?

I'm currently trying to get a rather tangled scheme running with registration free COM.
It's not that it is not working, it's that I have hit a kind of confusing situation, where it seems I should active the manifest of the assembly dependency directly in the application context, rather than have the application context point at the dependent assembly.
It is rather easy to explain by the example project MS themselves publish:
Normally, you have an application, an app manifest, a (server-)dll and it's assembly manifest. These correspond to what the example gives:
client.exe
client.exe.manifest (This one points to SideBySide.X as dependentAssembly)
SideBySide.dll
SideBySide.X.manifest
Now, one standard case is to embed the client application manifest inside the client executable, and then use the DLL and its external manifest file.
Now, if for whatever reason the correct application manifest isn't known at compile time, you can load a manifest file at runtime via the Activation Context API.
And this is where it gets confusing:
According to the article, the client application now directly switches its Activation Context to the assembly manifest:
If you look at the _tmain function in client.cpp ... a new section of code that initializes the activation context as follows:
actCtx.lpSource = "SideBySide.X.manifest";
I have cross checked this, and it would also work to dynamically load a file that contains the info from client.exe.manifest, i.e. just the reference to SideBySide.X, and continue with this Activation Context - which would also correspond to the ActCtx in use when we embed a correct application manifest into the executable.
That is, actCtx.lpSource = "client.exe.manifest"; would also work.
TL;DR What is the implication, if any, of directly activating an Activation Context "containing" an assembly manifest inside application code.
Is this how it's supposed to be done when loading manifests from files? (And if so, why can't we directly embed the assembly manifest into the executable, when it is known at compile time.)
Note: (This should really be a comment to #Eric Brown's answer, but it's getting rather lengthy)
The linked article does a decent job of explaining the two RT_MANIFESTresource types, but with regard to regFreeCOm, it leaves a few loose ends. I'll throw in some quotes that jumped at me:
ISOLATIONAWARE_MANIFEST_RESOURCE_ID is used primarily for DLLs. It
should be used if the dll wants private dependencies other than the
process default. ...
the NT library loader checks to see if the
dll has a resource of type RT_MANIFEST, ID
ISOLATIONAWARE_MANIFEST_RESOURCE_ID. If it does, the loader calls
CreateActCtx with the resource, and use the generated activation
context to probe the dll's static dependencies.
What I understand this to mean is that the only point of RT_MANIFEST/2 is for the static DLL dependency loader to find the correct resource to use for resolving DLL dependencies. (Not COM dependencies, see below.)
Sometimes, you want to use the activation context outside of probing
the dll's static dependencies. You can define macro
ISOLATION_AWARE_ENABLED when you compile the module.
When ISOLATION_AWARE_ENABLED is defined, Windows re-defines certain
APIs. For example LoadLibraryExW is redefined to
IsolationAwareLoadLibraryExW.
... Not all APIs affected by activation context are wrapped. For example,
..., and neither is any of the COM APIs.
So, to sum up: I think the RT_MANIFEST mechanism is mostly orthogonal to regFreeCOM as COM doesn't care at all where it's activation context comes from and there is no built-in help for regFreeCOM wrt. Isolation Awareness.
Yes, this is how it's supposed to be done, and you can embed the assembly manifest into the executable (well, the resource section). That's what the RT_MANIFEST resource type is for. There are two default types of manifest resources
Process manifests, with ID CREATEPROCESS_MANIFEST_RESOURCE_ID (1), used during process creation,
Isolation-Aware manifests, with ID ISOLATIONAWARE_MANIFEST_RESOURCE_ID (2), used during DLL loading.
There are a couple of uses (primarily around Click-once deployment) that illustrate the ability to embed registration-free COM manifests in subsidiary DLLs, using RT_MANIFEST. In particular, if a DLL has a CREATEPROCESS_MANIFEST_RESOURCE_ID, that manifest will be used as well.
An example seems like a good thing here.
Given
client.exe
sidebyside.dll
If sidebyside.dll has an RT_MANIFEST resource with ID 1 (CREATEPROCESS_MANIFEST_RESOURCE_ID) which has the appropriate registration-free COM entries in it, and client.exe has an RT_MANIFEST resource with ID 1 that has a <file> entry for sidebyside.dll, then Win32 will automatically handle the registration-free COM management.
Part 8 of the example article strongly implies this, and I've seen it done in a number of in-house projects.

Adding Runtime Intelligence Application Analytics for a library and not an application

I want to add usage statistics for a .NET 4.0 library I write on CodePlex.
I try to follow the step described here but my problem lies with the fact that what I write is a library and not an application.
One of the steps is put the Setup and Teardown attributes. I thought about adding the Setup attribute on a static constructor or a different place that will run once per usage of the library. My problem lies with the Teardown attribute that should be placed on code that ends the usage. I don't know where to put this attribute.
Is it possible to get usage statistics on a library?
Maybe I can register on an event that will fire when the application unloads the dll?
This looks like a typical honeypot giveaway, designed to commit you to the retail edition of their obfuscator. It's a tough business, few play this game better than Preemptive. Yes, using attributes is not going work for a library. The only possible candidate would be a finalizer. And you do not want your code to contact some website while the finalizer thread is running.
Take a look at the retail edition of their product. I bet it has a way to invoke the methods that are normally injected by their obfuscator directly. The class constructor is an obvious candidate for "Setup". An event handler for the AppDomain.ProcessExit event could be a possible location for the "Teardown" call. This also might avoid having to run the obfuscator at all, not undesirable in an open source project.

When is registering a Type Library necessary?

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.

How to use Windows Forms in a C/C++ application?

I have an existing project created using C/C++ under a development environment.
Currently we want to facelift the existing form using a Window Forms application but the problem is the existing project is using Common Runtime Library = No /CLR and Runtime Library = /MTd.
But the a Windows Forms application is using Common Runtime Library = /CLR and Runtime Library = /MDd.
Please advise if it possible to use a Windows Forms application to create a form in the existing project?
Is there any tutorial regarding this?
The comment from MSDN was:-
Caution Do not mix static and
dynamic versions of the run-time
libraries. Having more than one copy
of the run-time libraries in a process
can cause problems, because static
data in one copy is not shared with
the other copy. The linker prevents
you from linking with both static and
dynamic versions within one .exe file,
but you can still end up with two (or
more) copies of the run-time
libraries. For example, a dynamic-link
library linked with the static
(non-DLL) versions of the run-time
libraries can cause problems when used
with an .exe file that was linked with
the dynamic (DLL) version of the
run-time libraries. (You should also
avoid mixing the debug and non-debug
versions of the libraries in one
process.)
http://msdn.microsoft.com/en-us/library/2kzt1wy3(VS.71).aspx..
The simple answer is no. A more accurate answer is kind of, but you probably wouldn't want to.
It is possible to use Windows Forms (i.e. managed code) for your user interface and something else (e.g. non .NET/unmanaged code) for your domain logic. However I'd guess that if you're asking this question then that is going to be a bit much for you to do at the moment.
I suggest that you create a user interface with Windows Forms and then have that user interface call a native C/C++ DLL. Google for PInvoke on how to call an unmanaged dll (C/C++) from managed (.NET) code.
If you did that then you would be much better positioned to answer this question.
My company software often has to have modules which mix managed and unmanaged code and user interfaces. What we do is to separate the modules into their own executables and expose the functionality as COM localserver objects. This way, the unmanaged code can have a user interface written in managed code.
However, you need to do alot of plumbing to get it to work. We do it this way because our applications have been deployed in the field for years and it will take years to give the entire program a makeover into .NET

Avoid loading .Net Dlls in a C++/CLI project?

I have a project written in C++/CLI. Some of the types there are in managed code, and some are in completely native code. Let's say I have the produced DLL on a machine that dosen't have any version of the .Net framework installed, is there a way that another, native application will link with my "mixed-mode" Dll and use only the native types? I've noticed that the minute I add the "/clr" switch, my Dll automatically depends on several .Net Framework Dlls (mscorjit, mscoree etc.), and when I actually try to use the 100% native types defined in it, the application still tries to load those .Net Framework Dlls (even though I don't use the framework in that part of the code).
So, is it possible to avoid loading those Dlls in such case? (as I see it, the other option is to create another, native project, that will contain all of the native types, without the managed ones).
Thanks
No. When you load a mixed mode assembly (/clr), right after DllMain runs, the .cctor runs and initializes the framework, if it hasn't already been setup for the application.
Without this, there would be a big hit as soon as you called a function that required a managed API. For details, see "Initialization of Mixed Assemblies" on MSDN.
The best option would be to make your native API a separate DLL, and have the mixed mode assembly a separate project, so you can load it separately if required.

Resources