Update about Manager.

This commit is contained in:
Bruce
2026-01-27 22:47:49 +08:00
parent 5a404a55e3
commit 0c87a2cdcd
52 changed files with 9170 additions and 201 deletions
+29
View File
@@ -4,6 +4,8 @@ using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Reflection;
namespace AppxPackage
{
[Serializable]
@@ -229,4 +231,31 @@ namespace AppxPackage.Info
return a._value < value;
}
}
public static class JSHelper
{
public static void CallJS (object jsFunc, params object [] args)
{
if (jsFunc == null) return;
try
{
// 这里固定第一个参数为 thisArg(比如 1)
object [] realArgs = new object [args.Length + 1];
realArgs [0] = jsFunc; // thisArg
Array.Copy (args, 0, realArgs, 1, args.Length);
jsFunc.GetType ().InvokeMember (
"call",
BindingFlags.InvokeMethod,
null,
jsFunc,
realArgs
);
}
catch
{
// ignore errors in callback invocation
}
}
}
}
+32 -43
View File
@@ -7,6 +7,8 @@ using System.Text;
using AppxPackage.Info;
using NativeWrappers;
using System.IO;
using System.Threading;
//using PriFormat;
namespace AppxPackage
{
public static class DataUrlHelper
@@ -543,13 +545,14 @@ namespace AppxPackage
private MRApplication ReadSingleApplication (IntPtr hKeyValues)
{
var app = new MRApplication (ref m_hReader, ref m_pri, ref m_usePri, ref m_enablePri, m_reader.Value.FileRoot);
uint pairCount = (uint)Marshal.ReadInt32 (hKeyValues);
int baseOffset = Marshal.SizeOf (typeof (uint));
int pairSize = Marshal.SizeOf (typeof (PackageReadHelper.PAIR_PVOID));
for (int j = 0; j < pairCount; j++)
int pairCount = Marshal.ReadInt32 (hKeyValues);
IntPtr arrayBase = IntPtr.Add (hKeyValues, sizeof (uint));
for (int i = 0; i < pairCount; i++)
{
IntPtr pPair = IntPtr.Add (hKeyValues, baseOffset + j * pairSize);
var pair = (PackageReadHelper.PAIR_PVOID)Marshal.PtrToStructure (pPair, typeof (PackageReadHelper.PAIR_PVOID));
IntPtr pPairPtr = Marshal.ReadIntPtr (arrayBase, i * IntPtr.Size);
if (pPairPtr == IntPtr.Zero) continue;
PackageReadHelper.PAIR_PVOID pair =
(PackageReadHelper.PAIR_PVOID)Marshal.PtrToStructure (pPairPtr, typeof (PackageReadHelper.PAIR_PVOID));
if (pair.lpKey == IntPtr.Zero) continue;
string key = Marshal.PtrToStringUni (pair.lpKey);
if (string.IsNullOrEmpty (key)) continue;
@@ -849,12 +852,12 @@ namespace AppxPackage
private string m_filePath = string.Empty;
private bool m_usePRI = false;
private bool m_enablePRI = false;
private PriReader m_pri = new PriReader ();
private PriReader m_pri = null;
public IntPtr Instance => m_hReader;
public string FileRoot{ get { return Path.GetPathRoot (m_filePath); } }
private void InitPri ()
{
m_pri.Dispose ();
m_pri?.Dispose ();
if (!m_usePRI) return;
#region Get PRI IStream
switch (Type)
@@ -862,45 +865,12 @@ namespace AppxPackage
case PackageType.Appx:
{
var pripath = Path.Combine (FileRoot, "resources.pri");
m_pri.Create (pripath);
m_pri = new PriReader (pripath);
}
break;
}
#endregion
try
{
var resnames = new HashSet<string> ();
using (var prop = Properties)
{
var temp = prop.Description;
if (PriFileHelper.IsMsResourcePrefix (temp)) resnames.Add (temp);
temp = prop.DisplayName;
if (PriFileHelper.IsMsResourcePrefix (temp)) resnames.Add (temp);
temp = prop.Publisher;
if (PriFileHelper.IsMsResourcePrefix (temp)) resnames.Add (temp);
resnames.Add (prop.Logo);
}
using (var apps = Applications)
{
foreach (var app in apps)
{
foreach (var pair in app)
{
foreach (var pathres in ConstData.FilePathItems)
{
if ((pathres?.Trim ()?.ToLower () ?? "") == (pair.Key?.Trim ()?.ToLower ()))
{
resnames.Add (pair.Value);
}
else if (PriFileHelper.IsMsResourcePrefix (pair.Value))
resnames.Add (pair.Value);
}
}
}
}
m_pri.AddSearch (resnames);
}
catch (Exception) { }
return;
}
public PackageType Type
{
@@ -979,6 +949,25 @@ namespace AppxPackage
Newtonsoft.Json.Formatting.Indented
);
}
public void BuildJsonTextAsync (object callback)
{
if (callback == null) return;
Thread thread = new Thread (() => {
string json = string.Empty;
try
{
json = BuildJsonText ();
}
catch
{
json = string.Empty;
}
JSHelper.CallJS (callback, json);
});
thread.SetApartmentState (ApartmentState.MTA);
thread.IsBackground = true;
thread.Start ();
}
private object BuildJsonObject ()
{
return new
+43 -54
View File
@@ -4,8 +4,10 @@ using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using AppxPackage.Info;
using NativeWrappers;
//using PriFormat;
namespace AppxPackage
{
internal static partial class ConstData
@@ -220,6 +222,9 @@ namespace AppxPackage
if (hr.Succeeded) return ret != 0;
else return defaultValue;
}
#if DEBUG
public string Debug_StringValue (string attr) => StringValue (attr);
#endif
protected string StringResValue (string attr)
{
var res = StringValue (attr);
@@ -237,6 +242,7 @@ namespace AppxPackage
protected string PathResValue (string attr)
{
var res = StringValue (attr);
//var id = new PriFormat.PriResourceIdentifier (res);
try
{
if (m_usePri && m_enablePri)
@@ -267,7 +273,7 @@ namespace AppxPackage
{
IntPtr base64Head = IntPtr.Zero;
var base64s = PackageReadHelper.StreamToBase64W (pic, null, 0, out base64Head);
if (base64Head != IntPtr.Zero) { PackageReadHelper.GetStringAndFreeFromPkgRead (base64Head); base64Head = IntPtr.Zero; }
//if (base64Head != IntPtr.Zero) { PackageReadHelper.GetStringAndFreeFromPkgRead (base64Head); base64Head = IntPtr.Zero; }
return PackageReadHelper.GetStringAndFreeFromPkgRead (base64s);
}
catch (Exception) { return ""; }
@@ -288,7 +294,7 @@ namespace AppxPackage
pic = PackageReadHelper.GetFileFromPayloadPackage (pkg, logopath);
IntPtr base64Head = IntPtr.Zero;
var lpstr = PackageReadHelper.StreamToBase64W (pic, null, 0, out base64Head);
if (base64Head != IntPtr.Zero) { PackageReadHelper.GetStringAndFreeFromPkgRead (base64Head); base64Head = IntPtr.Zero; }
//if (base64Head != IntPtr.Zero) { PackageReadHelper.GetStringAndFreeFromPkgRead (base64Head); base64Head = IntPtr.Zero; }
if (!(lpstr != IntPtr.Zero && !string.IsNullOrEmpty (PackageReadHelper.GetStringFromPkgRead (lpstr))))
{
if (lpstr != IntPtr.Zero) PackageReadHelper.GetStringAndFreeFromPkgRead (lpstr);
@@ -300,7 +306,7 @@ namespace AppxPackage
{
pic1 = PackageReadHelper.GetFileFromPayloadPackage (pkg1, logopath);
lpstr = PackageReadHelper.StreamToBase64W (pic1, null, 0, out base64Head);
if (base64Head != IntPtr.Zero) { PackageReadHelper.GetStringAndFreeFromPkgRead (base64Head); base64Head = IntPtr.Zero; }
//if (base64Head != IntPtr.Zero) { PackageReadHelper.GetStringAndFreeFromPkgRead (base64Head); base64Head = IntPtr.Zero; }
}
}
catch (Exception) { }
@@ -478,11 +484,7 @@ namespace AppxPackage
pic = PackageReadHelper.GetAppxFileFromAppxPackage (m_hReader, value);
IntPtr base64Head = IntPtr.Zero;
IntPtr lpstr = PackageReadHelper.StreamToBase64W (pic, null, 0, out base64Head);
if (base64Head != IntPtr.Zero)
{
PackageReadHelper.GetStringAndFreeFromPkgRead (base64Head);
base64Head = IntPtr.Zero;
}
//if (base64Head != IntPtr.Zero) { PackageReadHelper.GetStringAndFreeFromPkgRead (base64Head); base64Head = IntPtr.Zero; }
return lpstr != IntPtr.Zero
? PackageReadHelper.GetStringAndFreeFromPkgRead (lpstr)
: "";
@@ -508,16 +510,12 @@ namespace AppxPackage
{
IntPtr header = IntPtr.Zero;
PackageReadHelper.GetSuitablePackageFromBundle (m_hReader, out header, out pkg);
if (header != IntPtr.Zero) PackageReadHelper.GetStringAndFreeFromPkgRead (header);
//if (header != IntPtr.Zero) PackageReadHelper.GetStringAndFreeFromPkgRead (header);
header = IntPtr.Zero;
pic = PackageReadHelper.GetFileFromPayloadPackage (pkg, value);
IntPtr base64Head = IntPtr.Zero;
IntPtr lpstr = PackageReadHelper.StreamToBase64W (pic, null, 0, out base64Head);
if (base64Head != IntPtr.Zero)
{
PackageReadHelper.GetStringAndFreeFromPkgRead (base64Head);
base64Head = IntPtr.Zero;
}
//if (base64Head != IntPtr.Zero) { PackageReadHelper.GetStringAndFreeFromPkgRead (base64Head); base64Head = IntPtr.Zero; }
return lpstr != IntPtr.Zero
? PackageReadHelper.GetStringAndFreeFromPkgRead (lpstr)
: "";
@@ -667,13 +665,14 @@ namespace AppxPackage
private PRApplication ReadSingleApplication (IntPtr hKeyValues)
{
var app = new PRApplication (ref m_hReader, ref m_priBundle, ref m_usePri, ref m_enablePri);
uint pairCount = (uint)Marshal.ReadInt32 (hKeyValues);
int baseOffset = Marshal.SizeOf (typeof (uint));
int pairSize = Marshal.SizeOf (typeof (PackageReadHelper.PAIR_PVOID));
for (int j = 0; j < pairCount; j++)
int pairCount = Marshal.ReadInt32 (hKeyValues);
IntPtr arrayBase = IntPtr.Add (hKeyValues, sizeof (uint));
for (int i = 0; i < pairCount; i++)
{
IntPtr pPair = IntPtr.Add (hKeyValues, baseOffset + j * pairSize);
var pair = (PackageReadHelper.PAIR_PVOID) Marshal.PtrToStructure (pPair, typeof (PackageReadHelper.PAIR_PVOID));
IntPtr pPairPtr = Marshal.ReadIntPtr (arrayBase, i * IntPtr.Size);
if (pPairPtr == IntPtr.Zero) continue;
PackageReadHelper.PAIR_PVOID pair =
(PackageReadHelper.PAIR_PVOID)Marshal.PtrToStructure (pPairPtr, typeof (PackageReadHelper.PAIR_PVOID));
if (pair.lpKey == IntPtr.Zero) continue;
string key = Marshal.PtrToStringUni (pair.lpKey);
if (string.IsNullOrEmpty (key)) continue;
@@ -1064,41 +1063,11 @@ namespace AppxPackage
} break;
}
#endregion
try
{
var resnames = new HashSet<string> ();
using (var prop = Properties)
{
var temp = prop.Description;
if (PriFileHelper.IsMsResourcePrefix (temp)) resnames.Add (temp);
temp = prop.DisplayName;
if (PriFileHelper.IsMsResourcePrefix (temp)) resnames.Add (temp);
temp = prop.Publisher;
if (PriFileHelper.IsMsResourcePrefix (temp)) resnames.Add (temp);
resnames.Add (prop.Logo);
}
using (var apps = Applications)
{
foreach (var app in apps)
{
foreach (var pair in app)
{
foreach (var pathres in ConstData.FilePathItems)
{
if ((pathres?.Trim ()?.ToLower () ?? "") == (pair.Key?.Trim ()?.ToLower ()))
{
resnames.Add (pair.Value);
}
else if (PriFileHelper.IsMsResourcePrefix (pair.Value))
resnames.Add (pair.Value);
}
}
}
}
m_priBundle.AddSearch (resnames);
}
catch (Exception) { }
return;
}
#if DEBUG
public PriReaderBundle PriInstance => m_priBundle;
#endif
public PackageType Type
{
get
@@ -1176,6 +1145,26 @@ namespace AppxPackage
Newtonsoft.Json.Formatting.Indented
);
}
public void BuildJsonTextAsync (object callback)
{
if (callback == null) return;
Thread thread = new Thread (() =>
{
string json = string.Empty;
try
{
json = BuildJsonText ();
}
catch
{
json = string.Empty;
}
JSHelper.CallJS (callback, json);
});
thread.SetApartmentState (ApartmentState.MTA);
thread.IsBackground = true;
thread.Start ();
}
private object BuildJsonObject ()
{
return new
+2
View File
@@ -401,6 +401,8 @@ namespace NativeWrappers
);
[DllImport (DllName, CallingConvention = CallConv)]
public static extern void PackageReaderFreeString (IntPtr p);
[DllImport (DllName, CallingConvention = CallConv, CharSet = CharSet.Unicode)]
public static extern IntPtr GetManifestPrerequistieSystemVersionName (IntPtr hReader, string lpName);
}
}
+1 -3
View File
@@ -58,7 +58,7 @@ namespace AppxPackage
[return: MarshalAs (UnmanagedType.Bool)]
public static extern bool IsMsResourceUri ([MarshalAs (UnmanagedType.LPWStr)] string pResUri);
[DllImport (DLL, CallingConvention = CallingConvention.Cdecl)]
public static extern void PriFormatFreeString (IntPtr ptr);
private static extern void PriFormatFreeString (IntPtr ptr);
public static string PtrToString (IntPtr ptr)
{
if (ptr == IntPtr.Zero) return null;
@@ -66,8 +66,6 @@ namespace AppxPackage
PriFormatFreeString (ptr); // 如果 DLL 返回的内存要求 free
return s;
}
[DllImport (DLL, CallingConvention = CallingConvention.Cdecl)]
public static extern void FreePriString (IntPtr p);
}
public static class LpcwstrListHelper
{
+17 -12
View File
@@ -1,9 +1,11 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices.ComTypes;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
namespace AppxPackage
{
@@ -75,17 +77,20 @@ namespace AppxPackage
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);
}
var task = Task.Factory.StartNew (() => {
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);
}
});
return task.Result;
}
public Dictionary<string, string> Resources (IEnumerable<string> resnames)
{