傳統應用通過稀疏包(Sparse Package)插上現代的翅膀
許多Windows 10/11可擴展性功能需要在非UWP桌面應用中使用程序包標識符,包括后台任務(BackgroundTasks)、通知(Notifications)、動態磁貼(LiveTiles) 和共享目標(Share)。 對於這些情況OS需要使用標識來識別相應API的調用方。
在Windows 10版本v2004之前的OS發行版中,向桌面應用授予標識符的唯一方式是將該應用打包到已簽名的MSIX包中。對於這些應用,將在程序包清單中指定標識,並由MSIX部署管道根據清單中的信息處理標識注冊。程序包清單中引用的所有內容都存在於MSIX包中。
從Windows 10版本v2004開始,可以通過生成稀疏包並將其注冊到應用,向未打包到MSIX包中的桌面應用授予包標識符。通過此支持,尚不能采用MSIX打包方式進行部署的桌面應用可以使用需要程序包標識符的Windows 10/11可擴展性功能。
需要包標識的功能(新式Windows 10/11體驗)
https://docs.microsoft.com/zh-cn/windows/apps/desktop/modernize/modernize-packaged-apps
如果要將桌面應用更新為新式Windows 10體驗,請注意,許多功能僅在具有程序包標識符的桌面應用中可用。
可通過多種方式向桌面應用授予程序包標識符:
- 將其打包到MSIX包中。MSIX是一種新式應用包格式,提供適合所有Windows應用、WPF、Windows窗體和Win32應用的通用打包體驗。它提供了可靠的安裝和更新體驗、功能系統靈活的托管安全模型、對MicrosoftStore的支持、企業管理以及許多自定義分發模型。有關詳細信息,請參閱MSIX文檔中的打包桌面應用程序。
- 如果無法采用MSIX打包來部署桌面應用,那么,自Windows10版本2004起,你可通過創建一個僅包含程序包清單的稀疏MSIX包來授予包標識。有關詳細信息,請參閱向未打包的桌面應用授予標識。
如果你的桌面應用具有程序包標識符,可以在其中使用以下功能:
集成包擴展
如果應用程序需要與系統集成(例如,建立防火牆規則),請在應用程序的包清單中描述集成任務,系統將完成其余操作。對於其中的大多數任務,根本不必編寫任何代碼。在清單中添加少量的XML后,可以執行一些操作,例如,在用戶登錄時啟動進程、將應用程序集成到文件資源管理器中,以及為應用程序添加顯示在其他應用中的打印目標列表。
有關詳細信息,請參閱將桌面應用與包擴展集成。
獲取打包應用的激活信息
從Windows 10 v1809版開始,經過打包的桌面應用可以在啟動過程中檢索某些類型的激活信息。例如,可以獲取通過打開文件、單擊交互式toast或使用協議激活應用的相關信息。
有關詳細信息,請參閱獲取打包應用的激活信息。
使用UWP組件進行擴展
某些Windows 10體驗(例如,支持觸摸的UI頁面)必須在新式應用容器內部運行。一般情況下,首先應確定是否可以通過Windows運行時API增強現有桌面應用程序來添加體驗。如果必須使用UWP組件來實現體驗,可將UWP項目添加到解決方案,並使用應用服務在桌面應用程序與UWP組件之間通信。
有關詳細信息,請參閱使用UWP組件擴展桌面應用。
分發
如果在MSIX包中打包應用,可以通過將應用發布到Microsoft Store或將其旁加載到其他系統來分發應用。
請參閱分發打包的桌面應用。
資料和示例
- https://aka.ms/sparsepkgsample
- SparsePackages
- Identity, Registration and Activation of Non-packaged Win32 Apps
未打包的Win32應用程序的身份、注冊和激活
許多新的和受歡迎的Windows API和功能,如后台任務(BackgroundTasks)、通知(Notifications)、動態磁貼(LiveTiles)、共享目標(Share) 等,要么無法使用,要么不容易從非打包的Win32應用程序中調用。這是由於UWP APIs的編程模型與系統集成,並對以下概念有依賴性。
- 身份(Identity) —— 需要包或應用程序的身份來識別調用者,需要一個標識符來確定數據和資源的范圍。
- 注冊(Registration) —— 在應用部署期間需要配置機器狀態,這是API的要求,並由包或應用身份索引。
對於打包的應用程序,在Appxmanifest.xml中聲明身份,注冊由MSIX部署管道根據AppxManifest.xml中的信息處理。這使得UWP API的調用模式得到簡化,應用程序代碼只需使用一個API。與典型的Win32 API相比,它需要一個注冊-使用-取消注冊的模式來管理一個回調。
我們聽到了你的反饋,作為回應,我們正在填補Win32應用程序和新的Windows API和功能之間的鴻溝,以便你可以利用這些新的API和功能,增強你的應用程序。從Windows Build 10.0.19000.0開始,我們將引入以下新的AppModel概念,為您的Win32應用程序提供與操作系統更深入的整合。
- 稀疏包(Sparse Package)注冊
今天可以在Windows上安裝簽名的MSIX包,但包的Appxmanifest.xml
中引用的所有內容必須存在於包內。一個稀疏包包含一個AppxManifest.xml
,但與普通/完整包不同,清單可以在預定的 "外部位置(External Location)"引用其包以外的文件。這允許尚未能夠采用完整MSIX打包的應用程序獲得身份,按照UWP API的要求配置狀態(注冊),然后利用這些API的優勢。
- 程序包外部位置(External Location)
為了支持稀疏包,包定義現在有一個新的<allowExternalContent>
元素。這就是允許你的包AppxManifest.xml
引用其包之外的內容,在磁盤上的一個特定位置。例如,如果你現有的Win32應用程序在C:\Program Files\MyWin32App\
中安裝內容,你可以創建一個稀疏包,聲明<allowExternalContent>
元素,在應用程序安裝或首次運行時,你可以注冊稀疏包並聲明C:\Program Files\MyWin32App\
作為你的應用程序將使用的外部位置(External Location)。這樣你就可以繼續在你現在的位置上部署你所有的其他應用程序工件,同時利用稀疏包的優勢。
- Win32類型的RuntimeBehavior
為了幫助你現有的Win32應用程序在使用稀疏包時的兼容性,應用程序可以注冊以使其應用程序盡可能地像非打包的Win32應用程序一樣運行。這與完全打包的Win32應用程序不同,因為它不受文件系統+注冊表虛擬化、系統的壽命管理和其他完全打包的應用程序的運行時屬性的影響。這種應用程序和完全打包的應用程序之間的主要運行時相似之處是在運行進程中存在"應用程序/包(app/package)"的身份。
- 通過CreateProcess進行激活
今天UWP應用程序的激活路徑確保應用程序在其進程標記中具有"包標識(PackageIdentity)"。這被UWP的API用來識別調用者,並在以后參考——要么執行回調,要么查詢部署期間配置的狀態。由於這個要求,在UWP exe上調用CreateProcess()
將會失敗,因為CreateProcess()
管道沒有被告知身份。為了支持具有外部位置的稀疏包,我們利用經典的Win32 application.manifest
,在CreateProcess()
場景中提供身份信息。
這些功能的核心是為未打包的Win32進程提供一個基礎,以使用我們最新的API和功能。
請注意,這些仍然是新的、有點高級的開發功能,還沒有完全與Visual Studio集成,即在端到端的編寫經驗中仍然存在一些差距,例如必須在Visual Studio之外創建一個稀疏包。
獲取並體驗示例程序PhotoStoreDemo
0. 前言
我們將使用一個使用稀疏包的示例應用程序來了解稀疏包編寫和使用的不同方面。該演示應用程序位於https://aka.ms/sparsepkgsample
我們有一個未打包的WPF應用程序PhotoStoreDemo,用於存儲和顯示照片。在其純粹的未打包狀態下,利用新的Windows APIs和功能可能是一個挑戰。我們的目標是通過創建一個稀疏包並繼續使用我們先前已有的Win32應用程序的工件來改變這種情況。
1. 什么是應用程序模型
應用程序模型(App Model) 代表了平台中的核心應用程序激活和生命周期管理基礎設施。這些組件負責實際激活應用程序,創建流程,將應用程序與平台整合,管理激活-暫停-恢復-終止周期,協商資源分配,等等。應用程序模型還暴露了一些以開發者為中心的API,用於診斷。更多信息。
2. Git拉取源碼
git clone https://github.com/microsoft/AppModelSamples.git
3. 找到PhotoStoreDemo的解決方案文件
\AppModelSamples\Samples\SparsePackages\WPF+SparsePkg.sln
4. 補充安裝.NET Framework 4.6.1
打開WPF+SparsePkg.sln
之后,會提示你有項目是通過較老版本的.NET Framework來設計的,所以這里根據提示安裝。
裝好之后,就能順利打開項目了。
5. 運行並調試PhotoStoreDemo項目
我們在Visual Studio中找到PhotoStoreDemo
項目並且把它設置為啟動項目,啟動本地調試就運行起來了。
稀疏包的剖析
一個稀疏包必須有一個AppxManifest.xml
和一組最小的所需的視覺資產,以便部署。
[code lang=”xml”]
<Package
xmlns:uap10="http://schemas.microsoft.com/appx/manifest/uap/windows10/10"
IgnorableNamespaces="uap10">
<Identity Name="PhotoStoreDemo" Publisher="CN=Contoso" … />
<Properties>
…
<Logo>Assets\storelogo.png</Logo>
<uap10:AllowExternalContent>true</uap10:AllowExternalContent>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Desktop"
MinVersion="10.0.19000.0"
MaxVersionTested="10.0.19000.0" />
</Dependencies>
<Capabilities>
<rescap:Capability Name="runFullTrust" />
<rescap:Capability Name="unvirtualizedResources"/>
</Capabilities>
…
<Applications>
<Application Id="PhotoStoreDemo"
Executable="PhotoStoreDemo.exe"
uap10:TrustLevel="mediumIL"
uap10:RuntimeBehavior="win32App">
…
</Application>
</Applications>
</Package>
[/code]
讓我們使用上面示例代碼中的AppxManifest.xml
來看看稀疏包的結構。
包的外部位置(External Location)
首先,AppxManifest應聲明<AllowExternalContent>
包屬性。這允許清單引用不位於包內的內容。稀疏包中引用的任何不直接位於包內的內容都應在"外部"位置,該位置在注冊稀疏包時已指定。
<Properties>
<DisplayName>PhotoStoreDemo</DisplayName>
<PublisherDisplayName>Sparse Package</PublisherDisplayName>
<Logo>Assets\storelogo.png</Logo>
<uap10:AllowExternalContent>true</uap10:AllowExternalContent>
</Properties>
例如,如果我在安裝期間或第一次運行時聲明我的包的外部位置是C:\Program Files\MyDesktopApp\
,為<Logo>
屬性定義的圖像storelogo.png應該安裝在C:\Program Files\MyDesktopApp\Assets\storelogo.png
,主要應用程序可執行文件PhotoStoreDemo.exe
應該安裝在C:\Program Files\MyDesktopApp\PhotoStoreDemo.exe
。
<Dependencies>
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.18950.0" MaxVersionTested="10.0.19000.0" />
</Dependencies>
此外,MinVersion應該是OS Build 10.0.19000.0(此處存在疑問,是否后續降低了標准?)或更高,Sparse包目前不支持早於這個版本的OS。
值得注意的是,與完全打包的應用程序不同,使用稀疏包+"外部位置(External Location)"的應用程序在部署、運行和卸載時不會被操作系統完全管理。就像現在的Win32應用程序一樣,你的應用程序要負責安裝和卸載它的所有工件,包括稀疏包和"外部位置(External Location)"中的任何內容。這也意味着你的應用程序不能像完全打包的應用程序那樣獲得終身管理和防篡改保護,因為它被安裝在系統上的一個鎖定位置。
Win32運行時行為(Win32 Runtime Behavior)
<Application>
元素中新引入的TrustLevel=mediumIL
和RuntimeBehavior=Win32App
屬性被用來聲明與此稀疏包相關的應用程序將像Win32應用程序一樣運行,沒有注冊表+文件系統虛擬化和其他運行時變化。
<Applications>
<Application Id="PhotoStoreDemo" Executable="PhotoStoreDemo.exe" uap10:TrustLevel="mediumIL" uap10:RuntimeBehavior="win32App">
<uap:VisualElements AppListEntry="none" DisplayName="PhotoStoreDemo" Description="PhotoStoreDemo" BackgroundColor="transparent" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png">
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" Square310x310Logo="Assets\LargeTile.png" Square71x71Logo="Assets\SmallTile.png"></uap:DefaultTile>
<uap:SplashScreen Image="Assets\SplashScreen.png" />
</uap:VisualElements>
稀疏包的編寫(Sparse Package Authoring)
編寫稀疏包所需的步驟是。
- 創建一個
AppxManifest.xml
+ 視覺資產(Visual Assets)並打包 - 簽名稀疏包
- 在你的Win32應用程序中創建一個經典的Win32
application.manifest
- 注冊稀疏包
創建和打包"AppxManifest.xml"和視覺資產(Visual Assets)
創建應用程序清單
創建一個稀疏包的第一步是生成AppxManifest.xml
。AppxManifest需要包含上面列出的屬性,你可以使用這個模板作為一個起點。
我們在項目跟目錄下面創建一個Template
文件夾,我們先按下面的模板內容創建一個名為AppxManifest.xml
的應用程序清單文件。
<?xml version="1.0" encoding="utf-8"?>
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:uap2="http://schemas.microsoft.com/appx/manifest/uap/windows10/2"
xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10"
xmlns:uap10="http://schemas.microsoft.com/appx/manifest/uap/windows10/10"
IgnorableNamespaces="uap uap2 uap3 rescap desktop uap10">
<Identity Name="PhotoStoreDemo" ProcessorArchitecture="x86" Publisher="CN=MyPubisher" Version="1.0.0.0" />
<Properties>
<DisplayName>Sparse Package Template</DisplayName>
<PublisherDisplayName>My Publisher</PublisherDisplayName>
<Logo>Assets\StoreLogo.png</Logo>
<uap10:AllowExternalContent>true</uap10:AllowExternalContent>
</Properties>
<Resources>
<Resource Language="en-us" />
</Resources>
<Dependencies>
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.19000.0" MaxVersionTested="10.0.19000.0" />
</Dependencies>
<Capabilities>
<rescap:Capability Name="runFullTrust" />
<rescap:Capability Name="unvirtualizedResources"/>
</Capabilities>
<Applications>
<Application Id="MyApp" Executable="MyApp.exe" uap10:TrustLevel="mediumIL" uap10:RuntimeBehavior="win32App">
<uap:VisualElements DisplayName="MyApp" Description="AppDescription" BackgroundColor="transparent" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png">
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" Square310x310Logo="Assets\LargeTile.png" Square71x71Logo="Assets\SmallTile.png"></uap:DefaultTile>
<uap:SplashScreen Image="Assets\SplashScreen.png" />
</uap:VisualElements>
</Application>
</Applications>
</Package>
這里面我們可以完善兩個內容,第一個是根據自己的實際情況修改"身份(Identity)"節點的信息,比如應用名稱Name
,處理器架構ProcessorArchitecture
,發布者信息Publisher
,以及程序包版本號Version
。
根據需要,這里作為示范,稍作修改,改成:
<Identity Name="DemoForSparsePackage" ProcessorArchitecture="x86" Publisher="CN=Contoso Software, O=Contoso Corporation, C=US" Version="1.0.0.0" />
緊接着,我們看到"屬性(Properties)"節點的信息,這里面有一個應用顯示名稱DisplayName
、發布者顯示名稱PublisherDisplayName
,這里也需要進行一些定制修改:
<Properties>
<DisplayName>SparsePackageDemo</DisplayName>
<PublisherDisplayName>Contoso Software</PublisherDisplayName>
<Logo>Assets\StoreLogo.png</Logo>
<uap10:AllowExternalContent>true</uap10:AllowExternalContent>
</Properties>
另外一個,我們看到"應用(Application)"節點的信息,這里面有個一個應用標識Id
和程序文件名Executable
,以及程序顯示名稱DisplayName
這里,我們根據需要做一些修改,改成:
<Applications>
<Application Id="Contoso.DemoForSparsePackage" Executable="DemoForSparsePackage.exe" uap10:TrustLevel="mediumIL" uap10:RuntimeBehavior="win32App">
<uap:VisualElements DisplayName="DemoForSparsePackage" Description="AppDescription" BackgroundColor="transparent" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png">
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" Square310x310Logo="Assets\LargeTile.png" Square71x71Logo="Assets\SmallTile.png"></uap:DefaultTile>
<uap:SplashScreen Image="Assets\SplashScreen.png" />
</uap:VisualElements>
</Application>
</Applications>
同時,這里其實還需要一個真正的DemoForSparsePackage.exe
執行文件才行,我們弄一個過來,放在這個目錄下。
創建應用視覺資產
除了AppxManifest之外,你還需要包括清單文件中引用的"視覺資產(Visual Assets)"。您可以使用 Visual Studio 應用程序打包項目(Application Packaging Project)的package.manifest
編輯器中的"視覺資產(Visual Assets)"節點來生成視覺資產。
弄好之后,我們在前面的Template
文件夾建立一個Assets
文件夾,用來存放這些素材。
通過命令打包
一旦你有了"應用清單文件(AppxManifest.xml)"和"視覺資產(Visual Assets)",你就可以使用"App Packager(MakeAppx.exe)"來創建一個稀疏包。因為稀疏包並不包含AppxManifest.xml
中引用的所有文件,你需要指定/nv
命令。
下面是一個從VS開發者命令提示符創建只包含AppxManifest.xml的稀疏包的命令示例。
MakeAppx.exe pack /d $AppxManifestFileDir /p $OutputMsixFilePath /nv
你可以在這里找到更多關於"App Packager(MakeAppx.exe)"的信息。
其中在Windows 11中makeappx.exe
所在位置:
C:\Program Files (x86)\Windows Kits\10\bin\10.0.22000.0\x64\makeappx.exe
那么我們先切換到它目錄。
cd 'C:\Program Files (x86)\Windows Kits\10\bin\10.0.22000.0\x64\'
然后執行命令進行打包:
.\makeappx.exe pack /d 'C:\TempSpace\HelloSparsePackage\Template\' /p 'C:\TempSpace\HelloSparsePackage\Msix\TestPackage.msix' /nv
好了,這時候MSIX包就生成了。
簽署一個稀疏包
為了在一台機器上成功安裝,你的Sparse包必須用該機器上信任的證書簽名。這就是今天普通MSIX包的情況。你可以為開發目的創建一個新的自簽名證書,並使用Windows SDK和MSIX Toolkit中的SignTool簽署你的稀疏包。你還可以利用新公布的"設備保護簽名(Device Guard Signing)"功能。
下面是一個如何使用"Sign工具(Sign Tool)"從VS開發者命令提示符簽署稀疏包的例子。
SignTool.exe sign /fd SHA256 /a /f <path to cert>\mycert.pfx /p <cert password> <Path to Package>\mypackage.msix
為程序包簽名創建證書
https://docs.microsoft.com/zh-cn/windows/msix/package/create-certificate-package-signing
在部署打包的應用之前,Windows對它們進行數字簽名。如果不使用Microsoft Visual Studio創建應用包並簽名,則需要創建和管理自己的代碼簽名證書。可以使用WDK驅動程序工具包中的Pvk2Pfx.exe和Windows創建(證書)。然后,可以使用證書對應用包進行簽名,以便可以部署在本地進行測試。
創建和使用自簽名證書時,只有安裝和信任證書的用戶才能運行應用程序。這很容易用於測試,但可能會阻止其他用戶安裝應用程序。准備好發布應用程序時,建議使用受信任源頒發的證書。這種集中式信任系統有助於確保應用程序生態系統具有驗證級別,以保護用戶免受惡意參與者的攻擊。
- 確定你的打包應用的主體
若要使用證書給你的應用包簽名,證書中的"主體"必須匹配應用清單中的"發布者"部分
與"應用清單文件(AppxManifest.xml)"的Identity
元素的Publisher
屬性所填的值要一一對應,等下使用的值必須是Publisher
屬性的完整值。
<Identity Name="Contoso.AssetTracker"
Version="1.0.0.0"
Publisher="CN=Contoso Software, O=Contoso Corporation, C=US"/>
那么這時候發布者身份就是:CN=Contoso Software, O=Contoso Corporation, C=US
這一整串。
- 使用自簽名證書命令創建證書
https://docs.microsoft.com/zh-CN/powershell/module/pki/new-selfsignedcertificate
使用"自簽名證書(New-SelfSignedCertificate)"命令創建證書,它包含一些自定義參數,我們這里側重於創建一個簡單的。
New-SelfSignedCertificate -Type Custom -Subject "CN=Contoso Software, O=Contoso Corporation, C=US" -KeyUsage DigitalSignature -FriendlyName "Your friendly name goes here" -CertStoreLocation "Cert:\CurrentUser\My" -TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.3", "2.5.29.19={text}")
其中FriendlyName
指代我們可以給生成的證書取一個更友好的名字,方便我們記憶,這個就隨意了。
其中KeyUsage
指代證書可用於什么,對於自簽名證書,此參數應設置為DigitalSignature
,這個參數可選的值包括:
- CertSign
- CRLSign
- DataEncipherment
- DecipherOnly
- DigitalSignature
- EncipherOnly
- KeyAgreement
- KeyEncipherment
- None (default)
- NonRepudiation
其中TextExtension
指代可擴展的設置,其中:
- EKU (擴展) 表示可能使用已認證的公鑰的其他目的,對於自簽名證書來說,這個擴展需要包括字符串:
2.5.29.37={text}1.3.6.1.5.5.7.3.3
,以便指示證書用於代碼簽名; - 基本約束 指示證書是否是CA證書,對於自簽名證書來說,,這個擴展需要包括字符串:
2.5.29.19={text}
,以便指示證書是最終實體(而不是CA)
其中CertStoreLocation
指代證書生成后的存儲位置,但是這個位置並非文件位置,而是本地證書存儲庫中的位置
- 如果指定的路徑是
Cert:\CurrentUser
或者Cert:\CurrentUser\My
,那么它的默認存儲位置就是Cert:\CurrentUser\My
。 - 如果指定的路徑是
Cert:\LocalMachine
或者Cert:\LocalMachine\My
,那么它的默認存儲位置就是Cert:\LocalMachine\My
。 - 你必須指定
Cert:\CurrentUser\My
或者Cert:\LocalMachine\My
其中一個,暫時不支持其他位置設定。
如果要查看本地存儲的證書,可以通過如下命令:
Set-Location Cert:\CurrentUser\My
Get-ChildItem | Format-Table Subject, FriendlyName, Thumbprint
說完這么多,現在搞懂概念之后,我們可以打個比如了:
New-SelfSignedCertificate -Type Custom -Subject "CN=Contoso Software, O=Contoso Corporation, C=US" -KeyUsage DigitalSignature -FriendlyName "HelloSparsePackage-SelfSignedCertificate-001" -CertStoreLocation "Cert:\CurrentUser\My" -TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.3", "2.5.29.19={text}")
太棒了,一氣呵成!
接下來,我們可以執行查詢命令看看。
Set-Location Cert:\CurrentUser\My
Get-ChildItem | Format-Table Subject, FriendlyName, Thumbprint
確實找到了。
如果要刪除本地存儲的證書,可以通過如下命令:
Remove-Item Cert:$TargetCertPath\$Thumbprint
例如:
Remove-Item Cert:\CurrentUser\My\492A496BDA7304061662DE55C533B4B657902A53
- 導出自簽名證書
https://docs.microsoft.com/zh-cn/powershell/module/pki/export-pfxcertificate
可以通過Export-PfxCertificate
命令把本地存儲的證書導出到個人信息交換(PFX)文件中。
第一種是采用攜帶密碼的方式導出,使用-Password
參數。
$password = ConvertTo-SecureString -String <Your Password> -Force -AsPlainText
Export-PfxCertificate -cert "Cert:\CurrentUser\My\<Certificate Thumbprint>" -FilePath <FilePath>.pfx -Password $password
其中-cert
指代待導出的本地存儲證書的路徑,它是由存儲目錄+證書指紋組成的,例如:Cert:\CurrentUser\My\0AC036CD37F5FF52B41F64F7B985E534E4E84EE0
其中-FilePath
指代導出的個人信息交換(PFX)文件的位置,這里需要指定一個絕對路徑,並且是帶格式后綴.pfx
的,例如:C:\HelloSparsePackage-SelfSignedCertificate-001.pfx
其中-Password
指代導出時設定的密碼,但是我們需要將其轉變為安全的字符串,所以通常先在前面把它准備好。例如:$password = ConvertTo-SecureString -String "1234567" -Force -AsPlainText
綜上所述,我們就可以來舉個例子:
$password = ConvertTo-SecureString -String "1234567" -Force -AsPlainText
Export-PfxCertificate -cert "Cert:\CurrentUser\My\0AC036CD37F5FF52B41F64F7B985E534E4E84EE0" -FilePath 'C:\TempSpace\HelloSparsePackage\Certificate\HelloSparsePackage-SelfSignedCertificate-001.pfx' -Password $password
最終得到了名為HelloSparsePackage-SelfSignedCertificate-001.pfx
的個人信息交換(PFX)文件。
第二種是采用白名單訪問方式導出,使用-ProtectTo
參數。
Export-PfxCertificate -cert Cert:\CurrentUser\My\<Certificate Thumbprint> -FilePath <FilePath>.pfx -ProtectTo <Username or group name>
其中-ProtectTo
指代允許指定的用戶名或用戶組在沒有密碼的情況下訪問這個密鑰,格式采用域+用戶名,例如:contoso\billb99
,如果多組可以采用:-ProtectTo "contoso\billb99", "contoso\johnj99"
注意,這種方式要求具備Windows Server® 2012及其以上版本的域控制功能,所以其實對一般用戶來說,無法采用這種方式。
使用SignTool對應用包進行簽名
https://docs.microsoft.com/zh-cn/windows/msix/package/sign-app-package-using-signtool
SignTool是命令行工具,用於對應用包或帶有證書的捆綁包進行數字簽名。證書可以由用戶創建(用於測試目的)或由公司頒發(用於分發)。登錄應用包可驗證用戶登錄后應用數據未經更改,並且可確認登錄用戶或公司的身份。SignTool可對已加密或未加密的應用包和捆綁包進行簽名。
- 確認本地安裝的SignTool的路徑
根據不同的系統架構版本,它的位置會存在差異,對X86和X64系統而言,他們的路徑位置應該位於:
- x86:
C:\Program Files (x86)\Windows Kits\10\bin\<sdk version\x86\SignTool.exe
- x64:
C:\Program Files (x86)\Windows Kits\10\bin\<sdk version\x64\SignTool.exe
對我當前的Windows 11來說,根據這個指引找的路徑是:
C:\Program Files (x86)\Windows Kits\10\bin\10.0.22000.0\x64\signtool.exe
- 確定簽名用的哈希算法
在使用SignTool對你的應用包或捆綁包進行簽名時,SignTool中所用的哈希算法必須與你用於打包應用的算法相同。
對使用了MakeAppx.exe的應用包簽名時,它的默認簽名算法是SHA256
。
要找出打包應用時用到了哪種哈希算法,則需要提取應用包的內容並檢查AppxBlockMap.xml
文件的BlockMap
元素。
查看這個信息有兩種辦法,一種是通過
MakeAppx
命令直接解壓MSIX包,另外一種方法,直接用壓縮軟件把它解開。
MakeAppx unpack /p <input package name> /d <output directory>
例如:
cd 'C:\Program Files (x86)\Windows Kits\10\bin\10.0.22000.0\x64\'
.\makeappx.exe unpack /p 'C:\TempSpace\HelloSparsePackage\Msix\TestPackage.msix' /d 'C:\TempSpace\HelloSparsePackage\Template-Unpack\'
回歸正題,我們需要看看AppxBlockMap.xml
文件的BlockMap
元素寫了什么。
<BlockMap xmlns="http://schemas.microsoft.com/appx/2010/blockmap" xmlns:b4="http://schemas.microsoft.com/appx/2021/blockmap" IgnorableNamespaces="b4" HashMethod="http://www.w3.org/2001/04/xmlenc#sha256">...
我們看到這里有個"哈希方法(HashMethod)",它的值是http://www.w3.org/2001/04/xmlenc#sha256
,那么它和我們要確認的哈希算法之間的關系是:
HashMethod 值 | 哈希算法 |
---|---|
http://www.w3.org/2001/04/xmlenc#sha256 | SHA256 |
http://www.w3.org/2001/04/xmldsig-more#sha384 | SHA384 |
http://www.w3.org/2001/04/xmlenc#sha512 | SHA512 |
所以這里我們能確認的是,當前MSIX包采用的打包哈希算法就是SHA256
。
通過命令對MSIX包簽名
https://docs.microsoft.com/zh-CN/windows/win32/seccrypto/signtool
如果我們要基於個人信息交換(PFX)文件進行簽名,那么可以采用:
SignTool sign /fd <Hash Algorithm> /a /f <Path to Certificate>.pfx /p <Your Password> <File path>.msix
其中/fd
指代簽名是采用何種哈希算法,其完整示例比如:/fd SHA256
其中/a
指代讓工具自動選擇最合適的證書進行簽名。
其中/f
指代個人信息交換(PFX)文件的路徑,而/p
指代它的訪問密碼,其完整示例比如:/f 'C:\H.pfx' /p '123457'
其中<File path>.msix
指代了待被簽名的MSIX包的完整路徑,例如:C:\demo.msix
甚至我們還可以加蓋時間戳,使用參數:/t http://timestamp.digicert.com
,但是這個會增加簽名的時間哈。
綜上所述,我們就可以來舉個例子:
cd 'C:\Program Files (x86)\Windows Kits\10\bin\10.0.22000.0\x64\'
.\signtool.exe sign /fd SHA256 /a /f 'C:\TempSpace\HelloSparsePackage\Certificate\HelloSparsePackage-SelfSignedCertificate-001.pfx' /t 'http://timestamp.digicert.com' /p '1234567' 'C:\TempSpace\HelloSparsePackage\Msix\TestPackage.msix'
.\signtool.exe sign /fd SHA256 /a /f 'C:\TempSpace\HelloSparsePackage\Certificate\HelloSparsePackage-SelfSignedCertificate-001.pfx' /p '1234567' 'C:\TempSpace\HelloSparsePackage\Msix\TestPackage.msix'
Done Adding Additional Store
Successfully signed: C:\TempSpace\HelloSparsePackage\Msix\TestPackage.msix
我們需要注意這前后的變化,在之前,這個MSIX是沒有簽名的:
完成這一步之后,它有數字簽名了:
創建一個經典的Win32程序配置
https://docs.microsoft.com/zh-cn/windows/win32/sbscs/application-manifests
為了支持不經過UWP激活管道的CreateProcess()
方案,您的應用程序必須使用經典的Win32風格的application.manifest
,在新的<msix>
元素下聲明您的應用程序的身份屬性。在清單中定義的值在其可執行程序啟動時用於確定您的應用程序的身份,並且必須與您的稀疏包的AppxManifest.xml
中聲明的值一致。
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="0.0.0.1" name="PhotoStoreDemo.app"/>
<msix xmlns="urn:schemas-microsoft-com:msix.v1"
publisher="CN=Contoso"
packageName="PhotoStoreDemo"
applicationId="PhotoStoreDemo"
/>
</assembly>
packageName
(上面)對應於Name
,publisher
對應於Sparse包的<Identity>
元素中的Publisher
。
<Identity Name="PhotoStoreDemo" Publisher="CN=Contoso" … />
applicationId
對應於在Sparse包中聲明的這個應用程序的<Application>
元素的Id
屬性。
Applications>
<Application Id="PhotoStoreDemo"…>
…
要在Visual studio中向現有項目添加經典的Win32清單,可在應用程序節點中右鍵單擊|添加|新項目|Visual C#|應用程序清單文件。清單文件的命名慣例是,它必須與您的應用程序的.exe名稱相同,並具有.manifest擴展名,在本例中我將其命名為 "PhotoStoreDemo.exe.manifest"。
這里需要注意的是,這個應用程序清單的.Msix
元素,只有在Windows 10 v2004及其以上版本才能識別並支持。
其中msix
元素必須在urn:schemas-microsoft-com:msix.v1
的命名空間中。
屬性 | 說明 |
---|---|
publisher |
介紹發布服務器信息。此值必須與稀疏包清單中的Identity 元素中的Publisher 特性匹配。 |
packageName |
描述包的內容。此值必須與稀疏包清單中的Identity 元素的Name 特性匹配。 |
applicationId |
應用程序的唯一標識符。此值必須與稀疏包清單中的應用程序Application 元素的Id 特性匹配。 |
添加應用程序清單
在項目上右鍵"添加"-"新建項"。
進入"添加新項"對話框,找到"應用程序清單(僅限Windows)"。
這里命名必須和應用程序的程序集帶后綴名稱一致,比如:DemoForSparseWPF.exe.manifest
。
生成后項目屬性里面的清單會自動關聯到它。
不過從默認得到的模板來看,里面還是蠻復雜的,為很多場景做了舉例。
定制稀疏包的清單內容
有了應用程序清單文件,我們就可以定制添加需要的清單內容了,先打個草稿,這里我們需要和稀疏包的清單文件保持一致,所以確定下來的內容是:
<msix xmlns="urn:schemas-microsoft-com:msix.v1"
publisher="CN=Contoso Software, O=Contoso Corporation, C=US"
packageName="DemoForSparsePackage"
applicationId="Contoso.DemoForSparsePackage"
/>
另外清單文件里面,還有個assemblyIdentity
元素的名稱name
,也一起改吧,這個根據對應的程序名稱來就行。
我們把這個msix
補充在清單文件的assemblyIdentity
節點后面。
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="DemoForSparseWPF.App"/>
<msix xmlns="urn:schemas-microsoft-com:msix.v1"
publisher="CN=Contoso Software, O=Contoso Corporation, C=US"
packageName="DemoForSparsePackage"
applicationId="Contoso.DemoForSparsePackage"
/>
...
利用你的應用程序的稀疏包的優勢
如前所述,為你的應用程序創建一個稀疏包使你的Win32應用程序更容易與操作系統深度集成,並利用諸如BackgroundTasks、共享、通知和瓷磚等功能。讓我們來看看我們的樣本應用程序是如何運行和使用稀疏包來注冊為一個共享目標並利用UWP激活的。
我們的樣本中的工作流程看起來是這樣的:
- 在稀疏包
AppxManifest.xml
中聲明我們的應用程序是一個共享目標。 - 向操作系統注冊我們的應用程序的稀疏包。
- 重新啟動應用程序並處理激活類型。
使用實例 - 在稀疏包AppxManifest.xml中聲明你的應用程序是一個共享目標。
我們的示例應用程序通過在稀疏包AppxManifest.xml
中聲明windows.ShareTarget
應用程序擴展來注冊為一個共享目標。
<Extensions>
<uap:Extension Category="windows.shareTarget">
<uap:ShareTarget Description="Send to PhotoStoreDemo">
<uap:SupportedFileTypes>
<uap:FileType>.jpg</uap:FileType>
<uap:FileType>.png</uap:FileType>
<uap:FileType>.gif</uap:FileType>
</uap:SupportedFileTypes>
<uap:DataFormat>StorageItems</uap:DataFormat>
<uap:DataFormat>Bitmap</uap:DataFormat>
</uap:ShareTarget>
</uap:Extension>
</Extensions>
所以這個AppxManifest.xml
文件我們修改成:
...
</Applications>
<Extensions>
<uap:Extension Category="windows.shareTarget">
<uap:ShareTarget Description="發送到SparsePackageDemo">
<uap:SupportedFileTypes>
<uap:FileType>.jpg</uap:FileType>
<uap:FileType>.png</uap:FileType>
<uap:FileType>.gif</uap:FileType>
</uap:SupportedFileTypes>
<uap:DataFormat>StorageItems</uap:DataFormat>
<uap:DataFormat>Bitmap</uap:DataFormat>
</uap:ShareTarget>
</uap:Extension>
</Extensions>
</Package>
注冊一個稀疏包
為了利用稀疏包,你的應用程序需要在系統中注冊簽名的包。你可以在第一次運行時注冊該包,或者你也可以在安裝其他Win32工件時注冊該包,如果你使用MSI這樣的安裝程序。要使用MSI安裝軟件包,你需要使用自定義動作。在我們的示例應用程序中,我們在第一次運行時注冊稀疏包。當我們的應用程序被啟動時,我們檢查它是否以身份信息運行(身份信息或沒有身份信息是稀疏包是否被注冊/安裝的信號)如果應用程序沒有以身份信息運行,我們就注冊稀疏包並重新啟動應用程序。這預計只在首次運行時發生一次。要看我們如何確定應用程序是否以身份運行,如果你想了解更多背景,請看ExecutionMode
類和這篇帖子。
這就是我們應用程序中的代碼的樣子:
//if app isn’t running with identity, register its sparse package
if (!ExecutionMode.IsRunningWithIdentity())
{
string externalLocation = @"C:\<App_Install_location_root>\";
string sparsePkgPath = @"C:\<App_Install_location_root>\PhotoStoreDemo.msix";
//Attempt registration
if (registerSparsePackage(externalLocation, sparsePkgPath))
{
//Registration succeded, restart the app to run with identity
System.Diagnostics.Process.Start(Application.ResourceAssembly.Location, arguments: cmdArgs?.ToString());
}
else //Registration failed, run without identity
{
Debug.WriteLine("Package Registation failed, running WITHOUT Identity");
SingleInstanceManager wrapper = new SingleInstanceManager();
wrapper.Run(cmdArgs);
}
}
而這是上面調用的處理包注冊的registerSparsePackage
方法:
Using Windows.Management.Deployment
…
private static bool registerSparsePackage(string externalLocation, string sparsePkgPath)
{
bool registration = false;
try
{
Uri externalUri = new Uri(externalLocation);
Uri packageUri = new Uri(sparsePkgPath);
PackageManager packageManager = new PackageManager();
//Set the externalLocation where your Win32 artifacts will be installed
//Anything not in the package but referenced by your AppxManifest.xml needs to to be under this location
var options = new AddPackageOptions();
options.ExternalLocationUri = externalUri;
Windows.Foundation.IAsyncOperationWithProgress<DeploymentResult, DeploymentProgress> deploymentOperation = packageManager.AddPackageByUriAsync(packageUri, options)
為了注冊稀疏包,你需要使用PackageManager AddPackageByUriAsync(packageUri, addPackageOptions)
的API。該API接收你簽名的稀疏包的位置作為URI和一個AddPackageOptions
對象。你需要創建一個AddpackageOptions
對象,並將ExternalLocationUri
屬性設置為URI,即在稀疏包中被引用的Win32工件(如應用程序可執行文件)將被安裝的位置。
處理應用程序的激活
生成並注冊稀疏包
為稀疏包創建程序包清單
生成稀疏包並為稀疏包簽名
將程序包標識符元數據添加到桌面應用程序清單
在運行時注冊稀疏包
使用打包擴展將桌面應用與Windows集成
https://docs.microsoft.com/zh-cn/windows/apps/desktop/modernize/desktop-to-uwp-extensions
如果桌面應用具有程序包標識符,你可通過程序包清單中的預定義擴展,使用擴展將應用與Windows 10及更高版本進行集成。
例如,使用擴展創建一個防火牆例外,使應用成為某一文件類型的默認應用程序,或將“開始”磁貼指向你的應用。若要使用擴展,只需將某些XML添加到應用的程序包清單文件。不需要任何代碼。
獲取打包應用的激活信息
從Windows 10 v1809版開始,經過打包的桌面應用可以調用AppInstance.GetActivatedEventArgs
方法,在啟動過程中檢索某些類型的應用激活信息。例如,可以調用此方法獲取通過打開文件、單擊交互式toast或使用協議激活應用的相關信息。從Windows 10 v2004版開始,使用稀疏包的應用中也支持此功能。
代碼示例
下面的代碼示例演示如何通過Windows窗體應用中的Main函數調用AppInstance.GetActivatedEventArgs
方法。對於應用支持的每個激活類型,將args返回值強制轉換為相應的事件args類型。此代碼示例假定Handlexxx方法是在其他地方定義的專用激活處理程序代碼。
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var args = AppInstance.GetActivatedEventArgs();
switch (args.Kind)
{
case ActivationKind.Launch:
HandleLaunch(args as LaunchActivatedEventArgs);
break;
case ActivationKind.ToastNotification:
HandleToastNotification(args as ToastNotificationActivatedEventArgs);
break;
case ActivationKind.VoiceCommand:
HandleVoiceCommand(args as VoiceCommandActivatedEventArgs);
break;
case ActivationKind.File:
HandleFile(args as FileActivatedEventArgs);
break;
case ActivationKind.Protocol:
HandleProtocol(args as ProtocolActivatedEventArgs);
break;
case ActivationKind.StartupTask:
HandleStartupTask(args as StartupTaskActivatedEventArgs);
break;
default:
HandleLaunch(null);
break;
}
支持的激活類型
可以使用AppInstance.GetActivatedEventArgs
方法從下表中列出的一組受支持的事件args對象中檢索激活信息。其中一些激活類型要求使用程序包清單中的一個程序包擴展。
僅Windows 10 v2004版及更高版本支持ShareTargetActivatedEventArgs
激活信息。Windows 10 v1809版及更高版本支持所有其他激活信息類型。
事件args類型 | 程序包擴展 | 相關文檔 |
---|---|---|
ShareTargetActivatedEventArgs | uap:ShareTarget | 使桌面應用程序成為共享目標 |
ProtocolActivatedEventArgs | uap:Protocol | 使用協議啟動應用程序 |
ToastNotificationActivatedEventArgs | desktop:ToastNotificationActivation | 來自桌面應用的Toast通知。 |
StartupTaskActivatedEventArgs | desktop:StartupTask | 用戶登錄Windows時啟動可執行文件 |
FileActivatedEventArgs | uap:FileTypeAssociation | 將打包的應用程序與一組文件類型相關聯 |
VoiceCommandActivatedEventArgs | 無 | 處理激活和執行語音命令 |
LaunchActivatedEventArgs | 無 |
使用新式UWP組件擴展桌面應用
https://docs.microsoft.com/zh-cn/windows/apps/desktop/modernize/desktop-to-uwp-extend
某些Windows 10體驗(例如,支持觸摸的UI頁面)必須在新式應用容器內部運行。如果要添加這些體驗,請用UWP項目和Windows運行時組件擴展桌面應用程序。
在許多情況下,你可以直接從桌面應用程序中調用Windows運行時API,因此在查看本指南前,請參閱面向Windows 10的增強。
本文中所述的功能要求桌面應用具有程序包標識符(通過在MSIX包中打包桌面應用或使用稀疏包授予應用標識)
如果你准備好了,那我們就開始吧。
在桌面應用中調用Windows運行時API
https://docs.microsoft.com/zh-cn/windows/apps/desktop/modernize/desktop-to-uwp-enhance
桌面應用項目以使用WindowsOS提供的Windows運行時(WinRT)API,並將新式Windows11和Windows10體驗添加到桌面應用。
桌面應用中不支持某些Windows運行時(WinRT)API。有關詳細信息,請參閱桌面應用中不支持的Windows運行時API。
修改.NET項目以使用Windows運行時API
有幾個用於.NET項目的選項:
- 從.NET5開始,可以在項目文件中添加目標框架名字對象(TFM),用於訪問WinRTAPI。此選項支持面向Windows 10 v1809版或更高版本的項目。
- 對於早期版本的.NET,可以安裝
Microsoft.Windows.SDK.Contracts
的NuGet包,以便將所有必要的引用添加到項目中。此選項支持面向Windows 10 v1803版或更高版本的項目。 - 如果你的項目同時面向.NET5(或更高版本)和早期版本的.NET等多個目標,可將項目文件配置為同時使用這兩個選項。
實踐
創建解決方案HelloSparsePackage
dotnet new sln -o HelloSparsePackage
cd .\HelloSparsePackage\
explorer.exe .
創建Windows應用程序打包項目DemoForSparsePacking
在Visual Studio中,在解決方案HelloSparsePackage
上右鍵選擇"添加"->"新建項目",打開新建項目對話框。
語言項選"所有語言",平台項選"Windows",項目類型項選"桌面",往下拉,找到"Windows應用程序打包項目",點擊"下一步"。
輸入新項目名DemoForSparsePacking
,然后點擊"創建"按鈕即可完成項目創建。
在"新式通用Windows平台項目",這里我們就保持默認,目標版本和最低版本都按推薦值來吧,最后點擊"確定"即可。
接下來,Windows應用程序打包項目DemoForSparsePacking
就創建好了。
創建.Net Framework的Winforms項目DemoForSparseWinforms
在Visual Studio中,在解決方案HelloSparsePackage
上右鍵選擇"添加"->"新建項目",打開新建項目對話框。
語言項選"C#",平台項選"Windows",項目類型項選"桌面",往下拉,找到"Windows窗體應用(.Net Framework)",點擊"下一步"。
輸入新項目名DemoForSparseWinforms
,框架項選擇".Net framework 2.0",然后點擊"創建"按鈕即可完成項目創建。
接下來,Windows窗體應用(.Net Framework)項目DemoForSparseWinforms
就創建好了。
創建.Net Framework的WPF項目DemoForSparseWPF
在Visual Studio中,在解決方案HelloSparsePackage
上右鍵選擇"添加"->"新建項目",打開新建項目對話框。
語言項選"C#",平台項選"Windows",項目類型項選"桌面",往下拉,找到"WPF應用(.Net Framework)",點擊"下一步"。
輸入新項目名DemoForSparseWPF
,框架項選擇".Net framework 4.6.1",然后點擊"創建"按鈕即可完成項目創建。
接下來,WPF應用(.Net Framework)項目DemoForSparseWPF
就創建好了。
案例分析:WinRAR
新聞
2022年1月25日,老牌壓縮軟件WinRAR迎來了6.10正式版更新,更新提供了對Windows 11右鍵菜單的支持。
安裝
目錄
我們看到安裝目錄下面有個RarExtPackage.msix
,接下來打開看看它。
解剖
把RarExtPackage.msix
解開,里面一些文件。
右邊就是一些視覺資產文件,它這個比較簡單了,只包括:
- RarExtLogo.altform-unplated_targetsize-32.png
- RarExtLogo.altform-unplated_targetsize-48.png
- RarExtLogo.altform-unplated_targetsize-64.png
- Square150x150Logo.png
- StoreLogo.png
基本上也夠用了。反映到AppxManifest.xml
中來看呢,對應了
<Properties>
<DisplayName>WinRAR</DisplayName>
<PublisherDisplayName>win.rar GmbH</PublisherDisplayName>
<Logo>StoreLogo.png</Logo>
<desktop6:RegistryWriteVirtualization>disabled</desktop6:RegistryWriteVirtualization>
<desktop6:FileSystemWriteVirtualization>disabled</desktop6:FileSystemWriteVirtualization>
<uap10:AllowExternalContent>true</uap10:AllowExternalContent>
</Properties>
<Applications>
<Application Id="WinRAR.ShellExtension" Executable="RarExtInstaller.exe" uap10:TrustLevel="mediumIL" uap10:RuntimeBehavior="win32App">
<uap:VisualElements AppListEntry="none" DisplayName="WinRAR" Description="RarExtInstaller.exe" BackgroundColor="transparent" Square150x150Logo="Square150x150Logo.png" Square44x44Logo="RarExtLogo.png">
</uap:VisualElements>
</Application>
</Applications>
左邊是MSIX要求的一些描述文件了,其中AppxManifest.xml
整體的看一下:
<?xml version="1.0" encoding="utf-8"?>
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:uap2="http://schemas.microsoft.com/appx/manifest/uap/windows10/2"
xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10"
xmlns:desktop4="http://schemas.microsoft.com/appx/manifest/desktop/windows10/4"
xmlns:desktop5="http://schemas.microsoft.com/appx/manifest/desktop/windows10/5"
xmlns:desktop6="http://schemas.microsoft.com/appx/manifest/desktop/windows10/6"
xmlns:uap10="http://schemas.microsoft.com/appx/manifest/uap/windows10/10"
xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10"
IgnorableNamespaces="uap uap2 uap3 rescap desktop desktop4 desktop5 uap10 com">
<Identity Name="WinRAR.ShellExtension" Publisher="CN=win.rar GmbH, O=win.rar GmbH, L=Berlin, S=Berlin, C=DE" ProcessorArchitecture="x64" Version="1.0.0.1" />
<Properties>
<DisplayName>WinRAR</DisplayName>
<PublisherDisplayName>win.rar GmbH</PublisherDisplayName>
<Logo>StoreLogo.png</Logo>
<desktop6:RegistryWriteVirtualization>disabled</desktop6:RegistryWriteVirtualization>
<desktop6:FileSystemWriteVirtualization>disabled</desktop6:FileSystemWriteVirtualization>
<uap10:AllowExternalContent>true</uap10:AllowExternalContent>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.18362.0" MaxVersionTested="10.0.19041.0" />
</Dependencies>
<Resources>
<Resource Language="EN-US" />
</Resources>
<Capabilities>
<rescap:Capability Name="runFullTrust" />
<rescap:Capability Name="unvirtualizedResources"/>
</Capabilities>
<Applications>
<Application Id="WinRAR.ShellExtension" Executable="RarExtInstaller.exe" uap10:TrustLevel="mediumIL" uap10:RuntimeBehavior="win32App">
<uap:VisualElements AppListEntry="none" DisplayName="WinRAR" Description="RarExtInstaller.exe" BackgroundColor="transparent" Square150x150Logo="Square150x150Logo.png" Square44x44Logo="RarExtLogo.png">
</uap:VisualElements>
<Extensions>
<com:Extension Category="windows.comServer">
<com:ComServer>
<com:SurrogateServer DisplayName="WinRAR">
<com:Class Id="b41db860-64e4-11d2-9906-e49fadc173ca" Path="RarExt.dll" ThreadingModel="STA" />
</com:SurrogateServer>
</com:ComServer>
</com:Extension>
<desktop4:Extension Category="windows.fileExplorerContextMenus">
<desktop4:FileExplorerContextMenus>
<desktop5:ItemType Type="*">
<desktop5:Verb Id="WinRARTopEntry" Clsid="b41db860-64e4-11d2-9906-e49fadc173ca" />
</desktop5:ItemType>
<desktop5:ItemType Type="Directory">
<desktop5:Verb Id="WinRARTopEntry" Clsid="b41db860-64e4-11d2-9906-e49fadc173ca" />
</desktop5:ItemType>
</desktop4:FileExplorerContextMenus>
</desktop4:Extension>
</Extensions>
</Application>
</Applications>
</Package>
至於[Content_Types].xml
、AppxBlockMap.xml
我暫時覺得就沒必要看了,應該是創建MSIX包自動生成的。
案例分析:NanaZip
新聞
2021年10月31日,NanaZip基於7-Zip,因此功能和性能都和7-Zip差不多,甚至連界面也和7-Zip一個簡陋風格,除了提供最基礎的交互,沒有什么精美的設計。
功能
- 繼承了7-Zip 21.07的所有功能。
- 使用MSIX打包,以獲得現代部署體驗。
- 支持Windows 10/11文件管理器中的上下文菜單。
- 啟用NSIS檔案的NSIS腳本反編譯支持。(合並自7-Zip NSIS分支。)
- 提供7-Zip執行別名,幫助用戶遷移到NanaZip。
- 支持 Brotli,Fast-LZMA2,Lizard, LZ4, LZ5和Zstandard編解碼器。(合並自7-Zip ZS分支。)
安裝
a. 從微軟官方商店獲取
NanaZip是一個開放源碼的文件存檔器,旨在為現代的Windows體驗,從著名的開放源碼文件存檔器7-Zip的源代碼分叉出來。
b. 從Github發布頁獲取
目錄
這是一個MSIX打包的應用。
解剖
其中AppxManifest.xml
整體的看一下:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Package IgnorableNamespaces="uap rescap desktop uap3 com desktop4 desktop5 uap8 virtualization build" xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities" xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10" xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3" xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10" xmlns:desktop4="http://schemas.microsoft.com/appx/manifest/desktop/windows10/4" xmlns:desktop5="http://schemas.microsoft.com/appx/manifest/desktop/windows10/5" xmlns:uap8="http://schemas.microsoft.com/appx/manifest/uap/windows10/8" xmlns:virtualization="http://schemas.microsoft.com/appx/manifest/virtualization/windows10" xmlns:build="http://schemas.microsoft.com/developer/appx/2015/build" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest">
<Identity Name="40174MouriNaruto.NanaZipPreview" Publisher="CN=E310A153-74A9-4D81-800B-857A8D58408A" Version="1.1.153.0" ProcessorArchitecture="x64" />
<Properties>
<DisplayName>NanaZip Preview</DisplayName>
<PublisherDisplayName>Kenji Mouri</PublisherDisplayName>
<Logo>Assets\StoreLogo.png</Logo>
<virtualization:FileSystemWriteVirtualization>
<virtualization:ExcludedDirectories>
<virtualization:ExcludedDirectory>$(KnownFolder:LocalAppData)</virtualization:ExcludedDirectory>
<virtualization:ExcludedDirectory>$(KnownFolder:LocalAppDataLow)</virtualization:ExcludedDirectory>
<virtualization:ExcludedDirectory>$(KnownFolder:RoamingAppData)</virtualization:ExcludedDirectory>
</virtualization:ExcludedDirectories>
</virtualization:FileSystemWriteVirtualization>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.17763.0" MaxVersionTested="10.0.22000.0" />
</Dependencies>
<Resources>
<Resource Language="EN-US" />
<Resource uap:Scale="100" />
<Resource uap:Scale="200" />
<Resource uap:Scale="400" />
</Resources>
<Applications>
<Application Id="NanaZipC" Executable="NanaZip.exe" EntryPoint="Windows.FullTrustApplication">
<uap:VisualElements AppListEntry="none" DisplayName="NanaZip Preview" Description="NanaZip" BackgroundColor="transparent" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" />
<Extensions>
<uap3:Extension Category="windows.appExecutionAlias" Executable="NanaZipC.exe" EntryPoint="Windows.FullTrustApplication">
<uap3:AppExecutionAlias>
<desktop:ExecutionAlias Alias="NanaZipC.exe" />
<desktop:ExecutionAlias Alias="7z.exe" uap8:AllowOverride="true" />
</uap3:AppExecutionAlias>
</uap3:Extension>
</Extensions>
</Application>
<Application Id="NanaZipG" Executable="NanaZipG.exe" EntryPoint="Windows.FullTrustApplication">
<uap:VisualElements AppListEntry="none" DisplayName="NanaZip Preview" Description="NanaZip" BackgroundColor="transparent" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" />
<Extensions>
<uap3:Extension Category="windows.appExecutionAlias" Executable="NanaZipG.exe" EntryPoint="Windows.FullTrustApplication">
<uap3:AppExecutionAlias>
<desktop:ExecutionAlias Alias="NanaZipG.exe" />
<desktop:ExecutionAlias Alias="7zG.exe" uap8:AllowOverride="true" />
</uap3:AppExecutionAlias>
</uap3:Extension>
</Extensions>
</Application>
<Application Id="NanaZip" Executable="NanaZip.exe" EntryPoint="Windows.FullTrustApplication">
<uap:VisualElements DisplayName="NanaZip Preview" Description="NanaZip" BackgroundColor="transparent" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png">
<uap:DefaultTile ShortName="NanaZip" Wide310x150Logo="Assets\Wide310x150Logo.png" Square310x310Logo="Assets\LargeTile.png" Square71x71Logo="Assets\SmallTile.png">
<uap:ShowNameOnTiles>
<uap:ShowOn Tile="wide310x150Logo" />
<uap:ShowOn Tile="square150x150Logo" />
<uap:ShowOn Tile="square310x310Logo" />
</uap:ShowNameOnTiles>
</uap:DefaultTile>
</uap:VisualElements>
<Extensions>
<uap3:Extension Category="windows.appExecutionAlias" Executable="NanaZip.exe" EntryPoint="Windows.FullTrustApplication">
<uap3:AppExecutionAlias>
<desktop:ExecutionAlias Alias="NanaZip.exe" />
<desktop:ExecutionAlias Alias="7zFM.exe" uap8:AllowOverride="true" />
</uap3:AppExecutionAlias>
</uap3:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_001">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - 001 Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.001</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_7z">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - 7z Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.7z</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_arj">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - arj Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.arj</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_bz2">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - bz2 Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.bz2</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_bzip2">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - bzip2 Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.bzip2</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_cab">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - cab Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.cab</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_cpio">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - cpio Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.cpio</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_deb">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - deb Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.deb</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_dmg">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - dmg Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.dmg</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_esd">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - esd Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.esd</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_fat">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - fat Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.fat</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_gz">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - gz Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.gz</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_gzip">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - gzip Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.gzip</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_hfs">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - hfs Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.hfs</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_iso">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - iso Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.iso</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_lha">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - lha Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.lha</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_liz">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - liz Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.liz</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_lz">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - lz Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.lz</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_lz4">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - lz4 Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.lz4</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_lz5">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - lz5 Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.lz5</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_lzh">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - lzh Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.lzh</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_lzma">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - lzma Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.lzma</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_ntfs">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - ntfs Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.ntfs</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_rar">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - rar Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.rar</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_rpm">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - rpm Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.rpm</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_squashfs">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - squashfs Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.squashfs</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_swm">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - swm Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.swm</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_tar">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - tar Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.tar</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_taz">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - taz Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.taz</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_tbz">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - tbz Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.tbz</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_tbz2">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - tbz2 Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.tbz2</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_tgz">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - tgz Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.tgz</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_tlz">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - tlz Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.tlz</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_tpz">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - tpz Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.tpz</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_txz">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - txz Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.txz</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_vhd">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - vhd Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.vhd</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_vhdx">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - vhdx Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.vhdx</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_wim">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - wim Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.wim</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_xar">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - xar Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.xar</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_xz">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - xz Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.xz</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_z">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - z Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.z</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_zip">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - zip Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.zip</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="archivetype_zst">
<uap:Logo>Assets\ArchiveFile.png</uap:Logo>
<uap:DisplayName>NanaZip - zst Archive</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.zst</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<desktop4:Extension Category="windows.fileExplorerContextMenus">
<desktop4:FileExplorerContextMenus>
<desktop5:ItemType Type="Directory">
<desktop5:Verb Id="NanaZipShellExtension" Clsid="469D94E9-6AF4-4395-B396-99B1308F8CE5" />
</desktop5:ItemType>
<desktop5:ItemType Type="*">
<desktop5:Verb Id="NanaZipShellExtension" Clsid="469D94E9-6AF4-4395-B396-99B1308F8CE5" />
</desktop5:ItemType>
</desktop4:FileExplorerContextMenus>
</desktop4:Extension>
<com:Extension Category="windows.comServer">
<com:ComServer>
<com:SurrogateServer DisplayName="NanaZip Shell Extension">
<com:Class Id="469D94E9-6AF4-4395-B396-99B1308F8CE5" Path="NanaZipShellExtension.dll" ThreadingModel="STA" />
</com:SurrogateServer>
</com:ComServer>
</com:Extension>
</Extensions>
</Application>
</Applications>
<Capabilities>
<rescap:Capability Name="runFullTrust" />
</Capabilities>
<build:Metadata>
<build:Item Name="Microsoft.Build.DesktopBridge.Tasks.dll" Version="4.6.30319.200" />
<build:Item Name="TargetFrameworkMoniker" Value="native,Version=v0.0" />
<build:Item Name="VisualStudio" Version="17.0" />
<build:Item Name="OperatingSystem" Version="10.0.22000.434 (WinBuild.160101.0800)" />
<build:Item Name="Microsoft.Build.AppxPackage.dll" Version="17.0.31912.81" />
<build:Item Name="ProjectGUID" Value="9a119a76-97cb-4490-b8c2-651576cb9302" />
<build:Item Name="MakePri.exe" Version="10.0.22000.194 (WinBuild.160101.0800)" />
</build:Metadata>
<mp:PhoneIdentity PhoneProductId="0f6c8cd6-bec0-499c-810f-28e88a3e4b62" PhonePublisherId="5865126c-fd0a-473f-9c00-925aa3a04529" />
</Package>
參考
- 向未打包的桌面應用授予標識
- Signed Sparse Packages and Identity
- https://aka.ms/sparsepkgsample
- SparsePackages
- Identity, Registration and Activation of Non-packaged Win32 Apps
- Enhancing Non-packaged Desktop Apps using Windows Runtime Components
- 使用打包擴展將桌面應用與Windows集成
- 獲取打包應用的激活信息
- 使用新式UWP組件擴展桌面應用
- 在桌面應用中調用Windows運行時API
- 解壓縮軟件 WinRAR 更新 6.10 正式版:支持 Win11 右鍵菜單、放棄 XP 系統
- 完美契合Win11右鍵菜單,這款壓縮軟件推薦給你
- 如何創建應用包簽名證書
- 使用SignTool對應用包進行簽名
- 為程序包簽名創建證書
- 如何創建應用程序清單文件 App.Manifest,如何創建不帶清單的應用程序
- 從CA存儲中刪除證書