mirror of
https://github.com/modernw/App-Installer-For-Windows-8.x-Reset.git
synced 2026-04-20 02:34:42 +10:00
Update about Manager.
This commit is contained in:
@@ -857,6 +857,7 @@ namespace AppxPackage
|
||||
private bool m_usePRI = false;
|
||||
private bool m_enablePRI = false;
|
||||
private PriReader m_pri = null;
|
||||
public PriReader PriFile => m_pri;
|
||||
public IntPtr Instance => m_hReader;
|
||||
public string FileRoot{ get { return Path.GetDirectoryName (m_filePath); } }
|
||||
private void InitPri ()
|
||||
|
||||
@@ -66,6 +66,108 @@ namespace AppxPackage
|
||||
PriFormatFreeString (ptr); // 如果 DLL 返回的内存要求 free
|
||||
return s;
|
||||
}
|
||||
[StructLayout (LayoutKind.Sequential)]
|
||||
internal struct DWORDWSTRPAIR
|
||||
{
|
||||
public uint dwKey;
|
||||
public IntPtr lpValue; // LPWSTR
|
||||
}
|
||||
[StructLayout (LayoutKind.Sequential)]
|
||||
internal struct DWSPAIRLIST
|
||||
{
|
||||
public uint dwLength;
|
||||
public DWORDWSTRPAIR lpArray; // 第一个元素(柔性数组起点)
|
||||
}
|
||||
[StructLayout (LayoutKind.Sequential)]
|
||||
internal struct WSDSPAIR
|
||||
{
|
||||
public IntPtr lpKey; // LPWSTR
|
||||
public IntPtr lpValue; // HDWSPAIRLIST
|
||||
}
|
||||
[StructLayout (LayoutKind.Sequential)]
|
||||
internal struct WSDSPAIRLIST
|
||||
{
|
||||
public uint dwLength;
|
||||
public WSDSPAIR lpArray; // 第一个元素
|
||||
}
|
||||
[DllImport (DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern IntPtr GetPriResourceAllValueList (PCSPRIFILE pFilePri, [MarshalAs (UnmanagedType.LPWStr)] string resName);
|
||||
[DllImport (DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void DestroyPriResourceAllValueList (IntPtr list);
|
||||
[DllImport (DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern IntPtr GetPriResourcesAllValuesList (PCSPRIFILE pFilePri, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr)] string [] lpResNames, uint dwCount);
|
||||
[DllImport (DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void DestroyResourcesAllValuesList (IntPtr list);
|
||||
public static Dictionary<uint, string> ParseDWSPAIRLIST (IntPtr ptr)
|
||||
{
|
||||
if (ptr == IntPtr.Zero)
|
||||
return null;
|
||||
|
||||
var result = new Dictionary<uint, string> ();
|
||||
|
||||
// 读取数量
|
||||
uint count = (uint)Marshal.ReadInt32 (ptr);
|
||||
|
||||
// 跳过 dwLength
|
||||
IntPtr pFirst = IntPtr.Add (ptr, sizeof (uint));
|
||||
|
||||
int elementSize = Marshal.SizeOf (typeof (DWORDWSTRPAIR));
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
IntPtr pItem = IntPtr.Add (pFirst, i * elementSize);
|
||||
|
||||
object boxed =
|
||||
Marshal.PtrToStructure (pItem, typeof (DWORDWSTRPAIR));
|
||||
|
||||
DWORDWSTRPAIR item = (DWORDWSTRPAIR)boxed;
|
||||
|
||||
string value = null;
|
||||
|
||||
if (item.lpValue != IntPtr.Zero)
|
||||
value = Marshal.PtrToStringUni (item.lpValue);
|
||||
|
||||
result [item.dwKey] = value;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
public static Dictionary<string, Dictionary<uint, string>> ParseWSDSPAIRLIST (IntPtr ptr)
|
||||
{
|
||||
if (ptr == IntPtr.Zero)
|
||||
return null;
|
||||
|
||||
var result =
|
||||
new Dictionary<string, Dictionary<uint, string>> ();
|
||||
|
||||
uint count = (uint)Marshal.ReadInt32 (ptr);
|
||||
|
||||
IntPtr pFirst = IntPtr.Add (ptr, sizeof (uint));
|
||||
|
||||
int elementSize = Marshal.SizeOf (typeof (WSDSPAIR));
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
IntPtr pItem = IntPtr.Add (pFirst, i * elementSize);
|
||||
|
||||
object boxed =
|
||||
Marshal.PtrToStructure (pItem, typeof (WSDSPAIR));
|
||||
|
||||
WSDSPAIR item = (WSDSPAIR)boxed;
|
||||
|
||||
string key = null;
|
||||
|
||||
if (item.lpKey != IntPtr.Zero)
|
||||
key = Marshal.PtrToStringUni (item.lpKey);
|
||||
|
||||
Dictionary<uint, string> valueDict =
|
||||
ParseDWSPAIRLIST (item.lpValue);
|
||||
|
||||
result [key] = valueDict;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
public static class LpcwstrListHelper
|
||||
{
|
||||
|
||||
@@ -9,6 +9,51 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace AppxPackage
|
||||
{
|
||||
public struct PriResourceKey
|
||||
{
|
||||
public enum PriResourceType: byte
|
||||
{
|
||||
Scale = 0,
|
||||
TargetSize = 1,
|
||||
String = 2
|
||||
}
|
||||
public enum PriContrast: byte
|
||||
{
|
||||
None = 0,
|
||||
White = 1,
|
||||
Black = 2,
|
||||
High = 3,
|
||||
Low = 4
|
||||
}
|
||||
public readonly PriResourceType Type;
|
||||
public readonly PriContrast Contrast;
|
||||
public readonly ushort Value;
|
||||
public uint Raw { get; }
|
||||
public PriResourceKey (uint raw)
|
||||
{
|
||||
Raw = raw;
|
||||
Type = (PriResourceType)((raw >> 28) & 0xF);
|
||||
Contrast = (PriContrast)((raw >> 24) & 0xF);
|
||||
Value = (ushort)(raw & 0xFFFF);
|
||||
}
|
||||
public bool IsScale => Type == PriResourceType.Scale;
|
||||
public bool IsTargetSize => Type == PriResourceType.TargetSize;
|
||||
public bool IsString => Type == PriResourceType.String;
|
||||
public override string ToString ()
|
||||
{
|
||||
switch (Type)
|
||||
{
|
||||
case PriResourceType.Scale:
|
||||
return $"Scale={Value}, Contrast={Contrast}";
|
||||
case PriResourceType.TargetSize:
|
||||
return $"TargetSize={Value}, Contrast={Contrast}";
|
||||
case PriResourceType.String:
|
||||
return $"LCID=0x{Value:X4}";
|
||||
default:
|
||||
return $"Unknown(0x{Raw:X8})";
|
||||
}
|
||||
}
|
||||
}
|
||||
public class PriReader: IDisposable
|
||||
{
|
||||
private IntPtr m_hPriFile = IntPtr.Zero;
|
||||
@@ -60,7 +105,7 @@ namespace AppxPackage
|
||||
public PriReader (IntPtr pStream) { Create (pStream); }
|
||||
public PriReader ([MarshalAs (UnmanagedType.LPWStr)] string fileName) { Create (fileName); }
|
||||
public PriReader () { }
|
||||
public void AddSearch (IEnumerable <string> arr)
|
||||
public void AddSearch (IEnumerable<string> arr)
|
||||
{
|
||||
IntPtr buf = IntPtr.Zero;
|
||||
try
|
||||
@@ -102,9 +147,98 @@ namespace AppxPackage
|
||||
}
|
||||
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 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 Dictionary<string, string> Strings (IEnumerable<string> resNames) { return Resources (resNames); }
|
||||
public Dictionary<PriResourceKey, string> ResourceAllValues (string resName)
|
||||
{
|
||||
var task = Task.Factory.StartNew (() => {
|
||||
IntPtr ptr = IntPtr.Zero;
|
||||
|
||||
try
|
||||
{
|
||||
ptr = PriFileHelper.GetPriResourceAllValueList (
|
||||
m_hPriFile, resName);
|
||||
|
||||
if (ptr == IntPtr.Zero)
|
||||
return new Dictionary<PriResourceKey, string> ();
|
||||
|
||||
var raw =
|
||||
PriFileHelper.ParseDWSPAIRLIST (ptr);
|
||||
|
||||
var result =
|
||||
new Dictionary<PriResourceKey, string> ();
|
||||
|
||||
foreach (var kv in raw)
|
||||
{
|
||||
var key = new PriResourceKey (kv.Key);
|
||||
result [key] = kv.Value;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (ptr != IntPtr.Zero) PriFileHelper.DestroyPriResourceAllValueList (ptr);
|
||||
}
|
||||
});
|
||||
return task.Result;
|
||||
}
|
||||
public Dictionary<string, Dictionary<PriResourceKey, string>> ResourcesAllValues (IEnumerable<string> resNames)
|
||||
{
|
||||
var task = Task.Factory.StartNew (() => {
|
||||
IntPtr ptr = IntPtr.Zero;
|
||||
|
||||
try
|
||||
{
|
||||
var list = resNames?.ToList ();
|
||||
|
||||
if (list == null || list.Count == 0)
|
||||
return new Dictionary<string,
|
||||
Dictionary<PriResourceKey, string>> ();
|
||||
|
||||
ptr = PriFileHelper.GetPriResourcesAllValuesList (
|
||||
m_hPriFile,
|
||||
list.ToArray (),
|
||||
(uint)list.Count);
|
||||
|
||||
if (ptr == IntPtr.Zero)
|
||||
return new Dictionary<string,
|
||||
Dictionary<PriResourceKey, string>> ();
|
||||
|
||||
var raw =
|
||||
PriFileHelper.ParseWSDSPAIRLIST (ptr);
|
||||
|
||||
var result =
|
||||
new Dictionary<string,
|
||||
Dictionary<PriResourceKey, string>> ();
|
||||
|
||||
foreach (var outer in raw)
|
||||
{
|
||||
var innerDict =
|
||||
new Dictionary<PriResourceKey, string> ();
|
||||
|
||||
foreach (var inner in outer.Value)
|
||||
{
|
||||
var key =
|
||||
new PriResourceKey (inner.Key);
|
||||
|
||||
innerDict [key] = inner.Value;
|
||||
}
|
||||
|
||||
result [outer.Key] = innerDict;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (ptr != IntPtr.Zero)
|
||||
PriFileHelper.DestroyResourcesAllValuesList (ptr);
|
||||
}
|
||||
});
|
||||
|
||||
return task.Result;
|
||||
}
|
||||
}
|
||||
public class PriReaderBundle: IDisposable
|
||||
{
|
||||
@@ -246,6 +380,7 @@ namespace AppxPackage
|
||||
{
|
||||
return Resources (resNames);
|
||||
}
|
||||
|
||||
public void Dispose ()
|
||||
{
|
||||
foreach (PriInst it in _priFiles) it.Reader.Dispose ();
|
||||
|
||||
Reference in New Issue
Block a user