mirror of
https://github.com/modernw/App-Installer-For-Windows-8.x-Reset.git
synced 2026-06-20 14:10:59 +10:00
Coding for Package Manager.
This commit is contained in:
@@ -48,6 +48,10 @@
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Newtonsoft.Json.13.0.4\lib\net40\Newtonsoft.Json.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
@@ -57,12 +61,24 @@
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="DataInterface.cs" />
|
||||
<Compile Include="PackageManager.cs" />
|
||||
<Compile Include="PackageReader.cs" />
|
||||
<Compile Include="PkgMgrNative.cs" />
|
||||
<Compile Include="PkgReadNative.cs" />
|
||||
<Compile Include="PriFileNative.cs" />
|
||||
<Compile Include="PriReader.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\DataUtils\DataUtils.csproj">
|
||||
<Project>{ffd3fd52-37a8-4f43-883c-de8d996cb0e0}</Project>
|
||||
<Name>DataUtils</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
||||
@@ -0,0 +1,232 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.ComponentModel;
|
||||
namespace AppxPackage
|
||||
{
|
||||
[Serializable]
|
||||
public sealed class Ref<T>
|
||||
{
|
||||
private T _value;
|
||||
public Ref ()
|
||||
{
|
||||
_value = default (T);
|
||||
}
|
||||
public Ref (T value)
|
||||
{
|
||||
_value = value;
|
||||
}
|
||||
/// <summary>
|
||||
/// 模拟 & 引用访问
|
||||
/// </summary>
|
||||
public T Value
|
||||
{
|
||||
get { return _value; }
|
||||
set { _value = value; }
|
||||
}
|
||||
/// <summary>
|
||||
/// 直接赋值(像 *ref = value)
|
||||
/// </summary>
|
||||
public void Set (T value)
|
||||
{
|
||||
_value = value;
|
||||
}
|
||||
/// <summary>
|
||||
/// 取值(像 value = *ref)
|
||||
/// </summary>
|
||||
public T Get ()
|
||||
{
|
||||
return _value;
|
||||
}
|
||||
public override string ToString ()
|
||||
{
|
||||
return _value == null ? string.Empty : _value.ToString ();
|
||||
}
|
||||
public override int GetHashCode ()
|
||||
{
|
||||
return _value == null ? 0 : _value.GetHashCode ();
|
||||
}
|
||||
public override bool Equals (object obj)
|
||||
{
|
||||
if (ReferenceEquals (this, obj)) return true;
|
||||
if (obj is Ref<T>) return Equals (_value, ((Ref<T>)obj)._value);
|
||||
return Equals (_value, obj);
|
||||
}
|
||||
public static implicit operator T (Ref<T> r)
|
||||
{
|
||||
return r == null ? default (T) : r._value;
|
||||
}
|
||||
public static implicit operator Ref<T>(T value)
|
||||
{
|
||||
return new Ref<T> (value);
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace AppxPackage.Info
|
||||
{
|
||||
public enum Architecture
|
||||
{
|
||||
x86 = 0,
|
||||
ARM = 5,
|
||||
x64 = 9,
|
||||
Neutral = 11,
|
||||
ARM64 = 12,
|
||||
Unknown = ushort.MaxValue
|
||||
};
|
||||
public enum PackageType
|
||||
{
|
||||
Unknown = 0,
|
||||
Appx = 1,
|
||||
Bundle = 2
|
||||
};
|
||||
public enum PackageRole
|
||||
{
|
||||
Unknown = 0,
|
||||
Application = 1,
|
||||
Framework = 2,
|
||||
Resource = 3
|
||||
};
|
||||
public interface IIdentity
|
||||
{
|
||||
string Name { get; }
|
||||
string Publisher { get; }
|
||||
string FamilyName { get; }
|
||||
string FullName { get; }
|
||||
string ResourceId { get; }
|
||||
DataUtils.Version Version { get; }
|
||||
List<Architecture> ProcessArchitecture { get; }
|
||||
}
|
||||
public interface IProperties
|
||||
{
|
||||
string DisplayName { get; }
|
||||
string Description { get; }
|
||||
string Publisher { get; }
|
||||
string Logo { get; }
|
||||
string LogoBase64 { get; }
|
||||
bool Framework { get; }
|
||||
bool ResourcePackage { get; }
|
||||
}
|
||||
public interface ICapabilities
|
||||
{
|
||||
List<string> Capabilities { get; }
|
||||
List<string> DeviceCapabilities { get; }
|
||||
}
|
||||
public class DependencyInfo
|
||||
{
|
||||
public string Name { get; private set; } = "";
|
||||
public string Publisher { get; private set; } = "";
|
||||
public DataUtils.Version Version { get; private set; } = new DataUtils.Version ();
|
||||
public DependencyInfo (string name, string publisher, DataUtils.Version ver)
|
||||
{
|
||||
Name = name;
|
||||
Publisher = publisher;
|
||||
Version = ver;
|
||||
}
|
||||
public DependencyInfo (string name, DataUtils.Version ver): this (name, "", ver) { }
|
||||
public DependencyInfo () { }
|
||||
}
|
||||
public enum DXFeatureLevel
|
||||
{
|
||||
Unspecified = 0,
|
||||
Level9 = 0x1,
|
||||
Level10 = 0x2,
|
||||
Level11 = 0x4,
|
||||
Level12 = 0x8
|
||||
}
|
||||
public interface IResources
|
||||
{
|
||||
List <string> Languages { get; }
|
||||
List <int> Languages_LCID { get; }
|
||||
List <int> Scales { get; }
|
||||
List <DXFeatureLevel> DXFeatures { get; }
|
||||
}
|
||||
public interface IPrerequisites
|
||||
{
|
||||
DataUtils.Version OSMinVersion { get; }
|
||||
DataUtils.Version OSMaxVersionTested { get; }
|
||||
string OSMinVersionDescription { get; }
|
||||
string OSMaxVersionDescription { get; }
|
||||
}
|
||||
[Serializable]
|
||||
[StructLayout (LayoutKind.Sequential)]
|
||||
public struct HRESULT: IEquatable<HRESULT>
|
||||
{
|
||||
private readonly int _value;
|
||||
public HRESULT (int value)
|
||||
{
|
||||
_value = value;
|
||||
}
|
||||
public int Value
|
||||
{
|
||||
get { return _value; }
|
||||
}
|
||||
public bool Succeeded
|
||||
{
|
||||
get { return _value >= 0; }
|
||||
}
|
||||
public bool Failed
|
||||
{
|
||||
get { return _value < 0; }
|
||||
}
|
||||
public void ThrowIfFailed ()
|
||||
{
|
||||
if (Failed)
|
||||
Marshal.ThrowExceptionForHR (_value);
|
||||
}
|
||||
public Exception GetException ()
|
||||
{
|
||||
return Failed ? Marshal.GetExceptionForHR (_value) : null;
|
||||
}
|
||||
public override string ToString ()
|
||||
{
|
||||
return string.Format ("HRESULT 0x{0:X8}", _value);
|
||||
}
|
||||
public override int GetHashCode ()
|
||||
{
|
||||
return _value;
|
||||
}
|
||||
public override bool Equals (object obj)
|
||||
{
|
||||
if (obj is HRESULT) return Equals ((HRESULT)obj);
|
||||
return false;
|
||||
}
|
||||
public bool Equals (HRESULT other)
|
||||
{
|
||||
return _value == other._value;
|
||||
}
|
||||
public static implicit operator int (HRESULT hr)
|
||||
{
|
||||
return hr._value;
|
||||
}
|
||||
public static implicit operator HRESULT (int value)
|
||||
{
|
||||
return new HRESULT (value);
|
||||
}
|
||||
public static bool operator == (HRESULT a, HRESULT b)
|
||||
{
|
||||
return a._value == b._value;
|
||||
}
|
||||
public static bool operator != (HRESULT a, HRESULT b)
|
||||
{
|
||||
return a._value != b._value;
|
||||
}
|
||||
public static bool operator >= (HRESULT a, int value)
|
||||
{
|
||||
return a._value >= value;
|
||||
}
|
||||
public static bool operator <= (HRESULT a, int value)
|
||||
{
|
||||
return a._value <= value;
|
||||
}
|
||||
public static bool operator > (HRESULT a, int value)
|
||||
{
|
||||
return a._value > value;
|
||||
}
|
||||
public static bool operator < (HRESULT a, int value)
|
||||
{
|
||||
return a._value < value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,603 @@
|
||||
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 = "";
|
||||
public PMIdentity (string _name, string _publisher, DataUtils.Version _ver, IEnumerable<Architecture> _archs, string _family, string _full, string _resid)
|
||||
{
|
||||
name = _name;
|
||||
publisher = _publisher;
|
||||
version = _ver;
|
||||
archs = _archs ?? new List<Architecture> ();
|
||||
familyName = _family;
|
||||
fullName = _full;
|
||||
resourceId = _resid;
|
||||
}
|
||||
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)
|
||||
)
|
||||
{ }
|
||||
public string FamilyName => familyName;
|
||||
public string FullName => fullName;
|
||||
public string Name => name;
|
||||
public List<Architecture> ProcessArchitecture => archs.ToList ();
|
||||
public string Publisher => publisher;
|
||||
public string ResourceId => resourceId;
|
||||
DataUtils.Version IIdentity.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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -14,6 +14,8 @@ namespace NativeWrappers
|
||||
using HRESULT = System.Int32;
|
||||
using BOOL = System.Int32;
|
||||
using UINT64 = System.UInt64;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
public static class PackageManageHelper
|
||||
{
|
||||
@@ -186,4 +188,41 @@ namespace NativeWrappers
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -218,6 +218,12 @@ namespace NativeWrappers
|
||||
}
|
||||
return s;
|
||||
}
|
||||
public static string GetStringFromPkgRead (IntPtr nativePtr)
|
||||
{
|
||||
if (nativePtr == IntPtr.Zero) return null;
|
||||
string s = Marshal.PtrToStringUni (nativePtr);
|
||||
return s;
|
||||
}
|
||||
|
||||
public static string PtrToStringNoFree (IntPtr nativePtr)
|
||||
{
|
||||
|
||||
@@ -32,10 +32,10 @@ namespace AppxPackage
|
||||
public static extern string PriFileGetLastError ();
|
||||
|
||||
[DllImport (DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void FindPriStringResource (PCSPRIFILE pFilePri, ref LPCWSTRLIST hUriList);
|
||||
public static extern void FindPriStringResource (PCSPRIFILE pFilePri, IntPtr hUriList);
|
||||
|
||||
[DllImport (DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void FindPriPathResource (PCSPRIFILE pFilePri, ref LPCWSTRLIST hPathList);
|
||||
public static extern void FindPriPathResource (PCSPRIFILE pFilePri, IntPtr hPathList);
|
||||
|
||||
[DllImport (DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void ClearPriCacheData ();
|
||||
@@ -44,7 +44,7 @@ namespace AppxPackage
|
||||
public static extern IntPtr GetPriResource (PCSPRIFILE pFilePri, [MarshalAs (UnmanagedType.LPWStr)] string lpswResId);
|
||||
|
||||
[DllImport (DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void FindPriResource (PCSPRIFILE pFilePri, ref LPCWSTRLIST hUriList);
|
||||
public static extern void FindPriResource (PCSPRIFILE pFilePri, IntPtr hUriList);
|
||||
|
||||
[DllImport (DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
[return: MarshalAs (UnmanagedType.Bool)]
|
||||
@@ -64,14 +64,42 @@ namespace AppxPackage
|
||||
Marshal.FreeHGlobal (ptr); // 如果 DLL 返回的内存要求 free
|
||||
return s;
|
||||
}
|
||||
|
||||
[DllImport (DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void FreePriString (IntPtr p);
|
||||
}
|
||||
[StructLayout (LayoutKind.Sequential)]
|
||||
public struct LPCWSTRLIST
|
||||
public static class LpcwstrListHelper
|
||||
{
|
||||
public uint dwLength; // DWORD
|
||||
[MarshalAs (UnmanagedType.ByValArray, SizeConst = 1)]
|
||||
public IntPtr [] aswArray; // LPCWSTR*,数组
|
||||
}
|
||||
public static IntPtr Create (IEnumerable<string> strings)
|
||||
{
|
||||
if (strings == null) return IntPtr.Zero;
|
||||
var list = new List<string> (strings);
|
||||
int count = list.Count;
|
||||
int size = sizeof (uint) + IntPtr.Size * count;
|
||||
IntPtr pMem = Marshal.AllocHGlobal (size);
|
||||
Marshal.WriteInt32 (pMem, count);
|
||||
IntPtr pArray = pMem + sizeof (uint);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
IntPtr pStr = Marshal.StringToHGlobalUni (list [i]);
|
||||
Marshal.WriteIntPtr (pArray, i * IntPtr.Size, pStr);
|
||||
}
|
||||
return pMem;
|
||||
}
|
||||
public static void Destroy (IntPtr pList)
|
||||
{
|
||||
if (pList == IntPtr.Zero)
|
||||
return;
|
||||
|
||||
int count = Marshal.ReadInt32 (pList);
|
||||
IntPtr pArray = pList + sizeof (uint);
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
IntPtr pStr = Marshal.ReadIntPtr (pArray, i * IntPtr.Size);
|
||||
if (pStr != IntPtr.Zero)
|
||||
Marshal.FreeHGlobal (pStr);
|
||||
}
|
||||
Marshal.FreeHGlobal (pList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+241
-2
@@ -2,11 +2,250 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices.ComTypes;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace AppxPackage
|
||||
{
|
||||
class PriReader
|
||||
public class PriReader: IDisposable
|
||||
{
|
||||
|
||||
private IntPtr m_hPriFile = IntPtr.Zero;
|
||||
public bool Valid { get { return m_hPriFile != IntPtr.Zero; } }
|
||||
public void Dispose ()
|
||||
{
|
||||
if (Valid)
|
||||
{
|
||||
PriFileHelper.DestroyPriFileInstance (m_hPriFile);
|
||||
m_hPriFile = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
~PriReader () { Dispose (); }
|
||||
public bool Create (IStream isfile)
|
||||
{
|
||||
try
|
||||
{
|
||||
Dispose ();
|
||||
if (isfile == null) return false;
|
||||
var pStream = Marshal.GetComInterfaceForObject (isfile, typeof (IStream));
|
||||
m_hPriFile = PriFileHelper.CreatePriFileInstanceFromStream (pStream);
|
||||
}
|
||||
catch (Exception) { m_hPriFile = IntPtr.Zero; }
|
||||
return Valid;
|
||||
}
|
||||
public bool Create (IntPtr pStream)
|
||||
{
|
||||
try
|
||||
{
|
||||
Dispose ();
|
||||
if (pStream == IntPtr.Zero) return false;
|
||||
m_hPriFile = PriFileHelper.CreatePriFileInstanceFromStream (pStream);
|
||||
}
|
||||
catch (Exception) { m_hPriFile = IntPtr.Zero; }
|
||||
return Valid;
|
||||
}
|
||||
public bool Create ([MarshalAs (UnmanagedType.LPWStr)] string filePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
Dispose ();
|
||||
if (string.IsNullOrWhiteSpace (filePath)) return false;
|
||||
m_hPriFile = PriFileHelper.CreatePriFileInstanceFromPath (filePath);
|
||||
}
|
||||
catch (Exception) { m_hPriFile = IntPtr.Zero; }
|
||||
return Valid;
|
||||
}
|
||||
public PriReader (IStream isfile) { Create (isfile); }
|
||||
public PriReader (IntPtr pStream) { Create (pStream); }
|
||||
public PriReader ([MarshalAs (UnmanagedType.LPWStr)] string fileName) { Create (fileName); }
|
||||
public PriReader () { }
|
||||
public void AddSearch (IEnumerable <string> arr)
|
||||
{
|
||||
IntPtr buf = IntPtr.Zero;
|
||||
try
|
||||
{
|
||||
if (arr == null) return;
|
||||
buf = LpcwstrListHelper.Create (arr);
|
||||
PriFileHelper.FindPriResource (m_hPriFile, buf);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (buf != IntPtr.Zero) LpcwstrListHelper.Destroy (buf);
|
||||
}
|
||||
}
|
||||
public void AddSearch (string uri) { AddSearch (new string [] { uri }); }
|
||||
public string Resource (string resName)
|
||||
{
|
||||
IntPtr ret = IntPtr.Zero;
|
||||
try
|
||||
{
|
||||
ret = PriFileHelper.GetPriResource (m_hPriFile, resName);
|
||||
if (ret == IntPtr.Zero) return string.Empty;
|
||||
return PriFileHelper.PtrToString (ret);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (ret != IntPtr.Zero) PriFileHelper.FreePriString (ret);
|
||||
}
|
||||
}
|
||||
public Dictionary<string, string> Resources (IEnumerable<string> resnames)
|
||||
{
|
||||
if (resnames == null) throw new ArgumentNullException (nameof (resnames));
|
||||
var result = new Dictionary<string, string> ();
|
||||
AddSearch (resnames);
|
||||
foreach (var name in resnames) result [name] = Resource (name);
|
||||
return result;
|
||||
}
|
||||
public static string LastError { get { return PriFileHelper.PriFileGetLastError (); } }
|
||||
public string Path (string resName) { return Resource (resName); }
|
||||
public Dictionary <string, string> Paths (IEnumerable <string> resNames) { return Resources (resNames); }
|
||||
public string String (string resName) { return Resource (resName); }
|
||||
public Dictionary <string, string> Strings (IEnumerable <string> resNames) { return Resources (resNames); }
|
||||
}
|
||||
public class PriReaderBundle: IDisposable
|
||||
{
|
||||
private class PriInst
|
||||
{
|
||||
public byte Type; // 0b01 lang, 0b10 scale, 0b11 both
|
||||
public PriReader Reader;
|
||||
public PriInst (byte type, IStream stream)
|
||||
{
|
||||
Type = (byte)(type & 0x03);
|
||||
Reader = new PriReader (stream);
|
||||
}
|
||||
public PriInst (byte type, IntPtr stream)
|
||||
{
|
||||
Type = (byte)(type & 0x03);
|
||||
Reader = new PriReader (stream);
|
||||
}
|
||||
public bool IsValid
|
||||
{
|
||||
get { return (Type & 0x03) != 0; }
|
||||
}
|
||||
}
|
||||
private readonly List<PriInst> _priFiles = new List<PriInst> (3);
|
||||
private readonly Dictionary<byte, PriInst> _mapPri = new Dictionary<byte, PriInst> ();
|
||||
// type: 1 language, 2 scale, 3 both
|
||||
public bool Set (byte type, IStream priStream)
|
||||
{
|
||||
byte realType = (byte)(type & 0x03);
|
||||
if (realType == 0) return false;
|
||||
PriInst inst;
|
||||
if (_mapPri.TryGetValue (realType, out inst))
|
||||
{
|
||||
inst.Reader.Dispose ();
|
||||
if (priStream != null) inst.Reader.Create (priStream);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (priStream == null) return false;
|
||||
inst = new PriInst (realType, priStream);
|
||||
_priFiles.Add (inst);
|
||||
_mapPri [realType] = inst;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public bool Set (byte type, IntPtr priStream)
|
||||
{
|
||||
byte realType = (byte)(type & 0x03);
|
||||
if (realType == 0) return false;
|
||||
PriInst inst;
|
||||
if (_mapPri.TryGetValue (realType, out inst))
|
||||
{
|
||||
inst.Reader.Dispose ();
|
||||
if (priStream != IntPtr.Zero) inst.Reader.Create (priStream);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (priStream == IntPtr.Zero) return false;
|
||||
inst = new PriInst (realType, priStream);
|
||||
_priFiles.Add (inst);
|
||||
_mapPri [realType] = inst;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
private PriReader Get (byte type, bool mustReturn)
|
||||
{
|
||||
type = (byte)(type & 0x03);
|
||||
PriInst inst;
|
||||
if (_mapPri.TryGetValue (type, out inst)) return inst.Reader;
|
||||
if (type != 0x03 && _mapPri.TryGetValue (0x03, out inst)) return inst.Reader;
|
||||
if (_priFiles.Count > 0 && mustReturn) return _priFiles [0].Reader;
|
||||
return null;
|
||||
}
|
||||
private static bool IsMsResourcePrefix (string s)
|
||||
{
|
||||
return PriFileHelper.IsMsResourcePrefix (s);
|
||||
}
|
||||
public void AddSearch (IEnumerable<string> arr)
|
||||
{
|
||||
if (arr == null) return;
|
||||
List<string> strRes = new List<string> ();
|
||||
List<string> pathRes = new List<string> ();
|
||||
foreach (string it in arr)
|
||||
{
|
||||
if (IsMsResourcePrefix (it)) strRes.Add (it);
|
||||
else pathRes.Add (it);
|
||||
}
|
||||
PriReader langPri = Get (1, true);
|
||||
PriReader scalePri = Get (2, true);
|
||||
if (langPri != null && strRes.Count > 0) langPri.AddSearch (strRes);
|
||||
if (scalePri != null && pathRes.Count > 0) scalePri.AddSearch (pathRes);
|
||||
}
|
||||
public void AddSearch (string resName)
|
||||
{
|
||||
if (IsMsResourcePrefix (resName))
|
||||
{
|
||||
PriReader langPri = Get (1, true);
|
||||
if (langPri != null) langPri.AddSearch (resName);
|
||||
}
|
||||
else
|
||||
{
|
||||
PriReader scalePri = Get (2, true);
|
||||
if (scalePri != null) scalePri.AddSearch (resName);
|
||||
}
|
||||
}
|
||||
public string Resource (string resName)
|
||||
{
|
||||
if (IsMsResourcePrefix (resName))
|
||||
{
|
||||
PriReader langPri = Get (1, true);
|
||||
return langPri != null ? langPri.Resource (resName) : string.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
PriReader scalePri = Get (2, true);
|
||||
return scalePri != null ? scalePri.Resource (resName) : string.Empty;
|
||||
}
|
||||
}
|
||||
public Dictionary<string, string> Resources (IEnumerable<string> resNames)
|
||||
{
|
||||
if (resNames == null) throw new ArgumentNullException ("resNames");
|
||||
Dictionary<string, string> result = new Dictionary<string, string> ();
|
||||
AddSearch (resNames);
|
||||
foreach (string name in resNames) result [name] = Resource (name);
|
||||
return result;
|
||||
}
|
||||
public string Path (string resName)
|
||||
{
|
||||
return Resource (resName);
|
||||
}
|
||||
public Dictionary<string, string> Paths (IEnumerable<string> resNames)
|
||||
{
|
||||
return Resources (resNames);
|
||||
}
|
||||
public string String (string resName)
|
||||
{
|
||||
return Resource (resName);
|
||||
}
|
||||
public Dictionary<string, string> Strings (IEnumerable<string> resNames)
|
||||
{
|
||||
return Resources (resNames);
|
||||
}
|
||||
public void Dispose ()
|
||||
{
|
||||
foreach (PriInst it in _priFiles) it.Reader.Dispose ();
|
||||
_mapPri.Clear ();
|
||||
_priFiles.Clear ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Newtonsoft.Json" version="13.0.4" targetFramework="net40" />
|
||||
</packages>
|
||||
Reference in New Issue
Block a user