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

230 lines
10 KiB
C#

// PackageManageHelper.cs
// P/Invoke wrapper for pkgmgr.dll (x86).
//
// 说明:此文件兼容 .NET Framework 4。
// - 将项目 Platform target 设置为 x86。
// - pkgmgr.dll 提供 PackageManagerFreeString 来释放它返回的字符串,请务必使用它释放由 pkgmgr 返回的 LPWSTR。
using System;
using System.Runtime.InteropServices;
namespace NativeWrappers
{
using DWORD = System.UInt32;
using HRESULT = System.Int32;
using BOOL = System.Int32;
using UINT64 = System.UInt64;
using System.Collections.Generic;
using System.Linq;
public static class PackageManageHelper
{
private const string DllName = "pkgmgr.dll";
private const CallingConvention CallConv = CallingConvention.Cdecl;
[UnmanagedFunctionPointer (CallConv)]
public delegate void PKGMRR_PROGRESSCALLBACK (DWORD dwProgress, IntPtr pCustom);
[UnmanagedFunctionPointer (CallConv)]
public delegate void PKGMGR_FINDENUMCALLBACK (IntPtr pNowItem, IntPtr pCustom);
[StructLayout (LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct REGISTER_PACKAGE_DEFENDENCIES
{
public DWORD dwSize;
public IntPtr alpDepUris; // tail array
}
[StructLayout (LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct FIND_PACKAGE_ID
{
public UINT64 qwVersion;
public ushort wProcessArchitecture;
[MarshalAs (UnmanagedType.ByValArray, SizeConst = 3)]
public ushort [] wPadding;
public IntPtr lpName;
public IntPtr lpFullName;
public IntPtr lpFamilyName;
public IntPtr lpPublisher;
public IntPtr lpPublisherId;
public IntPtr lpResourceId;
}
[StructLayout (LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct FIND_PACKAGE_PROPERTIES
{
public IntPtr lpDisplayName;
public IntPtr lpDescription;
public IntPtr lpPublisher;
public IntPtr lpLogoUri;
[MarshalAs (UnmanagedType.Bool)]
public bool bIsFramework;
[MarshalAs (UnmanagedType.Bool)]
public bool bIsResourcePackage;
[MarshalAs (UnmanagedType.Bool)]
public bool bIsBundle;
[MarshalAs (UnmanagedType.Bool)]
public bool bIsDevelopmentMode;
}
[StructLayout (LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct FIND_PACKAGE_INFO
{
public FIND_PACKAGE_ID piIdentity;
public FIND_PACKAGE_PROPERTIES piProperties;
public IntPtr lpInstallLocation;
public IntPtr lpUsers;
public IntPtr lpSIDs;
public DWORD dwDependencesSize;
public DWORD dwPadding;
public UINT64 ullBuffer;
}
// ========== Functions ==========
[DllImport (DllName, CallingConvention = CallConv, CharSet = CharSet.Unicode)]
public static extern HRESULT AddAppxPackageFromPath (string lpPkgPath, IntPtr alpDepUrlList, DWORD dwDeployOption, PKGMRR_PROGRESSCALLBACK pfCallback, IntPtr pCustom, out IntPtr pErrorCode, out IntPtr pDetailMsg);
[DllImport (DllName, CallingConvention = CallConv, CharSet = CharSet.Unicode)]
public static extern HRESULT AddAppxPackageFromURI (string lpFileUri, IntPtr alpDepFullNameList, DWORD dwDeployOption, PKGMRR_PROGRESSCALLBACK pfCallback, IntPtr pCustom, out IntPtr pErrorCode, out IntPtr pDetailMsg);
[DllImport (DllName, CallingConvention = CallConv, CharSet = CharSet.Unicode)]
public static extern HRESULT GetAppxPackages (PKGMGR_FINDENUMCALLBACK pfCallback, IntPtr pCustom, out IntPtr pErrorCode, out IntPtr pDetailMsg);
[DllImport (DllName, CallingConvention = CallConv, CharSet = CharSet.Unicode)]
public static extern HRESULT RemoveAppxPackage (string lpPkgFullName, PKGMRR_PROGRESSCALLBACK pfCallback, IntPtr pCustom, out IntPtr pErrorCode, out IntPtr pDetailMsg);
[DllImport (DllName, CallingConvention = CallConv, CharSet = CharSet.Unicode)]
public static extern HRESULT CleanupAppxPackage (string lpPkgName, string lpUserSID, PKGMRR_PROGRESSCALLBACK pfCallback, IntPtr pCustom, out IntPtr pErrorCode, out IntPtr pDetailMsg);
[DllImport (DllName, CallingConvention = CallConv, CharSet = CharSet.Unicode)]
public static extern HRESULT RegisterAppxPackageByPath (string lpManifestPath, IntPtr alpDependencyUriList, DWORD dwDeployOption, PKGMRR_PROGRESSCALLBACK pfCallback, IntPtr pCustom, out IntPtr pErrorCode, out IntPtr pDetailMsg);
[DllImport (DllName, CallingConvention = CallConv, CharSet = CharSet.Unicode)]
public static extern HRESULT RegisterAppxPackageByUri (string lpManifestUri, IntPtr alpDependencyUriList, DWORD dwDeployOption, PKGMRR_PROGRESSCALLBACK pfCallback, IntPtr pCustom, out IntPtr pErrorCode, out IntPtr pDetailMsg);
[DllImport (DllName, CallingConvention = CallConv, CharSet = CharSet.Unicode)]
public static extern HRESULT RegisterAppxPackageByFullName (string lpPackageFullName, IntPtr alpDepFullNameList, DWORD dwDeployOption, PKGMRR_PROGRESSCALLBACK pfCallback, IntPtr pCustom, out IntPtr pErrorCode, out IntPtr pDetailMsg);
[DllImport (DllName, CallingConvention = CallConv, CharSet = CharSet.Unicode)]
public static extern HRESULT SetAppxPackageStatus (string lpPackageFullName, DWORD dwStatus, out IntPtr pErrorCode, out IntPtr pDetailMsg);
[DllImport (DllName, CallingConvention = CallConv, CharSet = CharSet.Unicode)]
public static extern HRESULT StageAppxPackageFromURI (string lpFileUri, IntPtr alpDepUriList, DWORD dwDeployOption, PKGMRR_PROGRESSCALLBACK pfCallback, IntPtr pCustom, out IntPtr pErrorCode, out IntPtr pDetailMsg);
[DllImport (DllName, CallingConvention = CallConv, CharSet = CharSet.Unicode)]
public static extern HRESULT StageAppxPackageFromPath (string lpFileUri, IntPtr alpDepUriList, DWORD dwDeployOption, PKGMRR_PROGRESSCALLBACK pfCallback, IntPtr pCustom, out IntPtr pErrorCode, out IntPtr pDetailMsg);
[DllImport (DllName, CallingConvention = CallConv, CharSet = CharSet.Unicode)]
public static extern HRESULT StageAppxUserData (string lpPackageFullName, PKGMRR_PROGRESSCALLBACK pfCallback, IntPtr pCustom, out IntPtr pErrorCode, out IntPtr pDetailMsg);
[DllImport (DllName, CallingConvention = CallConv, CharSet = CharSet.Unicode)]
public static extern HRESULT UpdateAppxPackageFromPath (string lpPkgPath, IntPtr alpDepUrlList, DWORD dwDeployOption, PKGMRR_PROGRESSCALLBACK pfCallback, IntPtr pCustom, out IntPtr pErrorCode, out IntPtr pDetailMsg);
[DllImport (DllName, CallingConvention = CallConv, CharSet = CharSet.Unicode)]
public static extern HRESULT UpdateAppxPackageFromURI (string lpFileUri, IntPtr alpDepFullNameList, DWORD dwDeployOption, PKGMRR_PROGRESSCALLBACK pfCallback, IntPtr pCustom, out IntPtr pErrorCode, out IntPtr pDetailMsg);
[DllImport (DllName, CallingConvention = CallConv, CharSet = CharSet.Unicode)]
public static extern HRESULT FindAppxPackage (string lpPackageFullName, PKGMGR_FINDENUMCALLBACK pfCallback, IntPtr pCustom, out IntPtr pErrorCode, out IntPtr pDetailMsg);
[DllImport (DllName, CallingConvention = CallConv, CharSet = CharSet.Unicode)]
public static extern IntPtr GetPackageManagerLastErrorCode ();
[DllImport (DllName, CallingConvention = CallConv, CharSet = CharSet.Unicode)]
public static extern IntPtr GetPackageManagerLastErrorDetailMessage ();
[DllImport (DllName, CallingConvention = CallConv, CharSet = CharSet.Unicode)]
public static extern HRESULT ActivateAppxApplication (string lpAppUserId, out DWORD pdwProcessId);
[DllImport (DllName, CallingConvention = CallConv, CharSet = CharSet.Unicode)]
public static extern HRESULT FindAppxPackagesByIdentity (string lpPkgName, string lpPkgPublisher, PKGMGR_FINDENUMCALLBACK pfCallback, IntPtr pCustom, out IntPtr pErrorCode, out IntPtr pDetailMsg);
[DllImport (DllName, CallingConvention = CallConv, CharSet = CharSet.Unicode)]
public static extern HRESULT FindAppxPackagesByFamilyName (string lpPkgFamilyName, PKGMGR_FINDENUMCALLBACK pfCallback, IntPtr pCustom, out IntPtr pErrorCode, out IntPtr pDetailMsg);
[DllImport (DllName, CallingConvention = CallConv, CharSet = CharSet.Unicode)]
public static extern void PackageManagerFreeString (IntPtr lpString);
[DllImport (DllName, CallingConvention = CallConv, CharSet = CharSet.Unicode, ExactSpelling = true)]
public static extern HRESULT ActivateAppxApplicationWithArgs ([MarshalAs (UnmanagedType.LPWStr)] string lpAppUserId, [MarshalAs (UnmanagedType.LPWStr)] string lpArguments, out DWORD pdwProcessId);
// ========== 托管辅助 ==========
public static string PtrToStringAndFree (IntPtr nativePtr)
{
if (nativePtr == IntPtr.Zero) return null;
string s = Marshal.PtrToStringUni (nativePtr);
try
{
PackageManagerFreeString (nativePtr);
}
catch
{
}
return s;
}
public static FIND_PACKAGE_INFO PtrToFindPackageInfo (IntPtr pInfo)
{
if (pInfo == IntPtr.Zero) return default (FIND_PACKAGE_INFO);
object boxed = Marshal.PtrToStructure (pInfo, typeof (FIND_PACKAGE_INFO));
return (FIND_PACKAGE_INFO)boxed;
}
public static string GetDisplayNameFromFindPackageInfo (IntPtr pInfo)
{
FIND_PACKAGE_INFO info = PtrToFindPackageInfo (pInfo);
if (info.piProperties.lpDisplayName == IntPtr.Zero) return null;
return Marshal.PtrToStringUni (info.piProperties.lpDisplayName);
}
public static string [] ReadRegisterPackageDependencies (IntPtr pReg)
{
if (pReg == IntPtr.Zero) return new string [0];
uint size = (uint)Marshal.ReadInt32 (pReg);
if (size == 0) return new string [0];
string [] result = new string [size];
int offset = Marshal.SizeOf (typeof (uint));
for (int i = 0; i < size; i++)
{
IntPtr pStr = Marshal.ReadIntPtr (pReg, offset + i * IntPtr.Size);
result [i] = pStr == IntPtr.Zero ? null : Marshal.PtrToStringUni (pStr);
}
return result;
}
}
internal static class NativeUtil
{
public static string ToAbsoluteUriString (Uri uri)
{
if (uri == null) return null;
return uri.AbsoluteUri;
}
public static IntPtr AllocStringArray (IEnumerable<string> values)
{
if (values == null) return IntPtr.Zero;
var list = values.Where (s => !string.IsNullOrEmpty (s)).ToList ();
if (list.Count == 0) return IntPtr.Zero;
IntPtr mem = Marshal.AllocHGlobal (IntPtr.Size * list.Count);
for (int i = 0; i < list.Count; i++)
{
IntPtr pStr = Marshal.StringToHGlobalUni (list [i]);
Marshal.WriteIntPtr (mem, i * IntPtr.Size, pStr);
}
return mem;
}
public static void FreeStringArray (IntPtr array, int count)
{
if (array == IntPtr.Zero) return;
for (int i = 0; i < count; i++)
{
IntPtr p = Marshal.ReadIntPtr (array, i * IntPtr.Size);
if (p != IntPtr.Zero)
Marshal.FreeHGlobal (p);
}
Marshal.FreeHGlobal (array);
}
}
}