深入解析 - 第三部分:应用程序安装和运行的内部机制 – WinRT, Windows 8, C++, C#.NET, Metro





0/5 (0投票)
应用程序安装和运行的内部机制 – WinRT, Windows 8, C++, C#.NET, Metro
在此前的文章中,我们已经开发了一个 C++ WinRT 组件 DLL 和 C#.NET 应用程序。
在此,我们已经看到了编译器生成的组件,用于使 C# 应用程序能够访问 C++ WinRT 组件。
请在此处参阅关于“Windows 8 新特性初探”的文章 此处。
进一步地,我创建了一个 C++ Metro 应用程序,并从该应用程序中访问了 C++ WinRT 组件 DLL。这里有趣的部分是 C++ 应用程序是基于 XAML 的。在 C++ (对于 Metro) 中不再有 .RC 和 resource.h 文件。我们将在另一篇文章中探讨 C++ 应用程序。在本文中,让我们来回顾一下在构建和部署应用程序时在后台发生的打包和安装过程。
基本上,我们的应用程序有两个注册项。
- 扩展注册
- 类注册
图 1(来自 Build con)展示了两者之间的关系。
在 Visual Studio 2011 -> 解决方案资源管理器 -> CSharpApplication
项目中,您可以找到一个名为 Package.appxmanifest 的文件,如图 1 所示。该文件包含了部署应用程序所需的大部分信息。这是 Windows 用于识别应用程序的信息。程序包名称是在大多数识别过程中使用的名称。
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 所示。
从图 2 中,我们可以看到我们的包 HKEY_CURRENT_USER\Software\Classes\Extensions\ContractId\Windows.Launch\ PackageId\csharpapplicationcallingcppcomponent_1.0.0.0_x86_neutral_kb63pw67p0swp。此包有一个 ActivatableClassId
键。在该键下,我们看到 App,如图 3 所示。这是该扩展的类注册。
让我们看看应用程序的类注册是什么样的。首先,我们有扩展,它们说明我实现了这个合同,例如,我实现了这个启动,然后我们有类。扩展指向类。类实际上是实现。对 Windows OS 而言,所有应用程序都只是 Windows Runtime 对象,这就是一切开始的地方。这是 OS 了解的您应用程序的 Windows Runtime 类。
有趣的部分在于应用程序的类注册。如果我们向上导航注册表编辑器,应该会看到一个名为 ActivatableClasses
的注册表项,位于 HKEY_CURRENT_USER\Software\Classes\ActivatableClasses,这里是所有应用程序的类注册所在。这里,我们再次找到包。所有扩展,所有类都是基于包组织的。这意味着我们的应用程序或包具有一组唯一的类,并且它们与其他应用程序不共享扩展点或类。它们都是我们应用程序独有的。如果我们展开它,我们会看到 ActivatableClassId
,与我们在扩展中看到的名称相同。在这里,我们应该找到 App classId
。这是 WinRT 类注册。对于所有类型的应用程序、库等,这都是相同的。
在这里,我们可以看到一些注册属性。ActivationType
是一个重要的属性。Windows Runtime 支持两种激活样式:
InProcess
激活- Out of process 激活
因此,Windows Runtime 支持 InProcess
激活,在这种情况下,我们提供 DLL,Windows 将其加载到进程中;它还支持 Out of process 激活,在这种情况下,我们将提供一个 EXE,Windows 将该 EXE 作为您的类实现启动。
注册表键值
ActivationType = 1
表示它是 Out of process 激活类。Out of process 类有一个服务器。我们需要知道可执行文件在哪里,因此这里有一个服务器注册。
ActivationType = 0
表示它是 In-process 激活
Out of process 有一个服务器,因此这里有一个服务器注册。服务器的值为 App.AppXpdnr4x0evrk1yjmz5xfw2ksncfcjc5er.mca,如图 4 所示。
在图 3 中,在 ActivationType
下方,我们可以找到 Server
属性,其中包含我们从上面的 Server 值中获得的 App.AppXpdnr4x0evrk1yjmz5xfw2ksncfcjc5er.mca。服务器注册向 Windows Runtime 提供了足够的信息,说明我们需要从磁盘获取哪些代码并开始运行以启动应用程序。
Windows Runtime 支持两种单元模型:MTA 和 STA。如果您之前在 VC++ COM、COM+ 中工作过,那么您可能已经为多线程单元模型和单线程单元模型编程过组件。
让我们在 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsRuntime 下查看一些 Windows Runtime 的 ActivatableClassId
条目,如图 5 所示。
最后,吸引我注意的是图 6 中显示的部署管道过程,它展示了上述信息的整体视图。
“只有那些敢于冒险走得更远的人,才能发现他们能走多远。” – T.S. Eliot