在现代软件开发中,跨语言集成已成为常态。C++以其性能优势常被用于开发性能关键型组件,而C#.NET则因其简洁性和强大的库支持而广泛应用于快速开发。本文将探讨如何在C#.NET Metro应用中集成C++ WinRT组件,以及这一过程中涉及的注册表设置和部署流程。
首先,需要创建一个C++ WinRT组件。这个过程涉及到使用C++编写组件代码,并将其编译成DLL。在Windows 8及更高版本中,C++应用程序可以基于XAML,这意味着不再需要传统的.RC和resource.h文件。将在后续的文章中详细探讨C++应用程序的构建过程。本文将重点介绍在构建和部署应用程序时后台发生的打包和安装过程。
在Windows中,有两种类型的注册与应用程序相关:扩展注册和类注册。这两种注册之间的关系可以通过Visual Studio中的Package.appxmanifest文件来理解。这个文件包含了部署应用程序所需的大部分信息,也是Windows用来识别应用程序的关键。
在Visual Studio 2011的解决方案资源管理器中,可以在CSharpApplication项目下找到Package.appxmanifest文件。这个文件包含了应用程序的标识信息,如包名称、发布者、版本等。以下是一个Package.appxmanifest文件的代码片段:
<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest">
<Identity Name="CSharpApplicationCallingCPPComponent" Publisher="CN=Kishore" Version="1.0.0.0" />
<Properties>
<DisplayName>CSharpApplication</DisplayName>
<PublisherDisplayName>Kishore</PublisherDisplayName>
<Logo>Images\StoreLogo.png</Logo>
<Description>CSharpApplication</Description>
</Properties>
<Prerequisites>
<OSMinVersion>6.2</OSMinVersion>
<OSMaxVersionTested>6.2</OSMaxVersionTested>
</Prerequisites>
<Resources>
<Resource Language="en-us" />
</Resources>
<Applications>
<Application Id="App" Executable="csharpapplication.exe" EntryPoint="CSharpApplication.App">
<VisualElements DisplayName="CSharpApplication" Logo="Images\Logo.png" SmallLogo="Images\SmallLogo.png" Description="CSharpApplication" ForegroundText="light" BackgroundColor="#222222" InitialRotationPreference="portrait">
<SplashScreen Image="Images\SplashScreen.png" />
</VisualElements>
</Application>
</Applications>
<Capabilities>
<Capability Name="internetClient" />
</Capabilities>
</Package>
应用程序通过实现诸如搜索、共享、播放队列等合同来实现扩展注册。在Windows启动页面上看到的磁贴实际上就是另一种合同激活,即windows.launch合同。如果查看注册表中的HKEY_CURRENT_USER\Software\Classes\Extensions\ContractId\Windows.Launch,可以找到在图1中看到的应用程序包ID。Windows.Launch下的所有内容都是按包ID组织的。
从图2中,可以看到包HKEY_CURRENT_USER\Software\Classes\Extensions\ContractId\Windows.Launch\ PackageId\csharpapplicationcallingcppcomponent_1.0.0.0_x86_neutral_kb63pw67p0swp。这个包有一个ActivatableClassId键。在该键下,可以看到App,如图3所示。这是这个扩展的类注册。
首先,有扩展,它们声明实现了这个合同,例如,实现了这个启动,然后有类。扩展指向类。类实际上是实现。所有应用程序都是Windows运行时对象,这是Windows操作系统所知道的。这是Windows运行时类,操作系统知道应用程序。
类注册中有趣的部分是应用程序的类注册。如果在注册表编辑器中向上看,应该看到一个名为ActivatableClasses的注册表键HKEY_CURRENT_USER\Software\Classes\ActivatableClasses,这是所有应用程序的类注册。在这里,再次找到包。所有的扩展,所有的类都是基于包组织的。这意味着应用程序或包有一组独特的类,它们不与其他应用程序共享扩展点或类。它们都是应用程序独有的。如果展开它,可以看到ActivatableClassId,在扩展中看到的名字。在这里,应该找到App classId。这是WinRT类注册。这对所有类型的应用程序、库等都是相同的。
在这里,可以看到一些注册属性。ActivationType是一个重要的一个。Windows运行时支持两种激活样式:进程内激活和进程外激活。所以Windows运行时支持进程内激活,提供DLL,Windows将其加载到进程中,它还支持进程外激活,将提供一个EXE,Windows将启动EXE作为类实现。
ActivationType = 1表示它是进程外激活类。进程外类有一个服务器。必须知道可执行文件在哪里,所以这里有服务器注册。
ActivationType = 0表示它是进程内激活。
进程外有一个服务器,所以这里有服务器注册。服务器的值App.AppXpdnr4x0evrk1yjmz5xfw2ksncfcjc5er.mca如图4所示。
图3中,在ActivationType下面,可以找到Server属性,它包含从上面的Server值中得到的App.AppXpdnr4x0evrk1yjmz5xfw2ksncfcjc5er.mca。服务器注册告诉Windows运行时足够的信息,关于实际上需要从磁盘上获取什么代码并开始运行,以启动应用程序。ExePath属性给出了EXE的路径。
Windows运行时支持两种公寓模型。MTA和STA。如果在VC++ COM、COM+早期工作过,那么可能已经为多线程公寓模型和单线程公寓模型编程了组件。
让看看在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsRuntime中存在的一些ActivatableClassId条目,如图5所示。