C# 64位侧面加载的应用程序,用于使用代理的Windows运行时组件

C# 64位侧面加载的应用程序,用于使用代理的Windows运行时组件,c#,windows-runtime,windows-store-apps,ipc,32bit-64bit,C#,Windows Runtime,Windows Store Apps,Ipc,32bit 64bit,我有一个32位(x86)侧面加载的Windows应用商店应用程序,它与代理Windows运行时组件一起工作,工作平稳,可以启动桌面exe,使用反射加载桌面dll,等等 我想让这个侧面加载的应用程序64位。在将应用程序重新构建为x64之后,它再也不能使用代理的Windows运行时组件。错误是 其他信息: 无法将类型为“StoreAppBrokeredWindowsRuntimeComponent.DirectInvoker”的COM对象强制转换为接口类型“StoreAppBrokeredWindo

我有一个32位(x86)侧面加载的
Windows应用商店应用程序
,它与代理Windows运行时组件一起工作,工作平稳,可以启动桌面exe,使用反射加载桌面dll,等等

我想让这个侧面加载的应用程序64位。在将应用程序重新构建为x64之后,它再也不能使用代理的Windows运行时组件。错误是

其他信息:

无法将类型为“StoreAppBrokeredWindowsRuntimeComponent.DirectInvoker”的COM对象强制转换为接口类型“StoreAppBrokeredWindowsRuntimeComponent.IDirectInvokerClass”。此操作失败,因为对IID为“{50EA3FD3-2383-5445-4002-8CBCBED5DB0F}”的接口的COM组件的QueryInterface调用由于以下错误而失败:类未注册(HRESULT的异常:0x80040154(REGDB_E_CLASSNOTREG))

从医生那里

侧面加载的应用程序可以是64位(前提是同时注册了64位和32位代理),但这是不典型的

问题:

如何构建64位代理

只能生成32位(Win32)代理。如果将
WindowsRuntimeProxyStub
更改为x64,它甚至无法编译-存在大量链接错误


因此,32位侧面加载的应用程序、32位代理Windows运行时组件和32位代理是目前为止唯一有效的方法。

在Microsoft支持的帮助下,我成功构建了一个64位代理运行时组件,并从一个64位侧面加载的应用程序中使用它

为了便于理解,只需使用以下MS示例项目。您根本不需要修改任何代码文件。但是,模板中有两个错误需要首先修复,请参见本答案末尾的重要注意事项

构建64位代理组件和代理的步骤
  • 解压缩代码包(侧面加载的Windows应用商店应用程序的代理Windows运行时组件-Server.zip)并使用Visual studio 2013打开解决方案(以管理员身份运行

  • SampleProxy
    project的平台从Win32改为x64

  • 打开
    SampleProxy属性
    ->
    配置属性
    ->
    预处理器
    ->
    预处理器定义
    ,并更改其中两个定义

  • WIN32->X64;注册\u代理\u DLLWIN32->注册\u代理\u DLL

  • EnterpriseIPCServer
    project的平台更改为x64

  • 编辑
    EnterpriseIPCServer
    的生成后事件命令行,将
    x86
    Win32
    的每个事件替换为
    x64
    ,命令应如下所示:

  • 首先构建
    EnterpriseIPCServer
    项目

  • 然后构建
    SampleProxy
    项目

  • 检查输出文件(Fabrikam.winmd和SampleProxy.dll)

    使用64位代理组件和代理的步骤 非常棘手的是,从未使用64位代理运行时组件。我们只需要32位代理运行时组件,但我们需要同时注册32位和64位代理

    将3个文件(32位代理运行时组件+2个代理)放在同一文件夹下,例如C:\test。然后执行以下命令

    regsvr32.exe C:\test\SampleProxy_64.dll(我已重命名64位代理)

    regsvr32.exe C:\test\SampleProxy.dll(这是32位代理)

    icacls C:\test/T/grant“所有应用程序包”:RX

    然后在64位侧面加载应用程序中,引用32位代理运行时组件。但是要小心选择“reference”文件夹中的那个,不要引用“impl”文件夹中的那个

    为供参考,我已将代码上载到

    重要注意事项 此示例项目中存在一些错误,这使得为x86/win32配置构建它成为一场噩梦

    EnterpriseIPCServer的x86配置中,生成后事件中的以下命令包含无法识别的开关/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\u PROXY\u DLLWIN32应为REGISTER\u PROXY\u DLL

    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)"