Files
App-Installer-For-Windows-8…/AppxPackage/PackageManager.cs

620 lines
21 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AppxPackage.Info;
using NativeWrappers;
using System.Runtime.InteropServices;
using DataUtils;
using System.Net;
using System.IO;
namespace AppxPackage
{
public enum DeploymentOptions
{
None = 0,
ForceAppShutdown = 0x00000001,
DevelopmentMode = 0x00000002,
InstallAllResources = 0x00000020
};
public enum PackageStatus
{
Normal = 0,
LicenseInvalid = 1,
Modified = 2,
Tampered = 3
};
public static class ImageUriToBase64
{
public static string ConvertToDataUri (string uriString)
{
if (string.IsNullOrEmpty (uriString)) throw new ArgumentNullException ("uriString");
Uri uri = new Uri (uriString, UriKind.Absolute);
byte [] data;
string mime;
if (uri.IsFile)
{
string path = uri.LocalPath;
data = File.ReadAllBytes (path);
mime = GetMimeFromExtension (Path.GetExtension (path));
}
else
{
using (WebClient wc = new WebClient ())
{
data = wc.DownloadData (uri);
mime = GetMimeFromExtension (Path.GetExtension (uri.AbsolutePath));
}
}
string base64 = Convert.ToBase64String (data);
return "data:" + mime + ";base64," + base64;
}
private static string GetMimeFromExtension (string ext)
{
if (string.IsNullOrEmpty (ext)) return "application/octet-stream";
switch (ext.ToLowerInvariant ())
{
case ".png": return "image/png";
case ".jpg":
case ".jpeg": return "image/jpeg";
case ".gif": return "image/gif";
case ".bmp": return "image/bmp";
case ".webp": return "image/webp";
case ".svg": return "image/svg+xml";
default: return "application/octet-stream";
}
}
}
[ComVisible (true)]
[ClassInterface (ClassInterfaceType.AutoDual)]
public class PMIdentity: IIdentity
{
private string name = "";
private string publisher = "";
private DataUtils.Version version = new DataUtils.Version ();
private IEnumerable<Architecture> archs;
private string familyName = "";
private string fullName = "";
private string resourceId = "";
private string publisherId = "";
public PMIdentity (string _name, string _publisher, DataUtils.Version _ver, IEnumerable<Architecture> _archs, string _family, string _full, string _resid, string _publisherId)
{
name = _name;
publisher = _publisher;
version = _ver;
archs = _archs ?? new List<Architecture> ();
familyName = _family;
fullName = _full;
resourceId = _resid;
publisherId = _publisherId;
}
public PMIdentity (PackageManageHelper.FIND_PACKAGE_ID pkgId) :
this (
Marshal.PtrToStringUni (pkgId.lpName),
Marshal.PtrToStringUni (pkgId.lpPublisher),
new DataUtils.Version (pkgId.qwVersion),
new Architecture [] { (Architecture)pkgId.wProcessArchitecture },
Marshal.PtrToStringUni (pkgId.lpFamilyName),
Marshal.PtrToStringUni (pkgId.lpFullName),
Marshal.PtrToStringUni (pkgId.lpResourceId),
Marshal.PtrToStringUni (pkgId.lpPublisherId)
)
{ }
public string FamilyName => familyName;
public string FullName => fullName;
public string Name => name;
public List<Architecture> ProcessArchitecture => archs.ToList ();
public string Publisher => publisher;
public string PublisherId => publisherId;
public string ResourceId => resourceId;
public DataUtils.Version Version => version;
}
[ComVisible (true)]
[ClassInterface (ClassInterfaceType.AutoDual)]
public class PMProperties: IProperties
{
private string desc = "";
private string displayName = "";
private bool framework = false;
private string logo = "";
private string publisher = "";
private bool isres = false;
public PMProperties (string _name, string _pub, string _desc, string _logo, bool _fw, bool _res)
{
desc = _desc;
displayName = _name;
framework = _fw;
logo = _logo;
publisher = _pub;
isres = _res;
}
public PMProperties (PackageManageHelper.FIND_PACKAGE_PROPERTIES prop) :
this (
Marshal.PtrToStringUni (prop.lpDisplayName),
Marshal.PtrToStringUni (prop.lpPublisher),
Marshal.PtrToStringUni (prop.lpDescription),
Marshal.PtrToStringUni (prop.lpLogoUri),
prop.bIsFramework,
prop.bIsResourcePackage
)
{ }
public string Description => desc;
public string DisplayName => displayName;
public bool Framework => framework;
public string Logo => logo;
public string LogoBase64
{
get
{
try { return ImageUriToBase64.ConvertToDataUri (Logo); }
catch (Exception) { }
return "";
}
}
public string Publisher => publisher;
public bool ResourcePackage => isres;
}
[ComVisible (true)]
[ClassInterface (ClassInterfaceType.AutoDual)]
public class PMPackageInfo
{
public PMIdentity Identity { get; private set; }
public PMProperties Properties { get; private set; }
public bool IsBundle { get; private set; }
public bool DevelopmentMode { get; private set; }
public string InstallLocation { get; private set; }
public List<string> Users { get; private set; }
public List<string> SIDs { get; private set; }
public PMPackageInfo (PackageManageHelper.FIND_PACKAGE_INFO info)
{
Identity = new PMIdentity (info.piIdentity);
Properties = new PMProperties (info.piProperties);
IsBundle = info.piProperties.bIsBundle;
DevelopmentMode = info.piProperties.bIsDevelopmentMode;
InstallLocation = Marshal.PtrToStringUni (info.lpInstallLocation);
Users = (Marshal.PtrToStringUni (info.lpUsers) ?? "").Split (';').ToList ();
SIDs = (Marshal.PtrToStringUni (info.lpSIDs) ?? "").Split (';').ToList ();
}
}
[ComVisible (true)]
[ClassInterface (ClassInterfaceType.AutoDual)]
public static class PackageManager
{
private static DataUtils._I_HResult FromNative (int hr,IntPtr pErrorCode,IntPtr pDetailMsg)
{
string errCode = null;
string detail = null;
try
{
if (pErrorCode != IntPtr.Zero) errCode = Marshal.PtrToStringUni (pErrorCode);
if (pDetailMsg != IntPtr.Zero) detail = Marshal.PtrToStringUni (pDetailMsg);
}
finally
{
if (pErrorCode != IntPtr.Zero) PackageManageHelper.PackageManagerFreeString (pErrorCode);
if (pDetailMsg != IntPtr.Zero) PackageManageHelper.PackageManagerFreeString (pDetailMsg);
}
return new DataUtils._I_HResult (hr, errCode, detail);
}
public delegate void PackageProgressCallback (uint progress);
internal sealed class ProgressCallbackHolder
{
private readonly PackageProgressCallback _callback;
public ProgressCallbackHolder (PackageProgressCallback cb)
{
_callback = cb;
Native = new PackageManageHelper.PKGMRR_PROGRESSCALLBACK (OnNative);
}
public PackageManageHelper.PKGMRR_PROGRESSCALLBACK Native { get; private set; }
private void OnNative (uint progress, IntPtr custom)
{
if (_callback != null)
_callback (progress);
}
}
internal sealed class ResultCallbackHolder
{
public readonly List<PMPackageInfo> RetList = new List<PMPackageInfo> ();
public PackageManageHelper.PKGMGR_FINDENUMCALLBACK Callback;
public ResultCallbackHolder ()
{
Callback = OnResult;
}
private void OnResult (
IntPtr nativeInfo,
IntPtr pCustom)
{
RetList.Add (new PMPackageInfo (PackageManageHelper.PtrToFindPackageInfo (nativeInfo)));
}
}
public static DataUtils._I_HResult AddPackage (Uri fileUri, IEnumerable<Uri> depUris, DeploymentOptions options, PackageProgressCallback progress = null)
{
if (fileUri == null) throw new ArgumentNullException ("Required File URI");
IntPtr depArray = IntPtr.Zero;
IntPtr pErrCode = IntPtr.Zero;
IntPtr pDetail = IntPtr.Zero;
var depList = depUris == null ? new List<string> () : depUris.Select (u => u.AbsoluteUri).ToList ();
ProgressCallbackHolder holder = null;
try
{
depArray = NativeUtil.AllocStringArray (depList);
PackageManageHelper.PKGMRR_PROGRESSCALLBACK nativeCb = null;
if (progress != null)
{
holder = new ProgressCallbackHolder (progress);
nativeCb = holder.Native;
}
int hr = PackageManageHelper.AddAppxPackageFromURI (fileUri.AbsoluteUri, depArray, (uint)options, nativeCb, IntPtr.Zero, out pErrCode, out pDetail);
return FromNative (hr, pErrCode, pDetail);
}
finally
{
NativeUtil.FreeStringArray (depArray, depList.Count);
GC.KeepAlive (holder);
}
}
public static DataUtils._I_HResult AddPackage (string filePath, IEnumerable<string> depUris, DeploymentOptions options, PackageProgressCallback progress = null)
{
IntPtr depArray = IntPtr.Zero;
IntPtr pErrCode = IntPtr.Zero;
IntPtr pDetail = IntPtr.Zero;
var depList = depUris == null ? new List<string> () : depUris.ToList ();
ProgressCallbackHolder holder = null;
try
{
depArray = NativeUtil.AllocStringArray (depList);
PackageManageHelper.PKGMRR_PROGRESSCALLBACK nativeCb = null;
if (progress != null)
{
holder = new ProgressCallbackHolder (progress);
nativeCb = holder.Native;
}
int hr = PackageManageHelper.AddAppxPackageFromPath (filePath, depArray, (uint)options, nativeCb, IntPtr.Zero, out pErrCode, out pDetail);
return FromNative (hr, pErrCode, pDetail);
}
finally
{
NativeUtil.FreeStringArray (depArray, depList.Count);
GC.KeepAlive (holder);
}
}
public static Tuple <DataUtils._I_HResult, List <PMPackageInfo>> GetPackages ()
{
IntPtr depArray = IntPtr.Zero;
IntPtr pErrCode = IntPtr.Zero;
IntPtr pDetail = IntPtr.Zero;
ResultCallbackHolder callback = null;
try
{
callback = new ResultCallbackHolder ();
int hr = PackageManageHelper.GetAppxPackages (callback.Callback, IntPtr.Zero, out pErrCode, out pDetail);
return Tuple.Create (FromNative (hr, pErrCode, pDetail), callback.RetList);
}
finally
{
GC.KeepAlive (callback);
}
}
public static DataUtils._I_HResult RemovePackage (string packageFullName, PackageProgressCallback progress = null)
{
IntPtr depArray = IntPtr.Zero;
IntPtr pErrCode = IntPtr.Zero;
IntPtr pDetail = IntPtr.Zero;
ProgressCallbackHolder holder = null;
try
{
PackageManageHelper.PKGMRR_PROGRESSCALLBACK nativeCb = null;
if (progress != null)
{
holder = new ProgressCallbackHolder (progress);
nativeCb = holder.Native;
}
int hr = PackageManageHelper.RemoveAppxPackage (packageFullName, nativeCb, IntPtr.Zero, out pErrCode, out pDetail);
return FromNative (hr, pErrCode, pDetail);
}
finally
{
GC.KeepAlive (holder);
}
}
public static DataUtils._I_HResult ClearupPackage (string packageName, string userSID, PackageProgressCallback progress = null)
{
IntPtr depArray = IntPtr.Zero;
IntPtr pErrCode = IntPtr.Zero;
IntPtr pDetail = IntPtr.Zero;
ProgressCallbackHolder holder = null;
try
{
PackageManageHelper.PKGMRR_PROGRESSCALLBACK nativeCb = null;
if (progress != null)
{
holder = new ProgressCallbackHolder (progress);
nativeCb = holder.Native;
}
int hr = PackageManageHelper.CleanupAppxPackage (packageName, userSID, nativeCb, IntPtr.Zero, out pErrCode, out pDetail);
return FromNative (hr, pErrCode, pDetail);
}
finally
{
GC.KeepAlive (holder);
}
}
public static DataUtils._I_HResult RegisterPackage (Uri manifestUri, IEnumerable<Uri> depUris, DeploymentOptions options, PackageProgressCallback progress = null)
{
if (manifestUri == null) throw new ArgumentNullException ("Required File URI");
IntPtr depArray = IntPtr.Zero;
IntPtr pErrCode = IntPtr.Zero;
IntPtr pDetail = IntPtr.Zero;
var depList = depUris == null ? new List<string> () : depUris.Select (u => u.AbsoluteUri).ToList ();
ProgressCallbackHolder holder = null;
try
{
depArray = NativeUtil.AllocStringArray (depList);
PackageManageHelper.PKGMRR_PROGRESSCALLBACK nativeCb = null;
if (progress != null)
{
holder = new ProgressCallbackHolder (progress);
nativeCb = holder.Native;
}
int hr = PackageManageHelper.RegisterAppxPackageByUri (manifestUri.AbsoluteUri, depArray, (uint)options, nativeCb, IntPtr.Zero, out pErrCode, out pDetail);
return FromNative (hr, pErrCode, pDetail);
}
finally
{
NativeUtil.FreeStringArray (depArray, depList.Count);
GC.KeepAlive (holder);
}
}
public static DataUtils._I_HResult RegisterPackage (string manifestPath, IEnumerable<string> depUris, DeploymentOptions options, PackageProgressCallback progress = null)
{
IntPtr depArray = IntPtr.Zero;
IntPtr pErrCode = IntPtr.Zero;
IntPtr pDetail = IntPtr.Zero;
var depList = depUris == null ? new List<string> () : depUris.ToList ();
ProgressCallbackHolder holder = null;
try
{
depArray = NativeUtil.AllocStringArray (depList);
PackageManageHelper.PKGMRR_PROGRESSCALLBACK nativeCb = null;
if (progress != null)
{
holder = new ProgressCallbackHolder (progress);
nativeCb = holder.Native;
}
int hr = PackageManageHelper.RegisterAppxPackageByUri (manifestPath, depArray, (uint)options, nativeCb, IntPtr.Zero, out pErrCode, out pDetail);
return FromNative (hr, pErrCode, pDetail);
}
finally
{
NativeUtil.FreeStringArray (depArray, depList.Count);
GC.KeepAlive (holder);
}
}
public static DataUtils._I_HResult RegisterPackageByFullName (string pkgFullName, IEnumerable<string> depFullNames, DeploymentOptions options, PackageProgressCallback progress = null)
{
IntPtr depArray = IntPtr.Zero;
IntPtr pErrCode = IntPtr.Zero;
IntPtr pDetail = IntPtr.Zero;
var depList = depFullNames == null ? new List<string> () : depFullNames.ToList ();
ProgressCallbackHolder holder = null;
try
{
depArray = NativeUtil.AllocStringArray (depList);
PackageManageHelper.PKGMRR_PROGRESSCALLBACK nativeCb = null;
if (progress != null)
{
holder = new ProgressCallbackHolder (progress);
nativeCb = holder.Native;
}
int hr = PackageManageHelper.RegisterAppxPackageByFullName (pkgFullName, depArray, (uint)options, nativeCb, IntPtr.Zero, out pErrCode, out pDetail);
return FromNative (hr, pErrCode, pDetail);
}
finally
{
NativeUtil.FreeStringArray (depArray, depList.Count);
GC.KeepAlive (holder);
}
}
public static DataUtils._I_HResult SetPackageStatus (string packageFullName, PackageStatus status)
{
IntPtr depArray = IntPtr.Zero;
IntPtr pErrCode = IntPtr.Zero;
IntPtr pDetail = IntPtr.Zero;
try
{
int hr = PackageManageHelper.SetAppxPackageStatus (packageFullName, (uint)status, out pErrCode, out pDetail);
return FromNative (hr, pErrCode, pDetail);
}
finally { }
}
public static DataUtils._I_HResult StagePackage (Uri fileUri, IEnumerable<Uri> depUris, DeploymentOptions options, PackageProgressCallback progress = null)
{
if (fileUri == null) throw new ArgumentNullException ("Required File URI");
IntPtr depArray = IntPtr.Zero;
IntPtr pErrCode = IntPtr.Zero;
IntPtr pDetail = IntPtr.Zero;
var depList = depUris == null ? new List<string> () : depUris.Select (u => u.AbsoluteUri).ToList ();
ProgressCallbackHolder holder = null;
try
{
depArray = NativeUtil.AllocStringArray (depList);
PackageManageHelper.PKGMRR_PROGRESSCALLBACK nativeCb = null;
if (progress != null)
{
holder = new ProgressCallbackHolder (progress);
nativeCb = holder.Native;
}
int hr = PackageManageHelper.StageAppxPackageFromURI (fileUri.AbsoluteUri, depArray, (uint)options, nativeCb, IntPtr.Zero, out pErrCode, out pDetail);
return FromNative (hr, pErrCode, pDetail);
}
finally
{
NativeUtil.FreeStringArray (depArray, depList.Count);
GC.KeepAlive (holder);
}
}
public static DataUtils._I_HResult StagePackage (string filePath, IEnumerable<string> depUris, DeploymentOptions options, PackageProgressCallback progress = null)
{
IntPtr depArray = IntPtr.Zero;
IntPtr pErrCode = IntPtr.Zero;
IntPtr pDetail = IntPtr.Zero;
var depList = depUris == null ? new List<string> () : depUris.ToList ();
ProgressCallbackHolder holder = null;
try
{
depArray = NativeUtil.AllocStringArray (depList);
PackageManageHelper.PKGMRR_PROGRESSCALLBACK nativeCb = null;
if (progress != null)
{
holder = new ProgressCallbackHolder (progress);
nativeCb = holder.Native;
}
int hr = PackageManageHelper.StageAppxPackageFromPath (filePath, depArray, (uint)options, nativeCb, IntPtr.Zero, out pErrCode, out pDetail);
return FromNative (hr, pErrCode, pDetail);
}
finally
{
NativeUtil.FreeStringArray (depArray, depList.Count);
GC.KeepAlive (holder);
}
}
public static DataUtils._I_HResult StageUserData (string packageFullName, PackageProgressCallback progress = null)
{
IntPtr depArray = IntPtr.Zero;
IntPtr pErrCode = IntPtr.Zero;
IntPtr pDetail = IntPtr.Zero;
ProgressCallbackHolder holder = null;
try
{
PackageManageHelper.PKGMRR_PROGRESSCALLBACK nativeCb = null;
if (progress != null)
{
holder = new ProgressCallbackHolder (progress);
nativeCb = holder.Native;
}
int hr = PackageManageHelper.StageAppxUserData (packageFullName, nativeCb, IntPtr.Zero, out pErrCode, out pDetail);
return FromNative (hr, pErrCode, pDetail);
}
finally
{
GC.KeepAlive (holder);
}
}
public static DataUtils._I_HResult UpdatePackage (Uri fileUri, IEnumerable<Uri> depUris, DeploymentOptions options, PackageProgressCallback progress = null)
{
if (fileUri == null) throw new ArgumentNullException ("Required File URI");
IntPtr depArray = IntPtr.Zero;
IntPtr pErrCode = IntPtr.Zero;
IntPtr pDetail = IntPtr.Zero;
var depList = depUris == null ? new List<string> () : depUris.Select (u => u.AbsoluteUri).ToList ();
ProgressCallbackHolder holder = null;
try
{
depArray = NativeUtil.AllocStringArray (depList);
PackageManageHelper.PKGMRR_PROGRESSCALLBACK nativeCb = null;
if (progress != null)
{
holder = new ProgressCallbackHolder (progress);
nativeCb = holder.Native;
}
int hr = PackageManageHelper.UpdateAppxPackageFromURI (fileUri.AbsoluteUri, depArray, (uint)options, nativeCb, IntPtr.Zero, out pErrCode, out pDetail);
return FromNative (hr, pErrCode, pDetail);
}
finally
{
NativeUtil.FreeStringArray (depArray, depList.Count);
GC.KeepAlive (holder);
}
}
public static DataUtils._I_HResult UpdatePackage (string filePath, IEnumerable<string> depUris, DeploymentOptions options, PackageProgressCallback progress = null)
{
IntPtr depArray = IntPtr.Zero;
IntPtr pErrCode = IntPtr.Zero;
IntPtr pDetail = IntPtr.Zero;
var depList = depUris == null ? new List<string> () : depUris.ToList ();
ProgressCallbackHolder holder = null;
try
{
depArray = NativeUtil.AllocStringArray (depList);
PackageManageHelper.PKGMRR_PROGRESSCALLBACK nativeCb = null;
if (progress != null)
{
holder = new ProgressCallbackHolder (progress);
nativeCb = holder.Native;
}
int hr = PackageManageHelper.UpdateAppxPackageFromPath (filePath, depArray, (uint)options, nativeCb, IntPtr.Zero, out pErrCode, out pDetail);
return FromNative (hr, pErrCode, pDetail);
}
finally
{
NativeUtil.FreeStringArray (depArray, depList.Count);
GC.KeepAlive (holder);
}
}
public static Tuple<DataUtils._I_HResult, List<PMPackageInfo>> FindPackage (string packageName, string packagePublisher)
{
IntPtr depArray = IntPtr.Zero;
IntPtr pErrCode = IntPtr.Zero;
IntPtr pDetail = IntPtr.Zero;
ResultCallbackHolder callback = null;
try
{
callback = new ResultCallbackHolder ();
int hr = PackageManageHelper.FindAppxPackagesByIdentity (packageName, packagePublisher, callback.Callback, IntPtr.Zero, out pErrCode, out pDetail);
return Tuple.Create (FromNative (hr, pErrCode, pDetail), callback.RetList);
}
finally
{
GC.KeepAlive (callback);
}
}
public static Tuple<DataUtils._I_HResult, List<PMPackageInfo>> FindPackage (string packageFamilyName)
{
IntPtr depArray = IntPtr.Zero;
IntPtr pErrCode = IntPtr.Zero;
IntPtr pDetail = IntPtr.Zero;
ResultCallbackHolder callback = null;
try
{
callback = new ResultCallbackHolder ();
int hr = PackageManageHelper.FindAppxPackagesByFamilyName (packageFamilyName, callback.Callback, IntPtr.Zero, out pErrCode, out pDetail);
return Tuple.Create (FromNative (hr, pErrCode, pDetail), callback.RetList);
}
finally
{
GC.KeepAlive (callback);
}
}
public static Tuple<DataUtils._I_HResult, List<PMPackageInfo>> FindPackageByFullName (string packageFullName)
{
IntPtr depArray = IntPtr.Zero;
IntPtr pErrCode = IntPtr.Zero;
IntPtr pDetail = IntPtr.Zero;
ResultCallbackHolder callback = null;
try
{
callback = new ResultCallbackHolder ();
int hr = PackageManageHelper.FindAppxPackage (packageFullName, callback.Callback, IntPtr.Zero, out pErrCode, out pDetail);
return Tuple.Create (FromNative (hr, pErrCode, pDetail), callback.RetList);
}
finally
{
GC.KeepAlive (callback);
}
}
public static DataUtils._I_HResult ActiveApp (string appUserId)
{
uint processId;
var hr = PackageManageHelper.ActivateAppxApplication (appUserId, out processId);
return new DataUtils._I_HResult (hr);
}
public static DataUtils._I_HResult ActiveApp (string appUserId, string cmdargs)
{
uint processId;
var hr = PackageManageHelper.ActivateAppxApplicationWithArgs (appUserId, cmdargs, out processId);
return new DataUtils._I_HResult (hr);
}
}
}