Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Registration-free COM/DLL?

My program is using the Skype4COM.dll (A wrapper for the Skype API).

I am using Delphi 2010 - is there a way to make sure that my program is ALWAYS using the Skype4COM.dll that I will ship it with? The thing is, there are different versions of Skype4COM, and if I register mine over someone elses, their app may not work anymore.

Usually I use RegSvr32 to register the DLL on peoples system, but I heard its possible to make it registration-free (in C#), so my question is: Can we do that in Delphi, too?

Thanks!

like image 355
Jeff Avatar asked Feb 22 '11 05:02

Jeff


People also ask

What is register free COM?

Registration-free COM interop activates a component without using the Windows registry to store assembly information. Instead of registering a component on a computer during deployment, you create Win32-style manifest files at design time that contain information about binding and activation.


2 Answers

Before you even touch registration free com make sure your application works when the dll is registered. Once you are happy with this. It's time to try and get it to work registration free. First step is to unregister your dll. If you try and run your program now you should get ClassId not found.

First step is to create a manifest file for your application. A manifest file is an xml file which among other things can setup dependencies for your application. You may not know it, but since about Delphi 2007, if you have themes enabled, your application has had a manifest all along. Here it is from Delphi 2010 :

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">   <assemblyIdentity     type="win32"     name="CodeGear RAD Studio"     version="14.0.3615.26342"      processorArchitecture="*"/>   <dependency>     <dependentAssembly>       <assemblyIdentity         type="win32"         name="Microsoft.Windows.Common-Controls"         version="6.0.0.0"         publicKeyToken="6595b64144ccf1df"         language="*"         processorArchitecture="*"/>     </dependentAssembly>   </dependency>   <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">     <security>       <requestedPrivileges>         <requestedExecutionLevel           level="asInvoker"           uiAccess="false"/>         </requestedPrivileges>     </security>   </trustInfo> </assembly> 

Now I'm not sure if you can add to this and you can only have one manifest file per application, I just usually replace it completely. Since I want themes enabled I start off with this file and add my dependency. In your case you need to add a dependency for the skype4com.dll Here's what I need to add :

<assemblyIdentity    name="Skype4COM.X"    version="1.0.36.0"    type="win32"    processorArchitecture="x86"> </assemblyIdentity> 

Note I am actually adding a dependency to the Assembly Skye4COM.X and not the dll itself. Don't confuse the 2, although a dll can be an assembly an assembly is not necessarily 1 dll. This will become clear when we set up the assembly manifest/

Your manifest file now becomes :

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">   <assemblyIdentity     type="win32"     name="CodeGear RAD Studio"     version="14.0.3615.26342"      processorArchitecture="*"/>   <dependency>     <dependentAssembly>       <assemblyIdentity         type="win32"         name="Microsoft.Windows.Common-Controls"         version="6.0.0.0"         publicKeyToken="6595b64144ccf1df"         language="*"         processorArchitecture="*"/>     </dependentAssembly>   </dependency>   <dependency>     <dependentAssembly>       <assemblyIdentity          name="Skype4COM.X"          version="1.0.36.0"          type="win32"          processorArchitecture="x86">       </assemblyIdentity> </dependentAssembly>   </dependency>   <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">     <security>       <requestedPrivileges>         <requestedExecutionLevel           level="asInvoker"           uiAccess="false"/>         </requestedPrivileges>     </security>   </trustInfo> </assembly> 

Save this file with the same name as your executable, but with a .manifest suffix. For example SkypeClient.exe.manifest

The next step is to embed this manifest in your application. You'll need to create an resource file (rc file) with the following text :

#define RT_MANIFEST 24  #define APP_MANIFEST 1  APP_MANIFEST RT_MANIFEST SkypeClient.exe.manifest 

Add this file to your application and build. If you still have themes enabled you will get a duplicate resource warning, just removed the {$R *.res} from your dpr file. You should also see this in the project file :

{$R 'SkypeClient.manifest.res' 'SkypeClient.manifest.rc'} 

If you try and run your application now, you will get the following error message :

Unable to create process: The application has failed to start because its side-by-side configuration is incorrect. Please see the application event log or use the command-line sxstrace.exe tool for more detail.

We now need to add a manifest for the assembly (Skype4COM.X). Create a file called Skype4COM.X.manifest. We need to describe the assembly in the manifest file :

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">    <assemblyIdentity      name="Skype4COM.X"      version="1.0.36.0"      type="win32"     processorArchitecture="x86">   </assemblyIdentity>    <file name="Skype4COM.dll">     <typelib       tlbid="{03282B5D-B38F-469D-849A-09B0A7F4881B}"       version="1.0"       helpdir=""       flags="hasdiskimage"/>   </file> </assembly> 

Now place the Application the dll and the assembly manifest in the same folder and run!

If you get anymore errors you'll need to use SxSTrace to debug. This is available on Vista onwards. First start a trace :

SxSTrace trace -logfile:sxsTrace.etl 

run your program, and then press enter on the trace to finish it. Now parse the trace :

SxSTrace parse -logfile:SxSTrace.etl -outfile:SxStrace.txt 

You should have a comprehensive log of the whole process in SxSTrace.txt

like image 72
Steve Avatar answered Sep 21 '22 00:09

Steve


Refer to While & Muller's 2005 MSDN article "Registration-Free Activation of COM Components: A Walkthrough." It demonstrates with C++, C#, and VB, but none of that's important. The code portion — in steps 1 through 3 — are the same things you'd do in any COM application. The walkthrough explains:

The registration-free activation of COM components requires no special code in the server or in the client. All that's required is a matching pair of manifest files.

Create a manifest file for your COM DLL, and then create a manifest file for your application that refers to it.

like image 36
Rob Kennedy Avatar answered Sep 24 '22 00:09

Rob Kennedy