Reputation: 165
I have a .NET 4.6.2 app that needs to add a provisioned UWP app. The current plan is to use Process.Start()
to launch powershell. Assume the UWP app is present at the exe path as "test.appx".
Here's the code:
var psi = new ProcessStartInfo
{
UseShellExecute = true,
CreateNoWindow = false,
Arguments = "Add-AppxProvisionedPackage -Online -PackagePath test.appx -SkipLicense",
WindowStyle = ProcessWindowStyle.Hidden,
FileName = "powershell.exe",
Verb = "runas"
};
var proc = Process.Start(psi);
I'm using the runas
verb because provisioning commands require elevation.
The process starts without throwing, but the app does not get provisioned, and if I use proc.WaitForExit()
and check the ExitCode
, it returns error code 1.
If I use a manifest to require the host app to have elevated rights, it does work, but I would prefer to not require elevation to run the host app.
I'm wondering if there's something wrong with how I'm setting up the ProcessStartInfo
? Or otherwise if there's a way to temporarily elevate the host process?
Upvotes: 0
Views: 290
Reputation: 22251
You can also add the package by directly calling the undocumented DismAddProvisionedAppxPackage
API. (Standard warnings about using undocumented API's apply).
P/Invoke:
[DllImport("dismapi.dll", PreserveSig = false)]
public static extern void DismAddProvisionedAppxPackage(
uint Session,
[MarshalAs(UnmanagedType.LPWStr)] string AppPath,
[MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPWStr, SizeParamIndex=3)] string[] DependencyPackages,
uint DependencyPackageCount,
[MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPWStr, SizeParamIndex=5)] string[] OptionalPackages,
uint OptionalPackageCount,
[MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPWStr, SizeParamIndex=7)] string[] LicensePaths,
uint LicensePathCount,
bool SkipLicense,
[MarshalAs(UnmanagedType.LPWStr)] string CustomDataPath,
[MarshalAs(UnmanagedType.LPWStr)] string Regions,
int stubPackageOption
);
This is also available from ManagedDism (MIT License, Nuget)
using var sess = DismApi.OpenOnlineSession();
DismApi.AddProvisionedAppxPackage(sess, @"c:\foo\bar.appx", null, null, null!);
Upvotes: 0
Reputation: 447
When you run powershell.exe as an admin, it does not use the current folder as its starting folder, but instead goes under C:\WINDOWS\system32.
Therefore, it's impossible to find the test.appx file.
This should work:
var pathToAppx = Path.Combine(System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "test.msixbundle");
var psi = new ProcessStartInfo
{
UseShellExecute = true,
CreateNoWindow = false,
Arguments = $@"-NoExit &""Add-AppxProvisionedPackage -Online -PackagePath {pathToAppx} -SkipLicense;""",
WindowStyle = ProcessWindowStyle.Normal,
FileName = "powershell.exe",
Verb = "runas"
};
var proc = Process.Start(psi);
proc.WaitForExit();
In my example I used an msixbundle that I already had at my disposal, but it should not impact.
Upvotes: 1