Using Amyuni ActiveX Controls Without System Registration

This forum contains a series of Technical Newsletters designed to share with our customers valuable information about implementing or using our products.
Post Reply
Devteam
Posts: 115
Joined: Fri Oct 14 2005
Location: Montreal
Contact:

Using Amyuni ActiveX Controls Without System Registration

Post by Devteam » Wed Oct 22 2008

This newsletter discusses the use of the Amyuni PDF Converter and Creator ActiveX controls without the need to register them on the target system.

Updated Feb. 28, 2012 to include an alternative method for instantiating the PDF Creator objects without registration

Prior to Windows XP, an ActiveX control had to be registered on the system before it could be used by an application. This registration creates a few issues among which:
  • Registering a control requires administrative rights on a system.
  • Registering a control affects multiple applications as the same DLL is shared among all applications using the same version of the control (some developers refer to this issue as the DLL hell.)
  • An application that unregisters a control will prevent all other applications from using it.
Solution 1

The first solution to these issues is to use side-by-side activation, or registration-free components; a concept that is very similar to what was introduced with .NET. The Amyuni controls lend themselves to be properly used for side-by-side activation.

When side-by-side registration is used, two things happen:
  • The Amyuni DLLs can be placed in each application's folder and are not shared with other applications.
  • The ActiveX controls are not registered in the system wide registry but each application acts as if it had its own registered components.
Enabling this feature is straight-forward with Visual Studio 2005. Simply open the "References" panel, right-click on the control that you are using and set the Isolated property to True. When this is done, Visual Studio generates a manifest file that is similar to what is shown below. Note that the manifest has to be in the same folder as your application.

Sample manifest

Code: Select all

<?xml version="1.0" encoding="utf-8"?>
<assembly xsi:schemaLocation="urn:schemas-microsoft-com:asm.v1 assembly.adaptive.xsd" manifestVersion="1.0" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <assemblyIdentity name="RegFreeActiveX.exe" version="1.0.0.0" type="win32" />
  <file name="CDINTF300.DLL" asmv2:size="3833856">
    <hash xmlns="urn:schemas-microsoft-com:asm.v2">
      <dsig:Transforms>
        <dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
      </dsig:Transforms>
      <dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
      <dsig:DigestValue>bzDoHXngss9IjlvVboV6yKaLGn8=</dsig:DigestValue>
    </hash>
    <typelib tlbid="{4856f147-7516-11d3-bbe5-d53dcbd65107}" version="3.0" helpdir="" resourceid="0" flags="CONTROL,HASDISKIMAGE" />
    <comClass clsid="{68b34269-7559-11d3-bbe5-d53dcbd65107}" threadingModel="Apartment" tlbid="{4856f147-7516-11d3-bbe5-d53dcbd65107}" progid="CDIntfEx.CDIntfEx" />
    <comClass clsid="{4475f8b9-1316-4853-82e6-c6149a7ba4c3}" tlbid="{4856f147-7516-11d3-bbe5-d53dcbd65107}" progid="CDIntfEx.Document" />
  </file>
  <file name="PDFCreactiveX.dll" asmv2:size="3908904">
    <hash xmlns="urn:schemas-microsoft-com:asm.v2">
      <dsig:Transforms>
        <dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
      </dsig:Transforms>
      <dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
      <dsig:DigestValue>fr8MjzCRDcVzR4bTgsnX3ju6BkU=</dsig:DigestValue>
    </hash>
    <typelib tlbid="{efe9e105-2215-4c88-9ef7-338b23c1e681}" version="3.0" helpdir="" resourceid="0" flags="HASDISKIMAGE" />
    <comClass clsid="{525ca8d6-81ee-4aed-b95c-9c4dbad5980b}" threadingModel="Apartment" tlbid="{efe9e105-2215-4c88-9ef7-338b23c1e681}" progid="PDFCreactiveX.PDFCreactiveX.4" description="PDFCreactiveX Class" />
    <comClass clsid="{0874c7bd-284c-42b9-8592-34d4ffd356a2}" threadingModel="both" tlbid="{efe9e105-2215-4c88-9ef7-338b23c1e681}" progid="PDFCreactiveX.acContainer.4" description="acContainer Class" />
    <comClass clsid="{020fea15-f7f4-4591-aa59-da77170c90c8}" threadingModel="both" tlbid="{efe9e105-2215-4c88-9ef7-338b23c1e681}" progid="PDFCreactiveX.acScript.4" description="acScript Class" />
    <comClass clsid="{ebe87457-268d-45e3-9c65-5d9727b50eec}" threadingModel="both" tlbid="{efe9e105-2215-4c88-9ef7-338b23c1e681}" progid="PDFCreactiveX.acEvaluator.4" description="acEvaluator Class" />
    <comClass clsid="{252944b4-1146-43ee-9b01-0df0442c65b0}" threadingModel="both" tlbid="{efe9e105-2215-4c88-9ef7-338b23c1e681}" progid="PDFCreactiveX.acBookmark.4" description="acBookmark Class" />
    <comClass clsid="{aafd2c46-6735-485b-b942-636be73ca20e}" threadingModel="both" tlbid="{efe9e105-2215-4c88-9ef7-338b23c1e681}" progid="PDFCreactiveX.Object.4" description="acObject Class" />
  </file>
	<file name="acPDFCrExt.dll" asmv2:size="491520">
		<hash xmlns="urn:schemas-microsoft-com:asm.v2">
			<dsig:Transforms>
				<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
			</dsig:Transforms>
			<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
			<dsig:DigestValue>xGOoqK69LZsgNxJoYF+v/DidXPA=</dsig:DigestValue>
		</hash>
		<typelib tlbid="{7582c533-e00f-44d9-83a4-516e5be4cd8b}" version="3.0" helpdir="" resourceid="0" flags="HASDISKIMAGE" />
		<comClass clsid="{210be69a-5edf-4541-a92a-4ad391724695}" threadingModel="both" tlbid="{7582c533-e00f-44d9-83a4-516e5be4cd8b}" progid="AcPDFCrExt.acFormatter.4" description="acFormatter Class" />
		<comClass clsid="{ce67d948-c7f6-4172-baaa-ee3b13791220}" threadingModel="Both" tlbid="{7582c533-e00f-44d9-83a4-516e5be4cd8b}" progid="AcPDFCrExt.acCategory.4" description="acCategory Class" />
		<comClass clsid="{505ca723-1698-4edf-899b-13d7a04e4083}" threadingModel="Both" tlbid="{7582c533-e00f-44d9-83a4-516e5be4cd8b}" progid="AcPDFCrExt.acFormat.4" description="acFormat Class" />
		<comClass clsid="{02ca005a-5208-4455-910a-8f916c878aea}" threadingModel="Apartment" tlbid="{7582c533-e00f-44d9-83a4-516e5be4cd8b}" progid="AcPDFCrExt.acBookmarkCtrl.4" description="acBookmarkCtrl Class" />
		<comClass clsid="{03a08e51-58ad-4173-b3a5-3f6b795ec9b2}" threadingModel="Apartment" tlbid="{7582c533-e00f-44d9-83a4-516e5be4cd8b}" progid="acPDFCrExt.acPropCtrl.4" description="acPropCtrl Class" />
		<comClass clsid="{67e6eb4e-a429-4d10-84e1-443d6be717ce}" threadingModel="Apartment" tlbid="{7582c533-e00f-44d9-83a4-516e5be4cd8b}" progid="AcPDFCrExt.acStatusCtrl.4" description="acStatusCtrl Class" />
		<comClass clsid="{5740088e-fc50-4cc2-86f5-a59a3536c823}" threadingModel="Apartment" tlbid="{7582c533-e00f-44d9-83a4-516e5be4cd8b}" progid="AcPDFCrExt.acPropertiesDlg.4" description="acPropertiesDlg Class" />
		<comClass clsid="{cb606433-6a88-438e-82cf-c4baf1ff3bd9}" threadingModel="Apartment" tlbid="{7582c533-e00f-44d9-83a4-516e5be4cd8b}" progid="AcPDFCrExt.acGridUnitsDlg.4" description="acGridUnitsDlg Class" />
		<comClass clsid="{2564493b-2077-420e-b205-54c4ed338b0e}" threadingModel="Apartment" tlbid="{7582c533-e00f-44d9-83a4-516e5be4cd8b}" progid="AcPdfCrExt.acDocSettingsDlg.4" description="acDocSettingsDlg Class" />
		<comClass clsid="{0e63bb9e-7a41-4441-99d0-23bac684ad36}" threadingModel="Apartment" tlbid="{7582c533-e00f-44d9-83a4-516e5be4cd8b}" progid="AcPDFCrExt.acThumbnailCtrl.4" description="acThumbnailCtrl Class" />
	</file>
</assembly>
Solution 2

The second solution is to dynamically load PDFCreactiveX, retrieve the class factory, then use the class factory to instantiate the objects.
- Loading the DLL is done using: g_hLibPDFCreactiveX = LoadLibrary( DllPath ) where DllPath is the full path to where the DLL is located or a path relative to the calling application.
- Retrieving the class factory is done using: pfnDllGetClassObject = GetProcAddress( g_hLibPDFCreactiveX, "DllGetClassObject" ) followed by pfnDllGetClassObject( __uuidof(ACPDFCREACTIVEX::PDFCreactiveX), IID_IClassFactory, (LPVOID *) &g_cfPDFCreactiveX ).
- Instantiating the object is done using: g_cfPDFCreactiveX->CreateInstance( NULL, __uuidof(ACPDFCREACTIVEX::IPDFCreactiveX), (void **)&punknown );

Here a more complete example that shows all the steps:

Code: Select all

#import	"PDFCreactiveX.dll" named_guids rename("GetObject", "PDFCreactiveX_GetObject") rename("TextOut", "PDFCreactiveX_TextOut") rename("GetCharWidth", "PDFCreactiveX_GetCharWidth") rename("DrawText", "PDFCreactiveX_DrawText")

HMODULE		g_hLibPDFCreactiveX;
IClassFactoryPtr	g_cfPDFCreactiveX;

g_hLibPDFCreactiveX = LoadLibrary( modulePath );
if ( g_hLibPDFCreactiveX )
{
	//if the module was loaded:
	//get class object function pointer
	pfnDllGetClassObjectType pfnDllGetClassObject = (pfnDllGetClassObjectType) GetProcAddress( g_hLibPDFCreactiveX, "DllGetClassObject" );

	//get class factory interface
	HRESULT hr = pfnDllGetClassObject( __uuidof(ACPDFCREACTIVEX::PDFCreactiveX), IID_IClassFactory, (LPVOID *) &g_cfPDFCreactiveX );
	if ( FAILED(hr) )
	{
		// error processing
		return;
	}
	//Create PDFCreator object
	IUnknownPtr  punknown;
	ACPDFCREACTIVEX::IPDFCreactiveXPtr pdfPtr;
	hr = g_cfPDFCreactiveX->CreateInstance( NULL, __uuidof(ACPDFCREACTIVEX::IPDFCreactiveX), (void **)&punknown );
	if ( SUCCEEDED(hr) )
	{
		pdfPtr = punknown;

		// now do some processing with pdfPtr
		// pdfPtr->Save(FileName, ACPDFCREACTIVEX::acFileSaveView);
	}
}
FreeLibrary( g_hLibPDFCreactiveX );

Amyuni Development Team

Efficient and accurate conversion to PDF, XPS, PDF/A and more. Free trials at - http://www.amyuni.com

Post Reply