Registration-free COM client

thedeemon via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon Jun 27 19:30:56 PDT 2016


On Monday, 27 June 2016 at 21:17:52 UTC, Thalamus wrote:
> Hi everyone,
>
> I've succeeded in using D as a client for regular (registered) 
> COM servers in the past, but in this case, I'm building the 
> server as well. I would like to avoid registering it if 
> possible so XCOPY-like deployment remains an option. Can a 
> registration-free COM client be built in D? If so, how can the 
> code be setup to consume the manifest file, or alternately, is 
> there a way to just point D to the correct assembly directly in 
> code?

To load load a COM object from a given file (DLL or AX) without 
having it registered, just load the file with CoLoadLibrary() and 
use its DllGetClassObject() function to get IClassFactory which 
will give you any kind of object in this library.
Here's how I do it (in my case the requested object has 
"IBaseFilter" COM interface):

IBaseFilter createDSFilterFromFile(GUID guid, string dir, string 
fname) {
	auto curdir = getcwd();
	scope(exit) chdir(curdir);
	chdir(dir); // in case the lib depends on other dlls nearby
	
	auto hinst = CoLoadLibrary( cast(wchar*) buildPath(dir, 
fname).toUTF16z, TRUE);
	enforce!COMException(hinst);

	auto fnGetClassObject = cast(LPFNGETCLASSOBJECT) 
GetProcAddress(hinst, "DllGetClassObject");
	enforce!COMException(fnGetClassObject);

	IClassFactory factory;
	auto iid = IID_IClassFactory;
	fnGetClassObject(&guid, &iid, 
cast(void**)&factory).checkHR("fnGetClassObject failed");
	enforce!COMException(factory);
	
	IBaseFilter ibf;
	factory.CreateInstance(null, &IID_IBaseFilter, 
cast(void**)&ibf).checkHR("factory.CreateInstance");
	return ibf;
}


More information about the Digitalmars-d-learn mailing list