Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Egy működő, teljes körű példáért (WPF alkalmazás + Inno telepítő) tekintse meg a ritka alkalmazás mintáját.
A standard asztali végrehajtható fájlok – amelyek az MSBuild, a CMake vagy bármely más eszközlánc használatával dotnet buildkészültek – nem rendelkezik csomagidentitással. Identitás nélkül nem használhat számos modern Windows API-t (bejelentési értesítések, háttérfeladatok, megosztási célok, indítási feladatok, alkalmazásadat API-k stb.).
A ritka csomagolás identitást ad egy alkalmazásnak anélkül , hogy bináris fájljait MSIX-be helyezné át. Egy apró, csak identitást tartalmazó.msix csomagot ad át (csak egy jegyzékfájlt), és azt a szokásos módon telepített alkalmazása mellett, külső hely használatával regisztrálja. Az Ön .exe pontosan ott marad, ahová a telepítő helyezi. Ez a(z) winapp create-debug-identity éles környezeti megfelelője, amely kizárólag a fejlesztés közbeni hibakeresésre szolgál.
Ez az útmutató azt a három CLI-lépést ismerteti, amely a hivatalos Identitás megadása nem csomagolt alkalmazásoknak munkafolyamat első három lépésének felel meg:
| Lépés | Parancs | Result |
|---|---|---|
| 1. Az identitásjegyzék létrehozása | winapp init --exe <exe> --sparse |
sparse/appxmanifest.xml + sparse/Assets/ |
| 2. Az identitáscsomag létrehozása és aláírása | winapp pack <appxmanifest.xml> --cert <pfx> |
<PackageName>.identity.msix |
| 3. Identitás beágyazása az alkalmazásba | winapp embed-identity <exe> |
<msix> elem az exe fúziós jegyzékében |
A dokumentáció 4–5. lépése (a csomag regisztrálása / regisztrációjának törlése) a telepítő feladata – lásd a Telepítő integrációját.
Mikor érdemes ritkán használt csomagolást használni?
- Már rendelkezik kiforrott telepítővel (Inno Setup, WiX, NSIS, MSI), és nem szeretne msIX-re váltani a disztribúcióhoz, de identitásalapú Windows API-kra van szüksége.
- Az alkalmazásnak olyan elérési útra vagy elrendezésre kell telepítenie, amelyet az MSIX nem engedélyez.
- Minimális, additív módosítást szeretne: tartsa meg a meglévő telepítési folyamatot, és adjon hozzá egy
.msixregisztrációs lépést.
Ha most kezdi, és MSIX-ként tudja terjeszteni, a teljesen csomagolt alkalmazás (winapp init + winapp pack <folder>) egyszerűbb.
Prerequisites
- Windows 10, 2004-es (19041-es build) vagy újabb verzió. A sparse csomagok a
uap10:AllowExternalContentelemre támaszkodnak, amihez a 19041-es vagy újabb verzió szükséges. -
winapp CLI – telepítés wingettel (vagy frissítés, ha már telepítve van):
winget install Microsoft.WinApp --source winget -
Kódaláíró tanúsítvány, amelyben a célgép megbízik. A helyi teszteléshez hozzon létre egy fejlesztési tanúsítványt,
winapp cert generateés bízzon benne. Az éles csomagokat olyan tanúsítvánnyal kell aláírni, amelynek tárgya megegyezik a jegyzékfájllalPublisher.
Walkthrough
Az alábbi példák egy beépített végrehajtható fájlt feltételeznek a következő helyen ./bin/Release/net8.0-windows/MyApp.exe: .
1. lépés – Hozza létre a részleges identitás-jegyzékfájlt
winapp init --exe ./bin/Release/net8.0-windows/MyApp.exe --sparse
Ez az .exe fájlból kiolvassa a csomag nevét, a kiadóját, a verzióját és a leírását (a fájl verzióinformációi alapján), majd felkéri, hogy fogadja el vagy írja felül ezeket. Adja hozzá --use-defaults (vagy --no-prompt) a parancssorok kihagyásához a CI-ben, és --name / --publisher felülbírálja a megadott értékeket:
winapp init --exe ./bin/Release/net8.0-windows/MyApp.exe --sparse --use-defaults `
--name "Contoso.MyApp" --publisher "CN=Contoso"
Alapértelmezés szerint egy dedikált sparse/ mappába írja a következőket az aktuális könyvtárban (felülbírálás a következővel --output-dir):
-
appxmanifest.xml— egy egyszerű manifest, benne<uap10:AllowExternalContent>true</uap10:AllowExternalContent>-val (egy elem a(z)<Properties>alatt),ProcessorArchitecture="neutral"-mal, egywin32Appalkalmazással, és az exe neve a(z)Executablemezőbe beírva. -
Assets/— helyőrző vizualizációs objektumok (lehetőség szerint kinyerve az exe ikonjából).
Miért egy
sparse/mappa, és nem az exe mellett? A manifestum és aAssets/olyan fordításkori bemenetek, amelyeket awinapp packés awinapp embed-identityhasznál fel — futásidőben semmi sem olvassa őket az .exe mellől (a futásidejű identitás az .exe-be ágyazott<msix>elemből, valamint a regisztrált csomag külső helyéből származik, a manifestum pedig név alapján hivatkozik az .exe-re, így a helye független attól, hogy maga az .exe hol található). Ha egy dedikált, forrás által vezérelt mappába írja őket, azokat egy buildkimeneti könyvtárból (példáulbin/) távol tartja, amelyet egy tiszta/újraépítés törölne, és a mappa bináris fájloktól mentes marad, így a következő lépések tiszta maradnak.winapp packéswinapp embed-identityautomatikusan a(z)sparse/helyen keres, ezért ritkán kell megadnia az elérési utat.
Megjegyzés: A ritka init folyamat szándékosan kihagyja az összes SDK/csomagtelepítést – a csak identitásalapú csomagok nem rendelkeznek SDK-függőségekkel.
Ha egy appxmanifest.xml már létezik a célkönyvtárban, az init leáll ahelyett, hogy felülírná azt (és a Assets/ elemét). Az újrageneráláshoz futtassa újra a(z) --force használatával.
Győződjön meg arról, hogy a létrehozott Publisher jegyzékfájl megegyezik azzal a tanúsítvánnyal, amellyel alá fogja írni. Szükség esetén szerkessze a(z) appxmanifest.xml elemet, vagy generáláskor adja meg a(z) --publisher elemet.
2. lépés – Az identitáscsomag létrehozása és aláírása
Mutasson winapp pack a ritka jegyzékre (fájlra, nem mappára):
winapp pack ./sparse/appxmanifest.xml --cert ./devcert.pfx
Mivel a manifesztum deklarálja a AllowExternalContent elemet, a winapp pack egy csak identitást tartalmazó.msix csomagot hoz létre, amely csak a manifesztumot tartalmazza — bináris fájlok és erőforrások nélkül. A kimenet alapértelmezés szerint a jelenlegi könyvtárban lévő <PackageName>.identity.msix értéket használja; ennek módosításához használja a(z) --output kapcsolót. Az aláírásra csak akkor kerül sor, ha megadja a --cert elemet (vagy a --generate-cert elemet).
3. lépés – Identitás beágyazása az alkalmazásba
Ágyazza be az <msix> elemet úgy, hogy Windows csatlakoztassa a futó exe-t az identitáscsomaghoz:
# EXE mode — modify the built binary in place (uses mt.exe)
winapp embed-identity ./bin/Release/net8.0-windows/MyApp.exe
Vagy megőrizheti az egymás melletti manifestfájlt verziókövetésbe felvett fájlként, majd újraépítheti:
# XML mode — update an external SxS manifest, then rebuild your app
winapp embed-identity ./app.manifest
XML módban az <msix> elem be lesz szúrva (vagy lecserélve) a céljegyzékbe. Hivatkozzon a projektben lévő jegyzékfájlra (.NET esetén állítsa be: <ApplicationManifest>app.manifest</ApplicationManifest>), majd építse újra, hogy az elem beágyazódjon az EXE fájlba.
Mindkét mód egy ritkás appxmanifest.xml elemből olvassa ki az azonosítót. Ha kihagyja --manifest, a winapp először a cél mellett egy sparse/ mappában (ahol winapp init --exe --sparse alapértelmezés szerint megírja) jelenik meg, majd az aktuális könyvtárban, majd visszaesik a cél és az aktuális könyvtár mellé; átmegy --manifest máshová.
Megjegyzés: Az EXE mód
mt.exeújraírja a binárist, ami minden meglévő Authenticode-aláírást érvénytelenít. A terjesztés előtt írja alá újra az exe-t (példáulwinapp sign ./MyApp.exe <cert.pfx>).
4. lépés – Regisztráció (helyi teszteléshez)
A jegyzékfájl logói futásidőben a külső helyről töltődnek be, nem pedig a csak identitást tartalmazó .msix elemből. Az 1. lépés a ./sparse/Assets alá írta őket, ezért a regisztrálás előtt másolja át őket az .exe fájl mellé (a külső helyre) — ellenkező esetben a Windows olyan kiosztást regisztrál, amelyből hiányzik a jegyzékfájlban hivatkozott összes logó:
# Copy the generated assets into the external location (beside your exe)
Copy-Item ./sparse/Assets -Destination .\bin\Release\net8.0-windows\Assets -Recurse -Force
Ezután regisztrálja az identitáscsomagot ahhoz a mappához (a külső helyhez):
Add-AppxPackage -Path .\MyApp.identity.msix `
-ExternalLocation (Resolve-Path .\bin\Release\net8.0-windows)
Indítsa el az alkalmazást, és győződjön meg arról, hogy az identitás jelen van – Windows.ApplicationModel.Package.Current.Id.FamilyName például dobás helyett a csomagcsalád nevét kell visszaadnia.
Tisztítás:
Remove-AppxPackage <full-package-name>
Eszközkezelés
A ritka .msixcsak identitás lehet. A manifestumban hivatkozott vizuális elemek (Assets\StoreLogo.png, csempék stb.) futásidőben a külső tartalom helyéről kerülnek feloldásra — vagyis az alkalmazás telepítési könyvtárából —, nem pedig a .msix belsejéből.
Ez azt jelenti, hogy az alkalmazása mellett kell telepítenie a Assets/ mappát (ugyanabban az elrendezésben, mint amit a jegyzékfájl a külső helyhez képest elvár).
A 2. lépés közvetlenül a manifestfájlt csomagolja be (winapp pack ./sparse/appxmanifest.xml), ami kizárólag ebből a manifestfájlból hozza létre a csak identitást tartalmazó .msix elemet — a mellette lévő fájlokat figyelmen kívül hagyja, így az soha nem tartalmazza az erőforrásait vagy bináris fájljait. (Ha ehelyett a winapp pack mutat, amelynek a manifesztuma deklarálja a AllowExternalContent elemet, figyelmeztet az összes talált eszközfájlra vagy bináris fájlra, mivel ritkított csomag esetén ezeknek a külső helyen van a helyük, nem a .msix elemen belül.)
Telepítőintegráció
A regisztráció és a regisztráció törlése a telepítő feladata. A minta megegyezik a telepítőeszközökkel:
-
Telepítés: másolja az alkalmazás bináris fájljait, a
Assets/mappát és a.msixtelepítési könyvtárba, majd futtassaAdd-AppxPackage -Path "<install-dir>\MyApp.identity.msix" -ExternalLocation "<install-dir>". -
Eltávolítás: a fájlok törlése előtt futtassa
Remove-AppxPackage <full-package-name>.
Biztonság: a telepítési könyvtár a telepítéskor feloldódik, és tartalmazhat olyan karaktereket (például egyetlen idézőjelet), amelyek egy PowerShell-sztringkonstansból bontanak ki. A sztringbe történő
-Commandinterpolálás előtt mindig meneküljön vagy ellenőrizze az elérési utat – az alábbi WiX- és NSIS-kódrészletek megbízható telepítési útvonalat feltételeznek, míg az Inno telepítőpéldája a biztonságos menekülést szemlélteti. Részesítse előnyben az elérési utak argumentumként való átadását egy-Fileszkript számára a soron belüli-Commandinterpoláció helyett.
Inno Setup
A PowerShell-argumentumokat egy [Code] függvényben állítsa össze, hogy a futtatókörnyezet telepítési útvonala megfelelően escape-elve legyen az egyszeres idézőjelekkel határolt PowerShell-literálhoz (egy ' karaktert tartalmazó telepítési könyvtár nem teheti lehetővé szkriptinjektálást):
[Files]
Source: "dist\*"; DestDir: "{app}"; Flags: recursesubdirs
Source: "MyApp.identity.msix"; DestDir: "{app}"
[Run]
Filename: "powershell.exe"; Parameters: "{code:RegisterParams}"; Flags: runhidden
[UninstallRun]
Filename: "powershell.exe"; \
Parameters: "-NoProfile -ExecutionPolicy Bypass -Command ""Get-AppxPackage -Name 'MyApp' | Remove-AppxPackage"""; \
Flags: runhidden
[Code]
function EscapePSLiteral(const Value: string): string;
var S: string;
begin
S := Value; StringChange(S, '''', ''''''); Result := S;
end;
function RegisterParams(Param: string): string;
var AppDir: string;
begin
AppDir := ExpandConstant('{app}');
{ -ErrorAction Stop + try/catch make a registration failure terminating, so powershell.exe
exits nonzero and the AfterInstall callback (see the full sample) can abort with rollback. }
Result := '-NoProfile -ExecutionPolicy Bypass -Command "try { Add-AppxPackage -Path ''' +
EscapePSLiteral(AppDir + '\MyApp.identity.msix') +
''' -ExternalLocation ''' + EscapePSLiteral(AppDir) + ''' -ErrorAction Stop } catch { Write-Error $_; exit 1 }"';
end;
A teljes, működő setup.iss megtekintéséhez lásd a sparse-app példát.
Az alábbi WiX- és NSIS-példák a -File segítségével egy kis register-sparse.ps1-t hívnak meg, így a telepítési útvonal paraméterként lesz átadva (a PowerShell adatként kezeli), ahelyett hogy egy -Command karakterláncba lenne interpolálva. Így elkerülhető a szkriptinjektálás egy létrehozott telepítési könyvtáron keresztül (például egy idézőjelet tartalmazó mappanév vagy $(...)):
# register-sparse.ps1 — ship this alongside your installer
param(
[Parameter(Mandatory)] [string] $MsixPath,
[Parameter(Mandatory)] [string] $ExternalLocation,
[Parameter(Mandatory)] [string] $PackageName
)
$ErrorActionPreference = 'Stop'
try {
# Add-AppxPackage emits NON-terminating errors by default, so a failure would otherwise leave
# the process exit code at 0 and let the installer complete without identity. Try the add
# directly first: a fresh install or a version-bumped upgrade registers/updates in place
# without touching any existing registration. -ErrorAction Stop + the outer trap make a real
# failure terminating so the installer (WiX Return="check" / NSIS) sees it.
try {
Add-AppxPackage -Path $MsixPath -ExternalLocation $ExternalLocation -ErrorAction Stop
} catch {
# Only ONE failure is safe to resolve by unregister+retry: the exact same version is already
# registered (HRESULT 0x80073CFB, ERROR_PACKAGE_ALREADY_EXISTS — "already installed,
# reinstallation blocked"), which Add-AppxPackage rejects. Re-throw everything else
# (untrusted/corrupt .msix, unsupported OS, ...) so a bad new package can NEVER unregister a
# working prior registration and strip the installed app of the identity it already had.
if ($_.Exception.HResult -ne 0x80073CFB) { throw }
Get-AppxPackage -Name $PackageName | Remove-AppxPackage -ErrorAction SilentlyContinue
Add-AppxPackage -Path $MsixPath -ExternalLocation $ExternalLocation -ErrorAction Stop
}
} catch {
Write-Error $_
exit 1
}
WiX (v3)
Regisztráljon felhasználónként (Impersonate="yes"), mert Add-AppxPackage regisztrálja a csomagot az azt futtató fiókhoz. Az Impersonate="no" használatával végrehajtott halasztott művelet LocalSystem néven fut, amely nem biztosítja a telepítő felhasználó jogosultságait (ezért ezt gyakran elutasítják). Gépszintű MSI esetén a regisztrációt megszemélyesítve futtassa, hogy az a regisztrációt kezdeményező felhasználóra vonatkozzon.
Egy halasztott egyéni művelet nem tudja közvetlenül beolvasni a INSTALLFOLDER értékét (mivel a halasztott műveletek olyan környezetben futnak, ahol nincs hozzáférés a tulajdonságokhoz), és a művelet puszta deklarálása még nem hajtja végre azt. Ezért vezesse be az elérési utakat a(z) CustomActionData használatával — egy azonnali, 51-es típusú műveleten keresztül, amelynek a Property neve megegyezik a halasztott művelet Id értékével —, majd ütemezze mindkettőtInstallFiles után:
<!-- Immediate: stash the command line (with the resolved paths) into the deferred action's
CustomActionData. Windows Installer copies the value of the property named the same as a
deferred action into that action's CustomActionData. -->
<CustomAction Id="SetRegisterSparseCmd" Property="RegisterSparse" Execute="immediate"
Value="powershell.exe -NoProfile -ExecutionPolicy Bypass -File "[INSTALLFOLDER]register-sparse.ps1" -MsixPath "[INSTALLFOLDER]MyApp.identity.msix" -ExternalLocation "[INSTALLFOLDER]" -PackageName "MyPackageIdentityName"" />
<!-- Deferred + impersonated: CAQuietExec reads its command line from CustomActionData when run
deferred, so it registers the package for the invoking user. Return="check" fails the
install if registration fails. -->
<CustomAction Id="RegisterSparse" BinaryKey="WixCA" DllEntry="CAQuietExec"
Execute="deferred" Impersonate="yes" Return="check" />
<InstallExecuteSequence>
<Custom Action="SetRegisterSparseCmd" After="InstallFiles">NOT Installed</Custom>
<Custom Action="RegisterSparse" After="SetRegisterSparseCmd">NOT Installed</Custom>
</InstallExecuteSequence>
CAQuietExec a WiX util bővítmény részeként érhető el (WixUtilExtension); hivatkozzon erre, hogy a WixCA bináris elérhető legyen.
Egyetlen megszemélyesített művelet csak a telepítőt futtató felhasználó identitását regisztrálja. Ha egy gépenkénti telepítés minden felhasználója számára szeretné biztosítani az üzembe helyezést, regisztráljon helyette az első indításkor (felhasználónként), vagy használjon üzembehelyezési mechanizmust, például
Add-AppxProvisionedPackage.
NSIS
Section
# Capture the PowerShell exit code and abort if registration failed. register-sparse.ps1 exits
# nonzero on failure (it sets $ErrorActionPreference='Stop' and traps), so without this check the
# installer would complete even though the app has no identity.
ExecWait 'powershell.exe -NoProfile -ExecutionPolicy Bypass -File "$INSTDIR\register-sparse.ps1" -MsixPath "$INSTDIR\MyApp.identity.msix" -ExternalLocation "$INSTDIR" -PackageName "MyPackageIdentityName"' $0
IntCmp $0 0 +2
Abort "Registering the sparse identity package failed (exit code $0). The app requires package identity."
SectionEnd
Hibaelhárítás
Package.Current futásidőben „nincs csomagazonosító” hibát jelez
- Az identitáscsomag nincs regisztrálva, vagy az exe fúziós jegyzékfájlja hiányzik az
<msix>elemből. Futtassa újra a(z)winapp embed-identityelemet (és XML mód használata esetén építse újra), majd regisztrálja újra a(z)Add-AppxPackage -ExternalLocationhasználatával. - Az
<msix packageName>/ /publisherapplicationIdexe fájlnak pontosan meg kell egyeznie a regisztrált csomag identitásával.
Az eszközök/emblémák nem jelennek meg
- Győződjön meg arról, hogy a
Assets/mappa a külső helyre van telepítve, ugyanazokkal a relatív elérési utakkal, amelyeket a manifesztum elvár. Az eszközök a külső helyről vannak feloldva, nem a.msix.
Add-AppxPackage aláírási/megbízhatósági hibával meghiúsul
- A
.msixtanúsítványt olyan tanúsítvánnyal kell aláírni, amely megbízható a gépen, és amelynek tárgya megegyezik a jegyzékfájlévalPublisher. Helyi teszteléshez hozzon létre és bízzon meg egy fejlesztői tanúsítványtwinapp cert generate, és győződjön meg arról, hogy a jegyzékPublisheregyezik vele.
MakeAppx: "Az alkalmazás, amelynek a RuntimeBehavior értéke 'win32App', nem deklarálhatja az EntryPointot"
- Egy
win32Appritkás alkalmazás nem deklarálhatEntryPoint. Awinapp init --sparseáltal létrehozott jegyzékfájlok már helyesek; távolítsa el aEntryPointattribútumot, ha kézzel szerkesztette a jegyzékfájlt.
"A bemenet egy fájl, de nem szórt jegyzékfájl"
-
winapp pack <file>csak olyan jegyzékfájlt fogad el, amely deklarálja a(z)<uap10:AllowExternalContent>true</uap10:AllowExternalContent>elemet. Hozzon létre egyet a(z)winapp init --exe <exe> --sparsehasználatával, vagy adjon meg egy bemeneti mappát a teljes MSIX felépítéséhez.
Lásd még
Windows developer