64 位侧载应用程序使用 Brokered Windows 运行时组件
64 bit side-loaded app to use Brokered Windows Runtime Components
我有一个 32 位 (x86) 侧面加载的 Windows Store app
,它与代理 Windows 运行时组件一起工作,它运行流畅,可以启动桌面 exe,使用反射加载桌面 dll,等等
我想将此旁加载应用程序设为 64 位。在将应用程序重建为 x64 后,它再也不能使用代理的 Windows 运行时组件。错误是
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)).
来自文档 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.
问题:
如何构建 64 位代理?
VS template 只能构建 32 位 (Win32) 代理。如果将 WindowsRuntimeProxyStub
更改为 x64,它甚至无法编译 - 有一堆 LINK 错误。
所以 32 位侧载应用程序、32 位代理 Windows 运行时组件和 32 位代理是目前为止仅 的工作方法。
在 Microsoft 支持的帮助下,我成功构建了 64 位代理运行时组件,并在 64 位侧加载应用程序中使用了它。
为了更容易理解,只需使用以下 MS 示例项目。您根本不需要修改 any 代码文件。但是,您需要先修复模板中的两个错误,请参阅此答案末尾的重要说明。
Brokered Windows Runtime Components for side-loaded Windows Store apps - Server
Brokered Windows Runtime Components for side-loaded Windows Store apps - Client
构建 64 位代理组件和代理的步骤
解压代码包(Brokered Windows 运行time Components for side-loaded Windows Store apps - Server.zip)并打开解决方案使用 Visual studio 2013(运行 作为管理员);
将SampleProxy
项目的平台从Win32改为x64;
打开SampleProxy Property
->Configuration Properties
->Preprocessor
->Preprocessor Definitions
,修改两个定义
WIN32->X64; REGISTER_PROXY_DLLWIN32->REGISTER_PROXY_DLL
将 EnterpriseIPCServer
项目的平台更改为 x64。
编辑Post-构建EnterpriseIPCServer
的事件命令行,用x64
替换每个出现的x86
或Win32
,命令应该是这样的:
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)"
首先构建 EnterpriseIPCServer
项目。
然后构建 SampleProxy
项目。
检查输出文件(Fabrikam.winmd & SampleProxy.dll)。
使用 64 位代理组件和代理的步骤
够棘手的是,64 位代理运行时组件根本没有被使用过。我们只需要 32 位代理运行时组件,但我们需要注册 both 32 位和 64 位代理。
将3个文件(32位代理运行时组件+2个代理)放在同一个文件夹下,例如C:\test。然后执行以下命令。
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
然后在 64 位侧加载应用程序中,引用 32 位代理运行时组件。但是要注意选择"reference"文件夹中的那个,不要引用"impl"文件夹中的那个。
为了您的参考,我已经将代码上传到this GitHub repository。
重要提示
此示例项目中存在一些错误,这使得为 x86/win32 配置构建它成为一场噩梦。
在 EnterpriseIPCServer 的 x86 配置中,post 构建事件中的以下命令包含无法识别的开关 /x86 , 应该是 /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"
在 SampleProxy 项目的 Win32 配置中,预处理器定义之一 REGISTER_PROXY_DLLWIN32 应该是 REGISTER_PROXY_DLL。
我有一个 32 位 (x86) 侧面加载的 Windows Store app
,它与代理 Windows 运行时组件一起工作,它运行流畅,可以启动桌面 exe,使用反射加载桌面 dll,等等
我想将此旁加载应用程序设为 64 位。在将应用程序重建为 x64 后,它再也不能使用代理的 Windows 运行时组件。错误是
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)).
来自文档 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.
问题:
如何构建 64 位代理?
VS template 只能构建 32 位 (Win32) 代理。如果将 WindowsRuntimeProxyStub
更改为 x64,它甚至无法编译 - 有一堆 LINK 错误。
所以 32 位侧载应用程序、32 位代理 Windows 运行时组件和 32 位代理是目前为止仅 的工作方法。
在 Microsoft 支持的帮助下,我成功构建了 64 位代理运行时组件,并在 64 位侧加载应用程序中使用了它。
为了更容易理解,只需使用以下 MS 示例项目。您根本不需要修改 any 代码文件。但是,您需要先修复模板中的两个错误,请参阅此答案末尾的重要说明。
Brokered Windows Runtime Components for side-loaded Windows Store apps - Server
Brokered Windows Runtime Components for side-loaded Windows Store apps - Client
构建 64 位代理组件和代理的步骤
解压代码包(Brokered Windows 运行time Components for side-loaded Windows Store apps - Server.zip)并打开解决方案使用 Visual studio 2013(运行 作为管理员);
将
SampleProxy
项目的平台从Win32改为x64;打开
SampleProxy Property
->Configuration Properties
->Preprocessor
->Preprocessor Definitions
,修改两个定义
WIN32->X64; REGISTER_PROXY_DLLWIN32->REGISTER_PROXY_DLL
将
EnterpriseIPCServer
项目的平台更改为 x64。编辑Post-构建
EnterpriseIPCServer
的事件命令行,用x64
替换每个出现的x86
或Win32
,命令应该是这样的:
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)"
首先构建
EnterpriseIPCServer
项目。然后构建
SampleProxy
项目。
检查输出文件(Fabrikam.winmd & SampleProxy.dll)。
使用 64 位代理组件和代理的步骤
够棘手的是,64 位代理运行时组件根本没有被使用过。我们只需要 32 位代理运行时组件,但我们需要注册 both 32 位和 64 位代理。
将3个文件(32位代理运行时组件+2个代理)放在同一个文件夹下,例如C:\test。然后执行以下命令。
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
然后在 64 位侧加载应用程序中,引用 32 位代理运行时组件。但是要注意选择"reference"文件夹中的那个,不要引用"impl"文件夹中的那个。
为了您的参考,我已经将代码上传到this GitHub repository。
重要提示
此示例项目中存在一些错误,这使得为 x86/win32 配置构建它成为一场噩梦。
在 EnterpriseIPCServer 的 x86 配置中,post 构建事件中的以下命令包含无法识别的开关 /x86 , 应该是 /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"
在 SampleProxy 项目的 Win32 配置中,预处理器定义之一 REGISTER_PROXY_DLLWIN32 应该是 REGISTER_PROXY_DLL。