Just Code it!
Header

Comment or Leave a Message

Please Comment or Leave a Message if this is what you are looking for or if you have any question/comment/suggestion/request.

If you are reading this post it is probably because you have some trouble trying to have your application to run on a system where some COMs dependencies don’t seem to be happily resolved, or because you can’t afford to register the COMs at all (policy?)… or if you don’t have any COM problem at all, well… keep reading. The DLL Hell is always behind the corner.
Because the problem is quite annoying when happens, I provide at least four solutions so that you can choose the one you find more comfortable to use :). Let me know which one you prefer and if you know other alternative ways to do it as painlessly as possible.

The Problem
Imagine to have a simple application that references a COM object. You try to build your COM and then your app, and eventually you try to run it on your machine and… it works! Good! So you happily go and copy your App and the DLL of the COM in a single folder on a second machine and… BUM! Your App crashes without hope.
So, what’s going on?
The problem relies on the fact that when you use a COM DLL (with Early Binding), you are somehow coupling your App with a precise version of your COM library. This means that if one day you or someone else upgrades the COM DLL, then the App will still continue to work using the original COM it was binded to. What really happens is that your App will not simply try to locate the DLL (using only its name) in the current folder and then in the PATH environment variable, but will actually use a GUID (the CLSID) to locate the COM DLL in the Windows Registry and from there locate the file in the file system. GUID stands for Globally Unique IDentifier (while CLSID is the CLaSs IDentifier) and is automatically generated for you when you create the COM object and automatically used when you reference your COM from your App. If you want to see how to use a COM you can have a look at my other post ([intlink id=”114″ type=”post”]Create a .NET COM and use it in Unmanaged C++[/intlink]).
This GUID is then the only thing that the App will use to locate the COM DLL, and in order to make this work you have to “Register” your COM classes as we already know.
So, what if you don’t want to register it?

Sample Scenario
Let’s assume that we have a couple of COM DLLs with one sample Object each and both with a simple (different) method defined. In my example I have these:

  • MyPippoCOM COM with a SillyAdder class (CoClass)
  • MyOtherCOM COM with a SmarterMultiplier CoClass
  • TestApp exe that uses the two previous COMs using Early Bindings

In TestApp I instantiate the objects using the ProgID.

The Tool
Fortunately Microsoft came up with a (almost) simple solution.
The trick is create a *special* file that will tell to our App how to behave and where to look for what it needs. This file is the “Manifest”.
As a brief description let’s just say that this is a simple XML file and in there we can specify where are the DLLs that we want to provide to our app, bypassing the normal searching behaviour.

The Problem of the Tool
The problem here is that writing what you need here is not always (actually almost never) easy. In fact, in order to describe the COM that you App will have to use, you must “describe” it, specifying all the GUIDs, ProgIds (if you need it), and other nasty details that are generally (and fortunately) auto-generated for us when we Create and use a COM in a normal/standard way… So why do we have to suffer now? Fortunately we don’t, we are safe this time as well :P.

The Basic Solution – Understand What’s Going On
Based on Microsoft Documentation, the way to create a manifest for your DLL is to use the Tool mt.exe (this is the Documentation).
With this tool you can generate the manifest that you will have to use with your App if you want to achieve our goal.
For example, considering our MyPippoCOM.dll DLL, we could do something like this (from the command prompt, in the folder where the dll and tlb files are stored):

This will generate a file named “mySample.manifest” that, in my case, will contain something like this:

At this point you could do the same thing for the other DLL and then (only after), create the manifest for your app.
This is because with this tool you can only specify one dll and tlb when you generate a manifest and consequently you cannot create a manifest with the data for both DLLs in one go. Fortunately though this tool allows you to merge multiple manifests! So you could use this as final step toward the creation of the Application manifest. I said “toward the creation” because unfortunately the manifest that you will have at the end of this process will be incomplete and could contain some errors as well if you didn’t follow exactly my example and you specified the dll and tlb file using an absolute/relative path instead. I’ll explain later how fix this. For now le’s see how could you merge the two manifests:

The result will be a file named “merged.manifest” that in my case will contain this:

As it stands you cannot use it directly. You need to rename it, fix a couple of things in it, adding some missing informations and you need to build the TestApp without embedding its manifest.
So, first things first. Go back in VS2005 and build our TestApp changing one setting. Open the project’s properties, expand the section “Manifest Tool” and enter in the “Input and Output” entry. In the option screen on the right set “Embed Manifest” to “No”.
Now you can build the project again and this time a file TestApp.exe.manifest (in my case) will sit next to the executable.
Now open it. It should look like this (the dependentAssembly section will include the proper assembly based on which type of build you selected, debug or release):

Now it is just a question to grab our previous merged manifest (from the two COMs) and copy all the content that appears inside the “assembly” tags into the TestApp.exe.manifest, just before the assembly closing tag. In my case this will be the result of this step:

Ok! Almost there.
The final step is to add something that mt.exe doesn’t add for us but that I like to have, the ProgID attribute. You have to do this by hand unfortunately. Just add this attribute to any comClass tag. The final result in my case is this (I optimised some tags a little bit as well):

Note that the ProgID should actually contain the version number as well (e.g. progid=”MyPippoCOM.SillyAdder.1″), but the other version does work if you don’t specify this number when creating the object in your code as in:

That’s all for this first long manual version.
There is a way to skip some steps and do it slightly more automatically.

The Semi-Practical Solution – The Slightly More Automatic Way
A way that I found helpful to adopt is to make usage of the post-build steps feature.
To keep it short and simple, what you can do is edit the post-build event for both of your COMs projects, adding somethig like this:

(and similarly for the other COM).
This will generate automatically a manifest named “manifest.manifest” (nice name uh? :P) in the project output folder.
Then edit the TestApp project’s properties, writing in “Manifest Tool | Input Output | Additional Manifest Files” the location of any manifest that you want to merge.
Those two settings will essentially automate the creation and merge of the manifest that we previously did manually!
You will have to do the final fixes anyway. Maybe you can try to automate this as well :).

The Practical Solution – The Fast Way
I found a way to cheat and generate the manifest with even less work. It is sort of cheating, but it is fast and works! :).
Instead of opening Visual Studio 2005, open VS2010 and create a new project. Just any project, a console app for example.
Now right click the References tab in the solution explorer and select “Add Reference…”.
In the window that will pop-up select “Browse” and navigate where the first COM DLL is located and add it.
Repeat the same process for all the other COMs.
When the References list is completed, expand it and select all the COMs that you just added.
Go in the “Properties” window of the selected references entries and change the value of “Isolated” to True.
Job Done!
Now when you will build the project a .manifest file will be automatically generated and it will contain the correct XML for both COMs.
mine looks like this:

Notice that it contains the ProgID attribute with the version number (“.1″) at the end of the string (see: progid=”MyPippoCOM.SillyAdder.1”). You will have to remove it if you don’t specify it in your TestApp application.
Apart from this, you can directly use this as input manifest for the TestApp saving even more time! :) (you can consider to change the assemblyIdentity attribute if you do this).
NOTE: In order to apply this solution the COMs must be registered on the developer machine. This must be said just in case you did some previous steps and you unregistered them and you didn’t rebuild the projects ever after.

The Speedy Solution – The Last Tip!
There is a final tip to avoid even more typing. The only thing to prepare is the merged manifest in the way you prefer and use this one as Additional Manifest File in the Input and Output section of the Manifest Tool in the properties of the C++ TestApp project. Then, instead of setting the Embed Manifest to “No”, Leave it to “Yes”.
This will generate the application exe without any needed manifest and this is ready to be executed side-by-side with the COM DLLs.
No more editing, no more problems :).

Note about VB6 COMs
If you have VB6 COMs the previous method will still work really well (even with a correct ProgID), but if you want to explore even alternative ways, there is an interesting tool that you can try to use to generate the manifest for each specific COM.
You can find the tool here: Make My Manifest
What it does is essentially create a manifest for any VB6 projects (not only COMs) generating a complete manifest with all the project’s COM dependencies.
So this is more exhaustive than our single C++ COM manifest and this means that if you have multiple VB6 COMs that uses others COMs, then the manifests could contain common elements and thus the merge should take care of this. But for the rest it is a quite nice tool to use, so give it a try.

Conclusion
The DLL Hell is not a random name and what I tried to cover in this post is just the tip of the iceberg.
I wanted to write this because I found quite difficult to gather the practical information that I ended up discovering personally through a long series of frustrating experiments in order to properly understand and faultlessly solve the main problem.
I hope that this helped you and you found it interesting.
Let me know if you discovered other ways to solve it or if you have any suggestion/question/information that you want to share ;).

Comment or Leave a Message

Please Comment or Leave a Message if this is what you are looking for or if you have any question/comment/suggestion/request.


So, now you (actually Me) want to encode and crypt something in C++ and then (maybe after a network message), decrypt and decode this info in C#.

Let me explain exactly what I mean with encode/decode, crypt/decrypt.

We use the user’s two public/private key pairs to crypt/decrypt a session key that we will use to encode/decode a message. If all this make sense to you then let’s start.

First of all, let me answer one natural question: “Why all this?”

The reason of the double-step procedure to encode a message is due to two major reason:

  • crypt/decrypt (or signing and verifying) with an algorithm for public-key cryptography such as RSA (the one that I am using), uses a key pair, where one key is used to crypt some data, and the other (asymmetric) key is used to decrypt it. The things can actually work in both ways and in one case we will talk about signing and verifying.
    The protection here is very strong but the cost is resources, especially time. The algorithm is slow compared to others and for this it is not suitable for protecting a large amount of data. Another reason seems to be security itself, where many blocks encrypted with the same RSA key can help an attacker to reach his intent.
  • encode/decode instead is achieved using a symmetric key algorithm that can be very fast and if it is a stream cipher, it works great with streaming data :). I will use RC4 for this.

The Scenario

Two PC, connected through internet, where one behave as a server and the other is the client.

We assume that the server contains (well protected) its private and public keys that it will use to sign and decrypt some data that will go to or will come from the client.
For the client we assume that he knows the server’s public key and that he will use this to verify and crypt the data that he will receive from or that he will send to the server.

More about the Key Pair and Session Key

With Windows you can store/retrieve user keys (key pair) using the Crypto API. With it you can manage machine or user key in a quite simple way.
On the server we will use this API (in C++) to generate/retrieve (and then store) our machine key pair and we will tell the client our public key.

On the client will create a session key (C++) that will be used to encode a message with RC4.
Because the client knows the server public key, he will then use this to encrypt the session key.
Once this is done, the client will proceed to pack the two things together (encrypted session key plus the message) and send the packet to the server.

The Server at this point will save the message in a file, because we want to have more fun later on.

In fact, to make things more interesting then we will create a .NET (C#) project that will retrieve the same key pair previously stored, reads the file, imports the session key and decodes the message. All this in pure .NET.

Does it not seem fun?

To simplify stuff I will not use any network code and I will assume that the data are passed somehow between client and server. This can be network, file, or whatever (DB, mind power,…).
The only storage that I will use will be a file (the encrypted file) to allow a simple code in C# to open it and read and decrypt its content.
To simplify the code and shrink it to the fundamental parts I will provide code snippets that are mostly implemented as simple methods (C style) and I will assume the presence of some globally scoped variable (that should really be class scoped variable in a real environment). This will hopefully simplify the understanding of the concepts without losing the focus tracking the objects relationships.

Let’s start then.

Initial Server Code (C++)

In C++ we can easily use the Crypto API to do all we can (reasonably) think about when we want to protect our data.
This is available including “wincrypt.h” in your code.
The first thing to do is acquire the context where our secret keys are stored. This can be easily done with a code such as:

After this we can retrieve our exchange keys from the container. If the keys doesn’t exist I will create a brand new pair. This code does exactly this:

Happy with the result the next thing to do is to export our public key and give this to our client… or everyone… after all is a public key!
In my sample code I will use a memory buffer. The important thing here is that we are not here to cheat and this buffer will be the only thing that we will give to the client code pretending that it is a completely separate application. The export looks like this:

If everything is fine until now we can temporarily leave our server and switch to our client code.

Client Code (C++)

Because we are still working with Crypto API, the pattern is similar and so the first thing we have to do is acquire the container context in the same way we already did for the server.
The only difference is that we will use a different container to continue simulating a separate environment:

We can then import immediately the server public key:

The initial “handshaking” is completed now! The server is configured with his Key Pair and the client has received the the public part of this pair.

The next move is in client’s hand now. It has the freedom to choose a session key that will be used to encode a secret message.
For this task I am simply generating a brand new session key, especially generated for the algorithm that I will use to encode the message:

With this key I can finally encode my message!

Cool! The message is now protected… well, almost. In order to complete the transmission of the encrypted message, back to the server, we still need to take care of a few more details.
The first one is related to the protection of the session key itself. The server needs it in order to decode the message, but for sure we cannot send it as it is otherwise all this messing around with keys would be just a waste of time (human and cpu).
As already mentioned (and I hope obvious at this point) we will send our session key encrypted with the server public key. The server, and only the server, will then be able to decrypt it.

Enough chatting, let’s go to encrypt the session key then:

In my sample scenario I will simulate the transmission of the encrypted message using a simple file where I will write all the server needs to successfully decrypt the message.

My main focus here is to write a C# server that will be able to do this.
Anyway, just to complete the circle in the C++ world, I will add few more lines that will show how read and decrypt the same message in C++ as well, although I will not follow the same path and I will just continue to use memory buffers, just to avoid to add more details that are not relevant for what I have in mind now. If there is the need I will write another side article for it.

This said, let’s go back to our server (C++).

More Server Code (C++)

Assuming the message as received together with the encrypted key the first thing to do is decrypt the key of course:

As a result we will have another key object that can be used (at last!) to decrypt the message:

Job done! (in C++).

The last (really) thing to do is to create the file that will be used by the C# server.
I will use a single file where I will store both the encrypted key and the encoded message. To keep things a little bit more interesting (and realistic) I will write few bytes at the start of the file to communicate the size of the key.
Because we already have all we need, we can simply create a new file and write this info as described:

If you want to do some cleanup (and you should), remember to release the keys and the context when we don’t need them anymore.
This can be done easily in this way (this assumes that the keys are null if not initialised):

We are ready to switch to C#!

Server Code C#

The server here has to do basically the same things that we already done in C++, but in a slightly different way. In order to retrieve the Key Pair (I am not considering the creation of it in this context) we can use an RSACryptoServiceProvider object specifically configured (with a CspParameters object) to access the same server container we used in the previous app. You can find those classes in System.Security.Cryptography.
I will configure it to use the same RSA algorithm and forcing it to retrieve existing keys without attempting to create a new pair.

This is how we can do it:

We need something to decrypt now. I will use the file that has been created in C++ reading all its content in specific objects:

Once identified the encrypted session key we need to use the RSA service provider to decrypt it.
The only awkward things here is that the .NET encryption algorithm swaps the bytes after encryption (and before decryption) and we will have to take care of this directly, because this key was encrypted by the Crypto API in C++. Another thing to consider is that the encrypted blob doesn’t simply contain the encrypted key but some extra informations about the version, the algorithm to use with that key and the algorithm used to encrypt the key itself. I will not go into any detail for this here and I will instead jump in the session blob, straight to where the encrypted key is stored and use it (we already know what kind of key we generated for this toy app).
The encryption is then as simple as doing:

If everything is correct we will not receive any exception and the original session key is in our hands.

Let’s just use then to decrypt the message… well… no unfortunately.

In .NET there is no implementation of the RC4 algorithm that we used to encode the message.
Although annoying, this is not a big issue because its implementation is not so complex and can be easily hand-crafted.

I will not cover this algorithm in this post (but I will do soon in another one. Update: the post is available here: RC4 Cypher Algorithm in C#) and I will instead assume that you have access to a class/method that takes care of the algorithm details, providing a simple method to decode a message with a specific provided key.
If this is true we can then simply complete the task in this way:

Display the decoded message and jump of joy :).

Final Notes

Wait a second… nice, but… our keys? What if I want to cleanup the keys I generate with this sample code?
Correct. It would be nice to do some housekeeping when we are done with this.
In C++ we can remove out keys from our test container very easily. Sometime it is so easy that risks to be dangerous, but we know what we are doing now :).

The same thing can be done as easily as this in C# (actually it is even easier than C++):

If you try to run the C# server code again after removing the keys you will obtain a CryptographicException “Keyset does not exist” (as expected).
This will give you the knowledge that you correctly did your house-keeping :).

Comment or Leave a Message

Please Comment or Leave a Message if this is what you are looking for or if you have any question/comment/suggestion/request.


Well, there is enough material here to write a book… or at least a bunch of chapters. I don’t like to go through pages and pages that explain the concept but don’t give a tangible example. So, because the matter here is quite boring and not exciting, I’ll go directly to the point.

The goal here is to create a component in .NET, register it as COM and use it in a nice(!) and not-so-painful way, from C++.

This said let’s start with the bullet points:

  1. Create a .NET project and tell it some way that the result of it will be a COM object
  2. Write a bunch of methods, just to have something to test
  3. Start a C++ project and import all that we need to use our newly created .NET COM component
  4. Initialise and use it in code
  5. Deploy it on a different machine (not the one we are using as development environment)
  6. Enjoy and Comment

When you first see this you could think: “Well… easy!”. Well… not exactly. There are a bunch of stuff to consider if you don’t want to bang your head on the monitor (and keyboard) because you cannot see/use your simple object.

First things first: The .NET COM project

The first things to do here is to choose you preferred Visual Studio environment and launch it. I am using VS2010 as an example.
Start a new project, select Class Library and give it a name (I named mine COMTest). Rename the default class to something sensible (such as “MyPippoClass”… or even more sensible :P).

Write some code

In your custom class (MyPippoClass) write something like this:

Now, in order to make it visible as COM we need to generate the tlb file. In order to do this, right-click on the project and select Properties. Select the “Build” tab and (down in that page) tick the checkbox “Register for COM interop”.
Now, when you build the project you will see that, beside the .dll, there is a file with the same name and extension .tlb (COMTest.tlb in my case). Not finished yet. If you want to use the classes defined in you COM object (and I bet that you want) than in the property windows of the project select the “Application” tab and click on “Assembly Information…”. In the form that will pop-up tick the “Make assembly COM-Visible” checkbox.
Once this is done, you are ready to rock.

The C++ project

Now open you VS environment and create a new C++ project. Create a simple console app and go where the main is.
Now the only (well… almost) thing to do is to import our COM object through its Type Library file (the .tlb that we generated with so much love).
Assuming that you will have the include folder settings configured properly (to point where the type library file is), add this just before the main:

Finally some meat now. Go in the main and write:

Well,  now you will be probably surpised (or frustrated) that myPippoClass does not show any method. Yes, this is the default behaviour of your COM creation. Why? Well, the reason behind this is to allow more robustness when the client will be deployed. Once this is done in fact, and you will go and change the COM component (e.g. adding more stuff), the existing client will continue to work. You are essentially forced to use late binding to interact with your COM object.

If you don’t believe the intellisense and you try to write (C++) this anyway:

you will obtain an error similar to:

The only pain is that to make this work, you have to code in a way that is not very elegant and nice. You will have to query the method that you want to invoke on the instantiated COM object…
Something like this (don’t be scared):

Are you still there? Good!

If you don’t like it, I don’t like it. It is clear why, but what if we don’t care about this problem and we want to simplify all this?
Fortunately a solution exists, and it is pretty simple as well. Hurray!

Go back to your C# project, expand the “Properties” folder in your solution explorer and open the “AssemblyInfo.cs” file.
Just to put some order in what we will do, go where the line “[assembly: ComVisible(true)]” is (if you have “false” instead of “true” then you did something wrong in one of the initial steps. Simply double-check them or change the “false” to “true”).
Immediately underneath add this line:

Note here: Types that use a dual interface allow clients to bind to a specific interface layout. As already mentioned (and this is why it is generally discouraged, despite the ugly code): any changes in a future version to the layout of the type or any base types will break COM clients that bind to the interface. But… But now our C++ side is nicer to work with.

Go to the C++ code and try to use your COM instance. Be sure that the dll (and tlb) are updated, and you will see that your instance will expose (thanks to the intellisense)  all the methods and properties that we wrote.
Note that if the intellisense still doesn’t work, it could be due to intellisense itself that is somehow slow and dumb sometime (especially in C++). But if you write the following code the compiler should build without any problem.

Of course this will build but will not work. We still need some extra code to allow our program to interact with COMs.

As first line in our main function add this:

Then at the end don’t forget to add:

Now it should be happy!

If you did everything correctly and you run this on your dev machine you should see this output:

Isn’t it cool? Yes! Well… somehow.

Deploying it on another pc

If you try to copy this exe to another machine and the COM dll as well and you try to launch the exe you will obtain a not-so-nice (assuming that we are doing all in debug mode): “This application has requested the Runtime to terminate it in an unusual way. Please contact the application’s support team for more information.”

What’s now?! Well, you need to tell the system how to find your COM DLL. You can simply do it registering the dll (in the target machine) using the RegAsm tool provided with the .NET framework.
You can find it in:

or (if you are not using the .NET 4.0):

Simply run (assuming RegAsm.exe in your path and the dll in your current folder):

The output of the registration operation should be similar to this:

If you launch your C++ exe now everything should work fine :).

One or few more words. If you move your exe in a folder without your DLL you will have again the nasty crash. To solve this problem (in case you care about this) you need to run another tool (gacutil) that we will essentially use to register our DLL in the global assemblies cache.
After locating it just run it on your DLL with the /if option that will essentially force the installation of the DLL in the GAC.

Theoretically it should simply be:

Practically instead it depends on your framework version and what you have installed on your machine.

If you build your code using the .NET framework 4.0, then probably you will have to copy the gacutil tool from your dev pc into the other.
The fastest way (just to have it working without too many operations) is to copy the whole folder:

in your target machine and run the gacutil in there.
Once you do it you will see that it doesn’t work… again? Yes again. This is because, in order to do this, we need to give a strong name to our assembly.
The output of the gacutil registration will in fact be:

Well… let’s do it.

There are two ways of doing it, one semi-manual and the other more automated.
Just to explore both options let’s see both of them starting from the semi-manual one.

Open the command prompt (on your dev pc) and go where the generated COM DLL is.  Then from here (just for simplicity) run the command:

if your sn.exe is not in the path, then use the one in the same folder of the gacutil writing something like this (if you don’t want to move folder and assuming that you have my folder structure):

the result will be a file called (surprise) test.snk and the console output will be:

Well done.

Now open you C# project and go again in the property windows, “Signing” tab now. Tick the “Sign the assembly” option and from here you can select the file that we have just created (test.snk).
If you want to use the more automatic way directly instead, from here open the drop down box and select “<New…>”. In the dialog box that will pop-up remove the tick from “Protect my key file with a password” and enter a nice name (e.g. “MyComTestKeys”). Once you will press “OK” the system will automatically create a “MyComTestKeys.snk” file in your project and will give a strong name to the assembly.

If you build now and deploy the DLL and try to run the gacutil again you will succeed!

Note that you will need to unregister/register again the DLL with the RegAsm tool.

Now sit, relax, take a breath and launch again the C++ exe in its own isolated folder.

Well Done!

The journey ends… well… actually it starts here.

Please comment and leave any feedback/request about this or any other argument (it can be completely unrelated if you want). I will try to answer and explain more concepts in the future posts.

For now: Good Bye! :)