mcpField
D
dotnet-msix

dotnet-msix

github.com/wshaddix開発8687 回インストール35 週間前に更新
リポジトリ

dotnet-msix について

dotnet-msixは、.NETデスクトップアプリ開発者向けのMSIXパッケージングスキルです。パッケージ作成、署名、配布、更新、CIビルドを扱い、単一プロジェクトとWAPプロジェクトの両方に対応します。

主な機能

  1. 01csprojまたはWAPからMSIXを作成
  2. 02証明書署名の設定
  3. 03Store提出とサイドロード配布
  4. 04App Installer更新の設定
  5. 05複数アーキテクチャのバンドル作成
  6. 06CI/CDへのMSIX手順追加

活用シーン

  1. 01.NETデスクトップアプリのリリースパッケージ作成
  2. 02配布用の証明書署名設定
  3. 03自動更新付きの直接配布設定
  4. 04複数アーキテクチャ向けパッケージ作成

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/wshaddix/dotnet-skills --skill dotnet-msix

インストール後、Claude Code で/dotnet-msixを入力して読み込まれたか確認します。

詳細

dotnet-msix

.NET デスクトップアプリケーション向けの MSIX パッケージングパイプライン:csproj(WindowsPackageType)および WAP プロジェクトからのパッケージ作成、証明書による署名(開発用の自己署名、本番用の信頼された CA、Microsoft Store による署名)、配布チャネル(Microsoft Store への提出、App Installer によるサイドローディング、SCCM/Intune を使用したエンタープライズ展開)、自動更新の設定(App Installer XML、バージョンチェック、差分更新)、複数アーキテクチャ向けの MSIX バンドル形式(.msixbundle)、CI/CD の MSIX ビルド手順。

バージョンの前提条件: Windows App SDK 1.6 以降(現在の安定版)。Windows App SDK で MSIX を使用する場合、Windows 10 ビルド 19041 以降が最小要件です。App Installer の自動更新プロトコルには Windows 10 ビルド 1709 以降が必要です。.NET 8.0 以降を基準とします。

スコープの境界: このスキルが扱うのは、MSIX パッケージングパイプライン(作成、署名、配布、Store への提出、自動更新、CI ビルド手順)です。WinUI 3 プロジェクトのセットアップ、XAML のパターン、パッケージ化と非パッケージ化のデプロイモードの比較は、[skill:dotnet-winui] が扱います。一般的な Native AOT コンパイル(PublishAot、ILLink 記述子)は、[skill:dotnet-native-aot] が扱います。一般的な CI/CD パイプラインのパターンは、[skill:dotnet-gha-patterns] と [skill:dotnet-ado-patterns] が扱います。

対象外: WinUI 3 プロジェクトのセットアップと MSIX と非パッケージ化の比較については、[skill:dotnet-winui] を参照してください。Native AOT の MSBuild 設定については、[skill:dotnet-native-aot] を参照してください。一般的な CI/CD パイプラインのパターンについては、[skill:dotnet-gha-patterns] と [skill:dotnet-ado-patterns] を参照してください。一般的な NuGet パッケージングについては、[skill:dotnet-nuget-authoring] を参照してください。コンテナーを使用したデプロイについては、[skill:dotnet-containers] を参照してください。

相互参照:[skill:dotnet-winui](WinUI プロジェクトのセットアップとパッケージングモードの比較)、[skill:dotnet-native-aot](AOT と MSIX のシナリオ)、[skill:dotnet-gha-patterns](CI パイプラインの構成)、[skill:dotnet-ado-patterns](ADO パイプラインの構成)、[skill:dotnet-nuget-authoring](NuGet パッケージング)。


MSIX パッケージの作成

csproj からの作成(単一プロジェクトのパッケージング)

最新の WinUI 3 アプリと Windows App SDK アプリでは、別の Windows Application Packaging(WAP)プロジェクトを作成せずに、アプリケーションの .csproj から MSIX パッケージを直接生成できます。


<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
    <UseWinUI>true</UseWinUI>

    
    <WindowsPackageType>MSIX</WindowsPackageType>

    
    <AppxPackageDir>$(SolutionDir)AppPackages\</AppxPackageDir>
    <GenerateAppxPackageOnBuild>false</GenerateAppxPackageOnBuild>
  </PropertyGroup>
</Project>

MSIX パッケージをビルドします。

# Build MSIX package
dotnet publish --configuration Release --runtime win-x64 \
  /p:GenerateAppxPackageOnBuild=true \
  /p:AppxPackageSigningEnabled=false

# Output: AppPackages\MyApp_1.0.0.0_x64.msix
WAP プロジェクト(Desktop Bridge)

WinUI 以外のデスクトップアプリ(WPF、WinForms)を MSIX としてラップするには、Windows Application Packaging Project を使用します。WAP プロジェクト(.wapproj)は Visual Studio の「Windows Application Packaging Project」テンプレートから作成します。標準の Microsoft.NET.Sdk ではなく、専用のプロジェクト形式を使用します。

重要な設定は、デスクトップアプリのプロジェクトを参照することです。



<ItemGroup>
  
  <ProjectReference Include="..\MyWpfApp\MyWpfApp.csproj" />
</ItemGroup>


<PropertyGroup>
  <TargetPlatformVersion>10.0.22621.0</TargetPlatformVersion>
  <TargetPlatformMinVersion>10.0.19041.0</TargetPlatformMinVersion>
  <DefaultLanguage>en-US</DefaultLanguage>
  <AppxPackageDir>$(SolutionDir)AppPackages\</AppxPackageDir>
</PropertyGroup>
Package.appxmanifest

マニフェストでは、ID、機能、ビジュアルアセットを定義します。

<?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:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
         IgnorableNamespaces="uap rescap">

  <Identity Name="MyCompany.MyApp"
            Publisher="CN=My Company, O=My Company, L=Seattle, S=WA, C=US"
            Version="1.0.0.0"
            ProcessorArchitecture="x64" />

  <Properties>
    <DisplayName>My App</DisplayName>
    <PublisherDisplayName>My Company</PublisherDisplayName>
    <Logo>Assets\StoreLogo.png</Logo>
  </Properties>

  <Dependencies>
    <TargetDeviceFamily Name="Windows.Desktop"
                        MinVersion="10.0.19041.0"
                        MaxVersionTested="10.0.22621.0" />
  </Dependencies>

  <Resources>
    <Resource Language="en-us" />
  </Resources>

  <Applications>
    <Application Id="App"
                 Executable="MyApp.exe"
                 EntryPoint="$targetentrypoint$">
      <uap:VisualElements DisplayName="My App"
                          Description="My application description"
                          BackgroundColor="transparent"
                          Square150x150Logo="Assets\Square150x150Logo.png"
                          Square44x44Logo="Assets\Square44x44Logo.png">
        <uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" />
      </uap:VisualElements>
    </Application>
  </Applications>

  <Capabilities>
    <Capability Name="internetClient" />
    <rescap:Capability Name="runFullTrust" />
  </Capabilities>
</Package>

証明書による署名

Windows にインストールするには、すべての MSIX パッケージに署名が必要です。署名証明書の Subject は、パッケージマニフェストの Publisher 属性と一致している必要があります。

自己署名証明書(開発用)
# Create a self-signed certificate for development
$cert = New-SelfSignedCertificate `
  -Type Custom `
  -Subject "CN=My Company, O=My Company, L=Seattle, S=WA, C=US" `
  -KeyUsage DigitalSignature `
  -FriendlyName "MyApp Dev Signing" `
  -CertStoreLocation "Cert:\CurrentUser\My" `
  -TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.3", `
                    "2.5.29.19={text}")

# Export PFX for CI usage
$password = ConvertTo-SecureString -String "$env:CERT_PASSWORD" -Force -AsPlainText
Export-PfxCertificate -Cert $cert `
  -FilePath "MyApp_DevSigning.pfx" `
  -Password $password

# Find signtool.exe dynamically (SDK version varies by machine)
$signtool = Get-ChildItem "C:\Program Files (x86)\Windows Kits\10\bin\*\x64\signtool.exe" |
  Sort-Object { [version]($_.Directory.Parent.Name) } -Descending |
  Select-Object -First 1 -ExpandProperty FullName

# Sign the MSIX package
& $signtool sign /fd SHA256 /a /f "MyApp_DevSigning.pfx" `
  /p "$env:CERT_PASSWORD" `
  "AppPackages\MyApp_1.0.0.0_x64.msix"
信頼された CA の証明書(本番用)

Microsoft Store 以外で本番配布する場合:

  1. 信頼された CA(DigiCert、Sectigo、GlobalSign)からコード署名証明書を取得します
  2. Subject が Package.appxmanifest の Publisher と一致している必要があります
  3. 長期的な有効性を確保するため、署名にタイムスタンプを付与します
# Sign with a trusted CA certificate (from certificate store)
& signtool.exe sign /fd SHA256 /sha1 "THUMBPRINT_HERE" `
  /tr http://timestamp.digicert.com /td SHA256 `
  "AppPackages\MyApp_1.0.0.0_x64.msix"

# Sign with a PFX file
& signtool.exe sign /fd SHA256 /f "production-cert.pfx" `
  /p "$env:CERT_PASSWORD" `
  /tr http://timestamp.digicert.com /td SHA256 `
  "AppPackages\MyApp_1.0.0.0_x64.msix"
Microsoft Store による署名

Microsoft Store に提出されたアプリは、取り込み処理中に Microsoft によって再署名されます。開発用署名証明書は、Microsoft が発行した証明書に置き換えられます。Store のみで配布する場合、本番用署名証明書は必要ありません。


<PropertyGroup>
  <AppxPackageSigningEnabled>true</AppxPackageSigningEnabled>
  <PackageCertificateThumbprint>AUTO_GENERATED_BY_VS</PackageCertificateThumbprint>
</PropertyGroup>
証明書要件の概要
配布方法証明書の種類信頼された CA が必要
開発/テスト自己署名いいえ(証明書を手動でインストール)
エンタープライズのサイドロード自己署名または内部 CAいいえ(グループポリシーで証明書を展開)
直接ダウンロード信頼された CA(DigiCert など)はい
Microsoft Storeテスト証明書(MS による再署名)いいえ

配布チャネル

Microsoft Store への提出
  1. Partner Center(https://partner.microsoft.com/dashboard)で Windows 開発者として登録します
  2. アプリ名を確保するため、アプリの予約を作成します
  3. Store との関連付けを行って MSIX パッケージをビルドします:
# Build for Store submission (creates .msixupload)
dotnet publish --configuration Release --runtime win-x64 \
  /p:GenerateAppxPackageOnBuild=true \
  /p:UapAppxPackageBuildMode=StoreUpload \
  /p:AppxBundle=Auto
  1. .msixupload ファイルを Partner Center から提出します
  2. Microsoft がアプリを検証、署名し、公開します
App Installer によるサイドロード

App Installer(.appinstaller)を使用すると、自動更新に対応した直接配布が可能です。ファイルを Web サーバー、ネットワーク共有、または CDN でホストします。


<?xml version="1.0" encoding="utf-8"?>
<AppInstaller Uri="https://mycompany.com/apps/MyApp.appinstaller"
              Version="1.0.0.0"
              xmlns="http://schemas.microsoft.com/appx/appinstaller/2021">

  <MainPackage Name="MyCompany.MyApp"
               Version="1.0.0.0"
               Publisher="CN=My Company, O=My Company, L=Seattle, S=WA, C=US"
               ProcessorArchitecture="x64"
               Uri="https://mycompany.com/apps/MyApp_1.0.0.0_x64.msix" />

  <UpdateSettings>
    <OnLaunch HoursBetweenUpdateChecks="12"
              ShowPrompt="true"
              UpdateBlocksActivation="false" />
    <AutomaticBackgroundTask />
    <ForceUpdateFromAnyVersion>false</ForceUpdateFromAnyVersion>
  </UpdateSettings>
</AppInstaller>

ユーザーは次の方法でインストールします:

ms-appinstaller:?source=https://mycompany.com/apps/MyApp.appinstaller
エンタープライズ展開

管理対象のエンタープライズ環境では、次の方法を使用できます:

方法ツール最適な用途
Microsoft IntuneIntune ポータルクラウド管理デバイス
SCCM/MECMConfiguration Managerオンプレミス管理デバイス
グループポリシーDISM / PowerShellドメイン参加デバイス
PowerShellAdd-AppxPackageスクリプトによる展開
# Enterprise deployment via PowerShell
Add-AppxPackage -Path "\\fileserver\apps\MyApp_1.0.0.0_x64.msix"

# Install for all users (requires admin)
Add-AppxProvisionedPackage -Online `
  -PackagePath "MyApp_1.0.0.0_x64.msix" `
  -SkipLicense

自動更新の構成

App Installer の自動更新(Windows 10 1709+)

App Installer の XML ファイルで、自動更新の動作を制御します:

<UpdateSettings>
  
  <OnLaunch HoursBetweenUpdateChecks="12"
            ShowPrompt="true"
            UpdateBlocksActivation="false" />

  
  <AutomaticBackgroundTask />

  
  <ForceUpdateFromAnyVersion>false</ForceUpdateFromAnyVersion>
</UpdateSettings>
設定説明
HoursBetweenUpdateChecks更新チェックの最小間隔(時間)(0 = 起動のたび)
ShowPrompt更新前にユーザーに更新ダイアログを表示する
UpdateBlocksActivation更新が完了するまでアプリの起動をブロックする
AutomaticBackgroundTaskアプリを起動せずにバックグラウンドで更新を確認する
ForceUpdateFromAnyVersion任意のバージョンからの更新を許可する(ダウングレードを含む)
プログラムによる更新チェック(Windows App SDK)

カスタムの更新 UI やロジックが必要なアプリでは、Package.Current.CheckUpdateAvailabilityAsync() を使用します:

using Windows.ApplicationModel;

public class AppUpdateService
{
    public async Task<bool> CheckForUpdatesAsync()
    {
        var result = await Package.Current.CheckUpdateAvailabilityAsync();
        return result.Availability == PackageUpdateAvailability.Available
            || result.Availability == PackageUpdateAvailability.Required;
    }
}
差分更新

MSIX は差分更新に対応しており、変更されたブロックのみがダウンロードされます。次の条件を満たす場合、自動的に適用されます:

  • 同じ PackageName と Publisher を使用している
  • Version が更新されている
  • 古いパッケージと新しいパッケージが同じサーバーでホストされている

差分更新に追加の構成は必要ありません。


MSIX バンドル形式

MSIX バンドル(.msixbundle)は、複数のアーキテクチャ固有の MSIX パッケージを単一のダウンロード可能な成果物にまとめます。Windows は適切なアーキテクチャを自動的にインストールします。

バンドルの作成
# Build for multiple architectures
dotnet publish -c Release -r win-x64 /p:GenerateAppxPackageOnBuild=true
dotnet publish -c Release -r win-arm64 /p:GenerateAppxPackageOnBuild=true

# Find MakeAppx.exe dynamically (SDK version varies by machine)
$makeappx = Get-ChildItem "C:\Program Files (x86)\Windows Kits\10\bin\*\x64\MakeAppx.exe" |
  Sort-Object { [version]($_.Directory.Parent.Name) } -Descending |
  Select-Object -First 1 -ExpandProperty FullName

# Create bundle
& $makeappx bundle /d "AppPackages" /p "MyApp_1.0.0.0.msixbundle"
MSBuild によるバンドル生成
<PropertyGroup>
  
  <AppxBundle>Always</AppxBundle>
  <AppxBundlePlatforms>x64|arm64</AppxBundlePlatforms>
</PropertyGroup>
バンドルのレイアウト
MyApp_1.0.0.0.msixbundle
  MyApp_1.0.0.0_x64.msix
  MyApp_1.0.0.0_arm64.msix

CI/CD の MSIX ビルド手順

GitHub Actions の MSIX ビルド
# MSIX-specific build steps (embed in your CI workflow)
# For pipeline structure, see [skill:dotnet-gha-patterns]
jobs:
  build-msix:
    runs-on: windows-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup .NET
        uses: actions/setup-dotnet@v4
        with:
          dotnet-version: '8.0.x'

      - name: Decode signing certificate
        run: |
          $pfxBytes = [System.Convert]::FromBase64String("${{ secrets.SIGNING_CERT_BASE64 }}")
          [System.IO.File]::WriteAllBytes("signing-cert.pfx", $pfxBytes)
        shell: pwsh

      - name: Build MSIX package
        run: |
          dotnet publish --configuration Release --runtime win-x64 `
            /p:GenerateAppxPackageOnBuild=true `
            /p:AppxPackageSigningEnabled=true `
            /p:PackageCertificateKeyFile="${{ github.workspace }}\signing-cert.pfx" `
            /p:PackageCertificatePassword="${{ secrets.CERT_PASSWORD }}"
        shell: pwsh

      - name: Upload MSIX artifact
        uses: actions/upload-artifact@v4
        with:
          name: msix-package
          path: AppPackages/**/*.msix

      - name: Clean up certificate
        if: always()
        run: Remove-Item -Path "signing-cert.pfx" -ErrorAction SilentlyContinue
        shell: pwsh
Azure DevOps の MSIX ビルド
# MSIX-specific build steps (embed in your ADO pipeline)
# For pipeline structure, see [skill:dotnet-ado-patterns]
steps:
  - task: UseDotNet@2
    inputs:
      packageType: 'sdk'
      version: '8.0.x'

  - task: DownloadSecureFile@1
    name: signingCert
    inputs:
      secureFile: 'signing-cert.pfx'

  - task: DotNetCoreCLI@2
    displayName: 'Build MSIX'
    inputs:
      command: 'publish'
      publishWebProjects: false
      projects: '**/MyApp.csproj'
      arguments: >-
        --configuration Release
        --runtime win-x64
        /p:GenerateAppxPackageOnBuild=true
        /p:AppxPackageSigningEnabled=true
        /p:PackageCertificateKeyFile=$(signingCert.secureFilePath)
        /p:PackageCertificatePassword=$(CERT_PASSWORD)

  - task: PublishBuildArtifacts@1
    inputs:
      pathToPublish: 'AppPackages'
      artifactName: 'msix-package'
AOT + MSIX

MSIX パッケージには、起動の高速化とランタイムのフットプリント縮小を実現する AOT コンパイル済みバイナリを含めることができます。PublishAot と MSIX パッケージ化を組み合わせます:

<PropertyGroup>
  <PublishAot>true</PublishAot>
  <WindowsPackageType>MSIX</WindowsPackageType>
</PropertyGroup>

AOT の MSBuild 構成の詳細(ILLink ディスクリプター、トリミングオプション、プラットフォームに関する考慮事項)については、[skill:dotnet-native-aot] を参照してください。


Windows SDK のバージョン要件

機能最小 Windows バージョンビルド番号
Windows App SDK での MSIXWindows 10ビルド 19041(2004)
App Installer プロトコルWindows 10ビルド 1709(Fall Creators Update)
自動更新(OnLaunch)Windows 10ビルド 1709
バックグラウンド自動更新Windows 10ビルド 1803(April 2018 Update)
ForceUpdateFromAnyVersionWindows 10ビルド 1809
MSIX バンドル形式Windows 10ビルド 1709
オプションパッケージWindows 10ビルド 1709
変更パッケージWindows 10ビルド 1809
App Installer ファイルのホスティングWindows 10ビルド 1709
Microsoft Store への提出Windows App SDK 1.6+N/A
ターゲットプラットフォームのバージョン設定
<PropertyGroup>
  
  <TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>

  
  <TargetPlatformVersion>10.0.22621.0</TargetPlatformVersion>
</PropertyGroup>

エージェントが注意すべき点

  1. マニフェストの Publisher は署名証明書の Subject と完全に一致している必要があります -- 不一致の場合、ビルド時または署名時に SignTool Error: SignerSign() failed が発生します。

  2. 自己署名証明書は手動で信頼済みにする必要があります -- MSIX をインストールする前に、ユーザーは証明書を Trusted People または Trusted Root Certification Authorities にインストールする必要があります。

  3. PFX ファイルや証明書のパスワードをソース管理にコミットしないでください -- 証明書は CI シークレット(GitHub Secrets、Azure DevOps Secure Files)として保存し、ビルドパイプライン中にデコードしてください。

  4. AppxBundle=Auto でバンドルが生成されるのは、複数のアーキテクチャをビルドする場合のみです -- 単一アーキテクチャのビルドでは、バンドルではなくフラットな .msix ファイルが生成されます。

  5. MSIX アプリはコンテナーのようなサンドボックス内で動作します -- ファイルシステムへのアクセスは仮想化されます。AppData に書き込むアプリでは、パッケージ固有の場所にリダイレクトされます。ハードコードされたパスではなく、ApplicationData.Current API を使用してください。

  6. ストアへの提出には .msix ではなく .msixupload を使用します -- 正しいアップロード形式を生成するには、/p:UapAppxPackageBuildMode=StoreUpload を設定してください。

  7. windows-latest での CI ビルドには Windows SDK が含まれています -- signtool.exe と MakeAppx.exe のために、別途 SDK をインストールする必要はありません。

  8. CI の例では TFM のパスをハードコードしないでください -- 例が .NET の各バージョンで動作するよう、変数参照(例:${{ github.workspace }})を使用してください。

コメント