I have a game that uses flash activex component.
The problem is I need a specific version of flash.
I don't want to register the component over the existing higher version which can cause big security issues. I only want to use it for my application.
I've heard about registration free com technology using a manifest file for my application but didn't found any information on using it with flash activex or even its possible.
So my question is it possible to us the flash activex component as a registration free com? if yes then what are the requirements and how the manifest file should look as my try failed.
This is the .manifest I've tried:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32" name="App" version="1.0.0.1"
processorArchitecture="x86" publicKeyToken="0000000000000000" />
<file name="Flash8.ocx">
<comClass clsid="{D27CDB6E-AE6D-11cf-96B8-444553540000}" threadingModel="Both" />
</file>
</assembly>
WARNING: Before I give you too much hope, I haven't tested this with Flash. I've tested it with smaller stuff where I "owned" both COM client and server. If Flash or some software it depends on requires registry settings other than pure COM and ActiveX controls, and even so, settings which are not available in manifests (e.g. categories), this might not work.
Define one Assembly Manifest for each file that Flash installs, that matches the COM settings that Flash registers during installation. If you know enough COM, you'll-know-where-to-look. Each of these manifest files must have a name different from the DLL.
Then, create an Application Manifest for your executable and add assembly dependencies after the file names you chose previously. If your application doesn't have an embedded manifest, this will be <your-application>.exe.manifest
. If it has, you must make your build tool include these dependencies.
my-application.exe.manifest
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<!--
name: a string with the format: Organization.Division.Name
Note: It doesn't matter
version: 4 numbers between 0 and 65535 separated with dots
Note: It doesn't matter
-->
<assemblyIdentity type="win32" name="My.Application" version="1.0.0.0"/>
<dependency>
<dependentAssembly>
<!--
name: a string with the format: Organization.Division.Name
Note: It doesn't matter, but it must match what's in the manifest
version: 4 numbers between 0 and 65535 separated with dots
Note: It doesn't matter, but it must match what's in the manifest
-->
<assemblyIdentity type="win32" name="Adobe.Flash.Control" version="8.0.42.0"/>
</dependentAssembly>
</dependency>
</assembly>
Adobe.Flash.Control.manifest
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<!--
name: a string with the format: Organization.Division.Name
Note: It doesn't matter, but it must match what's in the dependency
version: 4 numbers between 0 and 65535 separated with dots
Note: It doesn't matter, but it must match what's in the dependency
-->
<assemblyIdentity type="win32" name="Adobe.Flash.Control" version="8.0.42.0"/>
<!-- file elements
name: HKEY_CLASSES_ROOT\CLSID\{CLSID}\InprocServer32, default value
HKEY_CLASSES_ROOT\TypeLib\{TLBID}\{version}\{lcid}\win32, default value
Note: Keep only the file names
Note: In this case, the class factories and the type library happen to be in the same file
Otherwise, the comClass and the typelib elements would be under different file elements
-->
<file name="Flash8g.ocx">
<!-- comClass elements
description: HKEY_CLASSES_ROOT\CLSID\{CLSID}, default value
clsid: {CLSID}
threadingModel: HKEY_CLASSES_ROOT\CLSID\{CLSID}\InprocServer32, ThreadingModel
tlbid: HKEY_CLASSES_ROOT\CLSID\{CLSID}\TypeLib, default value
progid: HKEY_CLASSES_ROOT\CLSID\{CLSID}\ProgID, default value
miscStatus: HKEY_CLASSES_ROOT\CLSID\{CLSID}\MiscStatus, default value
miscStatusIcon: HKEY_CLASSES_ROOT\CLSID\{CLSID}\MiscStatus\4, default value
miscStatusContent: HKEY_CLASSES_ROOT\CLSID\{CLSID}\MiscStatus\1, default value
miscStatusDocprint: HKEY_CLASSES_ROOT\CLSID\{CLSID}\MiscStatus\8, default value
miscStatusThumbnail: HKEY_CLASSES_ROOT\CLSID\{CLSID}\MiscStatus\2, default value
-->
<comClass description="Shockwave Flash Object"
clsid="{D27CDB6E-AE6D-11cf-96B8-444553540000}"
threadingModel="Apartment"
tlbid="{D27CDB6B-AE6D-11cf-96B8-444553540000}"
progid="ShockwaveFlash.ShockwaveFlash"
miscStatus=""
miscStatusContent="recomposeonresize,cantlinkinside,insideout,activatewhenvisible,setclientsitefirst">
<progid>MacromediaFlashPaper.MacromediaFlashPaper</progid>
<progid>ShockwaveFlash.ShockwaveFlash.1</progid>
<progid>ShockwaveFlash.ShockwaveFlash.3</progid>
<progid>ShockwaveFlash.ShockwaveFlash.4</progid>
<progid>ShockwaveFlash.ShockwaveFlash.5</progid>
<progid>ShockwaveFlash.ShockwaveFlash.6</progid>
<progid>ShockwaveFlash.ShockwaveFlash.7</progid>
<progid>ShockwaveFlash.ShockwaveFlash.8</progid>
</comClass>
<comClass description="Macromedia Flash Factory Object"
clsid="{D27CDB70-AE6D-11cf-96B8-444553540000}"
threadingModel="Apartment"
tlbid="{D27CDB6B-AE6D-11cf-96B8-444553540000}"
progid="FlashFactory.FlashFactory">
<progid>FlashFactory.FlashFactory.1</progid>
</comClass>
<!-- typelib elements
tlbid: {TLBID}
version: HKEY_CLASSES_ROOT\CLSID\{CLSID}\Version, default value
HKEY_CLASSES_ROOT\Interface\{IID}\TypeLib, Version
helpdir: HKEY_CLASSES_ROOT\TypeLib\{TLBID}\{version}\HELPDIR, default value
resourceid: HKEY_CLASSES_ROOT\TypeLib\{TLBID}\{lcid}, the subkey name
flags: HKEY_CLASSES_ROOT\TypeLib\{TLBID}\{version}\Flags, default value
-->
<typelib tlbid="{D27CDB6B-AE6D-11cf-96B8-444553540000}"
version="1.0"
helpdir="."
resourceid="0"
flags=""/>
<!-- comInterfaceProxyStub elements
iid: {IID}
name: HKEY_CLASSES_ROOT\Interface\{IID}, default value
tlbid: HKEY_CLASSES_ROOT\Interface\{IID}\TypeLib, default value
baseInterface: HKEY_CLASSES_ROOT\Interface\{IID}\BaseInterface, default value
numMethods: HKEY_CLASSES_ROOT\Interface\{IID}\NumMethods, default value
proxyStubClsid32: HKEY_CLASSES_ROOT\Interface\{IID}\ProxyStubClsid32, default value
threadingModel: HKEY_CLASSES_ROOT\CLSID\{ProxyStubClsid32}\InprocServer32, ThreadingModel
-->
<!-- I found no need for any comInterfaceProxyStub -->
</file>
<!-- comInterfaceExternalProxyStub elements
iid: {IID}
baseInterface: HKEY_CLASSES_ROOT\Interface\{IID}\BaseInterface, default value
numMethods: HKEY_CLASSES_ROOT\Interface\{IID}\NumMethods, default value
name: HKEY_CLASSES_ROOT\Interface\{IID}, default value
tlbid: HKEY_CLASSES_ROOT\Interface\{IID}\TypeLib, default value
proxyStubClsid32: HKEY_CLASSES_ROOT\Interface\{IID}\ProxyStubClsid32, default value
-->
<!--
I found these lingering from the current Flash installation I have.
Please check if they are the same for Flash 8.
If you don't need them, just remove them.
These are comInterfaceExternalProxyStub and not comInterfaceProxyStub,
because both {00020420-0000-0000-C000-000000000046} (PSDispatch, IDispatch-based interfaces)
and {00020424-0000-0000-C000-000000000046} (PSOAInterface, Type Library interfaces)
come with Windows.
-->
<comInterfaceExternalProxyStub iid="{86230738-D762-4C50-A2DE-A753E5B1686F}"
name="IFlashObject"
tlbid="{D27CDB6B-AE6D-11CF-96B8-444553540000}"
proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"/>
<comInterfaceExternalProxyStub iid="{D27CDB6C-AE6D-11CF-96B8-444553540000}"
name="IShockwaveFlash"
tlbid="{D27CDB6B-AE6D-11CF-96B8-444553540000}"
proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"/>
<comInterfaceExternalProxyStub iid="{D27CDB6D-AE6D-11CF-96B8-444553540000}"
name="_IShockwaveFlashEvents"
tlbid="{D27CDB6B-AE6D-11CF-96B8-444553540000}"
proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"/>
</assembly>
I tested with the following bare-bones example, and it seems to work. Using Process Explorer, I can see that it loads the local Flash8g.ocx:
my-application.cpp
#include <windows.h>
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
)
{
HRESULT hr;
if (SUCCEEDED(hr = CoInitialize(NULL))) {
CLSID clsid;
// Both ways work
if (SUCCEEDED(hr = CLSIDFromProgID(L"ShockwaveFlash.ShockwaveFlash.8", &clsid))) {
/*if (SUCCEEDED(hr = CLSIDFromString(L"{D27CDB6E-AE6D-11cf-96B8-444553540000}", &clsid))) {*/
IDispatch *flash;
// IID_PPV_ARGS is better, but doesn't exist in older SDKs
/*if (SUCCEEDED(hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&flash)))) {*/
if (SUCCEEDED(hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IDispatch, (void**)&flash))) {
OLECHAR name[] = L"ReadyState";
LPOLESTR names[] = { &name[0] };
DISPID dispid;
if (SUCCEEDED(hr = flash->GetIDsOfNames(IID_NULL, names, sizeof(names)/sizeof(names[0]), LOCALE_SYSTEM_DEFAULT, &dispid))) {
DISPPARAMS params;
VARIANT result;
EXCEPINFO excepinfo;
UINT argerr;
params.rgvarg = NULL;
params.rgdispidNamedArgs = NULL;
params.cArgs = 0;
params.cNamedArgs = 0;
// Initialize out args due to buggy IDispatch implementations
VariantInit(&result);
excepinfo.wCode = 0;
excepinfo.wReserved = 0;
excepinfo.bstrSource = NULL;
excepinfo.bstrDescription = NULL;
excepinfo.bstrHelpFile = NULL;
excepinfo.dwHelpContext = 0;
excepinfo.pvReserved = NULL;
excepinfo.pfnDeferredFillIn = NULL;
excepinfo.scode = S_OK;
argerr = 0;
if (SUCCEEDED(hr = flash->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, ¶ms, &result, &excepinfo, &argerr))) {
MessageBox(NULL, "The example ran to completion.", "Flash test", MB_OK);
VariantClear(&result);
SysFreeString(excepinfo.bstrSource);
excepinfo.bstrSource = NULL;
SysFreeString(excepinfo.bstrDescription);
excepinfo.bstrDescription = NULL;
SysFreeString(excepinfo.bstrHelpFile);
excepinfo.bstrHelpFile = NULL;
}
}
flash->Release();
flash = NULL;
}
}
CoUninitialize();
}
if (SUCCEEDED(hr)) {
return 0;
}
else {
return 1;
}
}