I have a 32-bit (x86) side-loaded Windows Store app
that works with a brokered Windows Runtime Component, it works smoothly and can launch desktop exe, load desktop dll using Reflection, etc.
I want to make this side-loaded app 64-bit. And after rebuilding the app as x64, it can never use the brokered Windows Runtime Component again. The error is
Additional information:
Unable to cast COM object of type 'StoreAppBrokeredWindowsRuntimeComponent.DirectInvoker' to interface type 'StoreAppBrokeredWindowsRuntimeComponent.IDirectInvokerClass'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{50EA3FD3-2383-5445-4002-8CBCBED5DB0F}' failed due to the following error: Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)).
From the doc Brokered Windows Runtime Components for a side-loaded Windows Store app,
Side-loaded applications can be 64-bit (provided there is both a 64-bit and 32-bit proxies registered), but this will be atypical.
Question:
How to build a 64-bit proxy?
The VS template can only build 32 bit (Win32) proxy. If change the WindowsRuntimeProxyStub
to x64, it cannot even be compiled - there are a bunch of LINK errors.
So 32-bit side-loaded app, 32-bit brokered Windows runtime component, and 32-bit proxy is the only working approach so far.
With the help of Microsoft Support, I have successfully built a 64 bit brokered runtime component and used it from a 64-bit side-loaded app.
To make it easier to follow, just use the following MS sample projects. You don't need to modify any code file at all. However, there are two errors in the template you need to fix first, see Important Notes at the end of this answer.
Brokered Windows Runtime Components for side-loaded Windows Store apps - Server
Brokered Windows Runtime Components for side-loaded Windows Store apps - Client
Unzip the code package(Brokered Windows Runtime Components for side-loaded Windows Store apps - Server.zip) and open the solution with Visual studio 2013 (Run as Administrator);
Change the platform of SampleProxy
project from Win32 to x64;
Open SampleProxy Property
->Configuration Properties
->Preprocessor
->Preprocessor Definitions
, and change two of definitions
WIN32->X64; REGISTER_PROXY_DLLWIN32->REGISTER_PROXY_DLL
Change the platform of EnterpriseIPCServer
project to x64.
Edit Post-build event command line of EnterpriseIPCServer
, replace each occurrence of x86
or Win32
with x64
, the command should be like this:
call "$(DevEnvDir)..\..\vc\vcvarsall.bat" x64
md "$(TargetDir)"\impl
md "$(TargetDir)"\reference
erase "$(TargetDir)\impl\*.winmd"
erase "$(TargetDir)\impl\*.pdb"
rem erase "$(TargetDir)\reference\*.winmd"
xcopy /y "$(TargetPath)" "$(TargetDir)impl"
xcopy /y "$(TargetDir)*.pdb" "$(TargetDir)impl"
winmdidl /nosystemdeclares /metadata_dir:C:\Windows\System32\Winmetadata "$(TargetPath)"
midl /metadata_dir "%WindowsSdkDir%References\CommonConfiguration\Neutral" /iid "$(SolutionDir)SampleProxy\$(TargetName)_i.c" /env x64 /x64 /h "$(SolutionDir)SampleProxy\$(TargetName).h" /winmd "$(TargetName).winmd" /W1 /char signed /nologo /winrt /dlldata "$(SolutionDir)SampleProxy\dlldata.c" /proxy "$(SolutionDir)SampleProxy\$(TargetName)_p.c" "$(TargetName).idl"
mdmerge -n 1 -i "$(ProjectDir)bin\$(PlatformName)\$(ConfigurationName)" -o "$(TargetDir)reference" -metadata_dir "%WindowsSdkDir%References\CommonConfiguration\Neutral" -partial
rem erase "$(TargetPath)"
First build the EnterpriseIPCServer
project.
Then build the SampleProxy
project.
Check the output files (Fabrikam.winmd & SampleProxy.dll).
Tricky enough, the 64-bit brokered runtime component is never used at all. All we need is the 32-bit brokered runtime component, but we need to register both 32-bit and 64-bit proxy.
Put the 3 files (32-bit brokered runtime component + 2 proxies) under the same folder, for example, C:\test. Then execute the following commands.
regsvr32.exe C:\test\SampleProxy_64.dll (I have renamed the 64-bit proxy)
regsvr32.exe C:\test\SampleProxy.dll (this is the 32 bit proxy)
icacls C:\test /T /grant "ALL APPLICATION PACKAGES":RX
Then in the 64-bit side-load app, reference the 32-bit brokered runtime component. But be careful to pick the one in the "reference" folder, don't reference the one in the "impl" folder.
For your reference, I have uploaded the code to this GitHub repository.
There are some errors in this sample project, which make it a nightmare to build it for the x86/win32 configuration.
In the x86 configuration of EnterpriseIPCServer, the following command in the post build event contains an unrecognizable switch /x86, it should be /win32.
midl /metadata_dir "%25WindowsSdkDir%25References\CommonConfiguration\Neutral" /iid "$(SolutionDir)SampleProxy\$(TargetName)_i.c" /env win32 /x86 /h "$(SolutionDir)SampleProxy\$(TargetName).h" /winmd "$(TargetName).winmd" /W1 /char signed /nologo /winrt /dlldata "$(SolutionDir)SampleProxy\dlldata.c" /proxy "$(SolutionDir)SampleProxy\$(TargetName)_p.c" "$(TargetName).idl"
In the Win32 configuration of the SampleProxy project, one of the preprocessor definitions REGISTER_PROXY_DLLWIN32 should be REGISTER_PROXY_DLL.