Compare commits

..
Author SHA1 Message Date
Aigio 44b4a3b05e 🐛 RunSingleInstancePipeServer 2023-09-01 06:29:54 +08:00
Aigio ac91872815 ✨ HostsTest 2023-09-01 05:09:48 +08:00
RMBGAME 2795dbac5f 🐛 Misc 2023-08-31 18:43:36 +08:00
ff m 4e2fe256ed 🐛 检测且初始化 nssdb 2023-08-31 18:33:54 +08:00
Aigio 83c515542c 🔥 StartAsAdministratorByBypassUAC 2023-08-31 18:06:35 +08:00
Aigio 0c9f25a304 🐛 CSR 2023-08-31 17:29:11 +08:00
Aigio 63be2ba037 ✨ CSR 2023-08-31 17:21:46 +08:00
Aigio 4c464623b8 🚧 3.0.0-preview.6 2023-08-31 04:30:17 +08:00
12 changed files with 402 additions and 145 deletions
+8 -1
View File
@@ -212,7 +212,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WinAuth", "ref\WinAuth\src\
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BD.WTTS.Client.Tools.OpenSourceLibraryList", "src\BD.WTTS.Client.Tools.OpenSourceLibraryList\BD.WTTS.Client.Tools.OpenSourceLibraryList.csproj", "{64F0101B-F54C-442E-BA70-738ACF72247F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BD.WTTS.Client.Plugins.SteamIdleCard", "src\BD.WTTS.Client.Plugins.SteamIdleCard\BD.WTTS.Client.Plugins.SteamIdleCard.csproj", "{80B51074-9473-4635-9B8F-4EB00B9ADCE7}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BD.WTTS.Client.Plugins.SteamIdleCard", "src\BD.WTTS.Client.Plugins.SteamIdleCard\BD.WTTS.Client.Plugins.SteamIdleCard.csproj", "{80B51074-9473-4635-9B8F-4EB00B9ADCE7}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BD.WTTS.Client.Tools.HostsTest", "src\BD.WTTS.Client.Tools.HostsTest\BD.WTTS.Client.Tools.HostsTest.csproj", "{13A7EBC3-7574-41BF-9657-CEC2053E54EC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -412,6 +414,10 @@ Global
{80B51074-9473-4635-9B8F-4EB00B9ADCE7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{80B51074-9473-4635-9B8F-4EB00B9ADCE7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{80B51074-9473-4635-9B8F-4EB00B9ADCE7}.Release|Any CPU.Build.0 = Release|Any CPU
{13A7EBC3-7574-41BF-9657-CEC2053E54EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{13A7EBC3-7574-41BF-9657-CEC2053E54EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{13A7EBC3-7574-41BF-9657-CEC2053E54EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{13A7EBC3-7574-41BF-9657-CEC2053E54EC}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -477,6 +483,7 @@ Global
{3F67183A-CC29-4B60-B534-08C2FB1A6746} = {84FF822C-BF60-493F-A8C8-6A413167E3DA}
{64F0101B-F54C-442E-BA70-738ACF72247F} = {D6C8A54D-878F-44A9-857F-6ED01491C7BD}
{80B51074-9473-4635-9B8F-4EB00B9ADCE7} = {A5828819-62AB-4B03-A083-8B6ED4915AA3}
{13A7EBC3-7574-41BF-9657-CEC2053E54EC} = {D6C8A54D-878F-44A9-857F-6ED01491C7BD}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {567F588F-E95C-4286-8B30-DB3B2200221C}
+14
View File
@@ -40,6 +40,19 @@ Install_certutil() {
echo "certutil 工具已安装。"
fi
}
certutil_Init() {
certutil -d sql:$HOME/.pki/nssdb -L
ret=$?
if [ $ret -ne 0 ]; then
echo "即将初始化 certutil sql:\$HOME/.pki/nssdb"
mkdir -p sql:$HOME/.pki
mkdir -p sql:$HOME/.pki/nssdb
chmod 700 sql:$HOME/.pki/nssdb
certutil -d sql:$HOME/.pki/nssdb -N --empty-password
else
echo "certutil nssdb 正常"
fi
}
Install_jq() {
# Check if jq is already installed
if command -v jq &>/dev/null; then
@@ -294,6 +307,7 @@ exit" >"$base_path/$exec_name.sh"
Install_certutil
Install_zenity
Install_jq
certutil_Init
#版本检查更新;
Get_NewVer
+1 -1
View File
@@ -14,7 +14,7 @@ public static partial class AssemblyInfo
/// <summary>
/// 预览版本号,范围 1~9
/// </summary>
const string ver_for_preview = "5";
const string ver_for_preview = "6";
/// <summary>
/// RC 版本号,范围 0~9
@@ -463,7 +463,7 @@ public static class AuthenticatorHelper
{
AvaloniaFilePickerFileTypeFilter fileTypes = new AvaloniaFilePickerFileTypeFilter.Item[] {
new($"{fileExtension} Files") {
Patterns = new[] { $"*.{fileExtension}", },
Patterns = new[] { $"*{fileExtension}", },
//MimeTypes
//AppleUniformTypeIdentifiers =
},
@@ -0,0 +1,36 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AssemblyName>Steam++.HostsTest</AssemblyName>
<OutputType>Exe</OutputType>
<ApplicationIcon>..\..\res\icons\app\v3\Icon.ico</ApplicationIcon>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DefineConstants>TOOL_HOSTSTEST;__NOT_IMPORT_COMMON__;$(DefineConstants)</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'">
<AllowedReferenceRelatedFileExtensions>
<!-- Prevent default XML and PDB files copied to output in RELEASE.
Only *.allowedextension files will be included, which doesn't exist in my case.
-->
.allowedextension
</AllowedReferenceRelatedFileExtensions>
<DebugType>none</DebugType>
<DebugSymbols>false</DebugSymbols>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\AssemblyInfo.Constants.cs">
<LinkBase>Properties</LinkBase>
</Compile>
</ItemGroup>
<ItemGroup>
<!-- PackageReference -->
<PackageReference Include="PInvoke.AdvApi32" />
<PackageReference Include="PInvoke.Kernel32" />
</ItemGroup>
<Import Project="..\TFM_NETX_WITH_WINDOWS.props" />
</Project>
@@ -0,0 +1,133 @@
// https://learn.microsoft.com/zh-cn/sysinternals/downloads/handle
var fColor = Console.ForegroundColor;
var bColor = Console.BackgroundColor;
try
{
var isProcessElevated = IsProcessElevated(Process.GetCurrentProcess());
Console.WriteLine($"当前进程是否为管理员权限:{isProcessElevated}");
var hostsFilePath = Path.Combine(Environment.SystemDirectory, "drivers", "etc", "hosts");
Console.WriteLine($"hosts 文件路径:{hostsFilePath}");
try
{
var text = File.ReadAllText(hostsFilePath);
Console.WriteLine("hosts 文件内容:");
Console.WriteLine("--------------------------------------------------");
Console.WriteLine(text);
Console.WriteLine("--------------------------------------------------");
File.WriteAllText(hostsFilePath, text);
Console.ForegroundColor = ConsoleColor.White;
Console.BackgroundColor = ConsoleColor.DarkGreen;
Console.WriteLine("OK");
}
catch (Exception ex)
{
Console.ForegroundColor = ConsoleColor.White;
Console.BackgroundColor = ConsoleColor.DarkRed;
Console.WriteLine("错误:");
Console.WriteLine(ex.ToString());
// https://learn.microsoft.com/zh-cn/sysinternals/downloads/handle
Console.WriteLine("查找 hosts 文件被哪个进程占用的命令,需要安装工具:");
Console.WriteLine("https://learn.microsoft.com/zh-cn/sysinternals/downloads/handle");
Console.WriteLine();
Console.WriteLine(
$"""
handle.exe "{hostsFilePath}" /accepteula
""");
}
}
finally
{
Console.ForegroundColor = fColor;
Console.BackgroundColor = bColor;
Console.WriteLine("键入回车键后退出此程序:");
Console.ReadLine();
}
/// <summary>
/// 检查指定的进程是否以管理员权限运行
/// </summary>
/// <param name="process"></param>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static unsafe bool IsProcessElevated(Process process)
{
try
{
var handle = process.Handle;
// IsPrivilegedProcess
// https://github.com/dotnet/runtime/pull/77355/files#diff-1c6f0e5208d48036e96fcc9c0243d93595f3ce16f2d1a50f51ba604d930ca69dR87
PInvoke.Kernel32.SafeObjectHandle? token = null;
try
{
if (PInvoke.AdvApi32.OpenProcessToken(handle,
PInvoke.AdvApi32.TokenAccessRights.TOKEN_READ,
out token))
{
TOKEN_ELEVATION elevation = default;
if (PInvoke.AdvApi32.GetTokenInformation(
token,
PInvoke.AdvApi32.TOKEN_INFORMATION_CLASS.TokenElevation,
&elevation,
sizeof(TOKEN_ELEVATION),
out _))
{
return elevation.TokenIsElevated != BOOL.FALSE;
}
}
}
finally
{
token?.Dispose();
}
var error = Marshal.GetLastPInvokeError();
throw new Win32Exception(error);
//using WindowsIdentity identity = new(handle);
//WindowsPrincipal principal = new(identity);
//return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
catch (Win32Exception ex)
{
/* “process.Handle”引发了类型“System.ComponentModel.Win32Exception”的异常
* Data: {System.Collections.ListDictionaryInternal}
* ErrorCode: -2147467259
* HResult: -2147467259
* HelpLink: null
* InnerException: null
* Message: "拒绝访问。"
* NativeErrorCode: 5
* Source: "System.Diagnostics.Process"
*/
if (ex.NativeErrorCode == 5)
return true;
}
return false;
}
// https://msdn.microsoft.com/en-us/library/windows/desktop/bb530717.aspx
struct TOKEN_ELEVATION
{
public BOOL TokenIsElevated;
}
/// <summary>
/// Blittable version of Windows BOOL type. It is convenient in situations where
/// manual marshalling is required, or to avoid overhead of regular bool marshalling.
/// </summary>
/// <remarks>
/// Some Windows APIs return arbitrary integer values although the return type is defined
/// as BOOL. It is best to never compare BOOL to TRUE. Always use bResult != BOOL.FALSE
/// or bResult == BOOL.FALSE .
/// </remarks>
enum BOOL : int
{
FALSE = 0,
TRUE = 1,
}
@@ -3,7 +3,7 @@ namespace BD.WTTS.Client.Tools.Publish.Commands;
interface IGenerateCaCertCommand : ICommand
{
const string commandName = "gcert";
const string X500DistinguishedNameValue = $"C=CN, S=Hunan, L=Changsha, O=\u6C5F\u82CF\u84B8\u6C7D\u51E1\u661F\u79D1\u6280\u6709\u9650\u516C\u53F8, OU=\u6280\u672F\u90E8, CN=\u6C5F\u82CF\u84B8\u6C7D\u51E1\u661F\u79D1\u6280\u6709\u9650\u516C\u53F8";
const string X500DistinguishedNameValue = $"C=CN, S=Hunan, L=Changsha, O=\u5F90\u5DDE\u7E41\u661F\u7F51\u7EDC\u79D1\u6280\u6709\u9650\u516C\u53F8, OU=\u6280\u672F\u90E8, CN=\u5F90\u5DDE\u7E41\u661F\u7F51\u7EDC\u79D1\u6280\u6709\u9650\u516C\u53F8";
public const int CertificateValidDays = 3650;
@@ -12,7 +12,7 @@ interface IGenerateCaCertCommand : ICommand
static Command ICommand.GetCommand()
{
var type = new Option<int>("--type",
"Generate certificate type(1 code, 2 store-code)");
"Generate certificate type(1 code, 2 store-code, 3 csr)");
var path = new Option<string>("--path",
"Directory where certificate files need to be saved");
var cn = new Option<string>("--cn", "X500DistinguishedNameValue");
@@ -39,9 +39,10 @@ interface IGenerateCaCertCommand : ICommand
/// </summary>
const string _13Oid = "1.3.6.1.4.1.311.10.3.13";
static (byte[] pfx, byte[] cer) GenerateCodeSigningCert(string x500DistinguishedNameValue, string password)
static (byte[] pfx, byte[] cer, string? csr) GenerateCodeSigningCert(string x500DistinguishedNameValue, string password, bool isCSR = false)
{
if (string.IsNullOrWhiteSpace(password))
string? csr = default;
if (!isCSR && string.IsNullOrWhiteSpace(password))
throw new ArgumentOutOfRangeException(nameof(password), password, null);
// https://learn.microsoft.com/zh-cn/windows/win32/appxpkg/how-to-create-a-package-signing-certificate
@@ -68,24 +69,36 @@ interface IGenerateCaCertCommand : ICommand
subjectKeyId = new(request.PublicKey, false);
request.CertificateExtensions.Add(subjectKeyId);
if (isCSR)
{
var signingRequestPem = request.CreateSigningRequestPem();
return (null!, null!, signingRequestPem);
}
var notBefore = DateTimeOffset.UtcNow;
var notAfter = notBefore.AddDays(CertificateValidDays);
using var cert = request.CreateSelfSigned(notBefore, notAfter);
var pfx = cert.Export(X509ContentType.Pfx, password); // 私钥
var cer = cert.Export(X509ContentType.Cert); // 公钥
return (pfx, cer);
return (pfx, cer, csr);
}
internal static void Handler(int type, string path, string cn, string password)
{
(var pfx, var cer) = type switch
(var pfx, var cer, var csr) = type switch
{
// 生成 BeyondDimension 代码签名证书
1 => GenerateCodeSigningCert(X500DistinguishedNameValue, password),
// 生成 上传应用商店的 代码签名证书
2 => GenerateCodeSigningCert($"CN={cn}", password),
3 => GenerateCodeSigningCert(X500DistinguishedNameValue, password, true),
_ => throw new ArgumentOutOfRangeException(nameof(type), type, null),
};
if (csr != default)
{
Console.WriteLine(csr);
return;
}
File.WriteAllBytes(path, pfx);
File.WriteAllBytes(path.TrimEnd(".pfx", StringComparison.OrdinalIgnoreCase) + ".cer", cer);
}
@@ -12,14 +12,21 @@ static partial class Interop
const uint QueryLimitedInformation = 0x00001000;
public static string QueryFullProcessImageName(Process process)
public static string? QueryFullProcessImageName(Process process)
{
int capacity = 1024;
StringBuilder sb = new(capacity);
var handle = Kernel32_.OpenProcess(new(QueryLimitedInformation), false, process.Id);
Kernel32_.QueryFullProcessImageName(handle, 0, sb, ref capacity);
string fullPath = sb.ToString(0, capacity);
return fullPath;
try
{
int capacity = 1024;
StringBuilder sb = new(capacity);
var handle = Kernel32_.OpenProcess(new(QueryLimitedInformation), false, process.Id);
Kernel32_.QueryFullProcessImageName(handle, 0, sb, ref capacity);
string fullPath = sb.ToString(0, capacity);
return fullPath;
}
catch
{
return null;
}
}
}
@@ -105,115 +105,115 @@ partial class WindowsPlatformServiceImpl
return false;
}
/// <summary>
/// 使用 BypassUAC 以管理员权限启动进程
/// </summary>
/// <param name="fileName"></param>
/// <param name="arguments"></param>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static async Task<Process?> StartAsAdministratorByBypassUAC(string fileName, string? arguments = null)
{
/** 33. Author: winscripting.blog
* https://github.com/hfiref0x/UACME
* https://github.com/FatRodzianko/SharpBypassUAC/blob/67a9a3e4500731881f60863454e4e42ef46874e0/SharpBypassUAC/FodHelper.cs
* Type: Shell API
* Method: Registry key manipulation
* Target(s): \system32\fodhelper.exe
* Component(s): Attacker defined
* Implementation: ucmShellRegModMethod
* Works from: Windows 10 TH1 (10240)
* Fixed in: unfixed 🙈
* How: -
* Code status: added in v2.7.2
*/
RegistryKey? classes = null;
var targetName = Path.Combine(Environment.GetFolderPath(
Environment.SpecialFolder.System),
"fodhelper.exe");
try
{
if (!File.Exists(targetName))
return null;
// /// <summary>
// /// 使用 BypassUAC 以管理员权限启动进程
// /// </summary>
// /// <param name="fileName"></param>
// /// <param name="arguments"></param>
// /// <returns></returns>
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// internal static async Task<Process?> StartAsAdministratorByBypassUAC(string fileName, string? arguments = null)
// {
// /** 33. Author: winscripting.blog
// * https://github.com/hfiref0x/UACME
// * https://github.com/FatRodzianko/SharpBypassUAC/blob/67a9a3e4500731881f60863454e4e42ef46874e0/SharpBypassUAC/FodHelper.cs
// * Type: Shell API
// * Method: Registry key manipulation
// * Target(s): \system32\fodhelper.exe
// * Component(s): Attacker defined
// * Implementation: ucmShellRegModMethod
// * Works from: Windows 10 TH1 (10240)
// * Fixed in: unfixed 🙈
// * How: -
// * Code status: added in v2.7.2
// */
// RegistryKey? classes = null;
// var targetName = Path.Combine(Environment.GetFolderPath(
// Environment.SpecialFolder.System),
// "fodhelper.exe");
// try
// {
// if (!File.Exists(targetName))
// return null;
var processPath = Environment.ProcessPath;
processPath.ThrowIsNull();
if (fileName != processPath) // 仅允许启动自己
throw new ArgumentOutOfRangeException(nameof(fileName));
// var processPath = Environment.ProcessPath;
// processPath.ThrowIsNull();
// if (fileName != processPath) // 仅允许启动自己
// throw new ArgumentOutOfRangeException(nameof(fileName));
var processName = Path.GetFileNameWithoutExtension(fileName);
if (string.IsNullOrWhiteSpace(processName))
throw new ArgumentNullException(nameof(processName));
// var processName = Path.GetFileNameWithoutExtension(fileName);
// if (string.IsNullOrWhiteSpace(processName))
// throw new ArgumentNullException(nameof(processName));
classes = Registry.CurrentUser.OpenSubKey(@"Software\Classes", true);
using var command = classes!.CreateSubKey(@"ms-settings\Shell\Open\command", true);
command.SetValue("DelegateExecute", "");
command.SetValue("", string.IsNullOrWhiteSpace(arguments) ?
$"\"{fileName}\"" : $"\"{fileName}\" {arguments}");
// classes = Registry.CurrentUser.OpenSubKey(@"Software\Classes", true);
// using var command = classes!.CreateSubKey(@"ms-settings\Shell\Open\command", true);
// command.SetValue("DelegateExecute", "");
// command.SetValue("", string.IsNullOrWhiteSpace(arguments) ?
// $"\"{fileName}\"" : $"\"{fileName}\" {arguments}");
ProcessStartInfo psi = new()
{
UseShellExecute = true,
WindowStyle = ProcessWindowStyle.Hidden,
FileName = targetName,
};
var processs_start_before = new HashSet<int>(
Process.GetProcessesByName(processName).Select(x => x.Id));
var process = Process.Start(psi);
process!.WaitForExit(6000);
// ProcessStartInfo psi = new()
// {
// UseShellExecute = true,
// WindowStyle = ProcessWindowStyle.Hidden,
// FileName = targetName,
// };
// var processs_start_before = new HashSet<int>(
// Process.GetProcessesByName(processName).Select(x => x.Id));
// var process = Process.Start(psi);
// process!.WaitForExit(6000);
Dictionary<int, bool> mIsProcessElevated = new();
for (int i = 0; i < 7; i++)
{
var processs_start_after = Process.GetProcessesByName(processName);
foreach (var item in processs_start_after)
{
if (item.Id == Environment.ProcessId)
continue;
if (processs_start_before.Contains(item.Id))
continue;
// Dictionary<int, bool> mIsProcessElevated = new();
// for (int i = 0; i < 7; i++)
// {
// var processs_start_after = Process.GetProcessesByName(processName);
// foreach (var item in processs_start_after)
// {
// if (item.Id == Environment.ProcessId)
// continue;
// if (processs_start_before.Contains(item.Id))
// continue;
if (mIsProcessElevated.TryGetValue(item.Id, out var value))
{
return item;
}
else
{
var isProcessElevated = IsProcessElevated(item);
if (isProcessElevated)
return item;
mIsProcessElevated.Add(item.Id, isProcessElevated);
}
}
// if (mIsProcessElevated.TryGetValue(item.Id, out var value))
// {
// return item;
// }
// else
// {
// var isProcessElevated = IsProcessElevated(item);
// if (isProcessElevated)
// return item;
// mIsProcessElevated.Add(item.Id, isProcessElevated);
// }
// }
await Task.Delay(800);
}
// await Task.Delay(800);
// }
return null;
}
catch (Exception ex)
{
#if DEBUG
Log.Error(TAG, ex, "StartAsAdministratorByBypassUAC fail.");
#endif
}
finally
{
if (classes != null)
{
try
{
classes.DeleteSubKeyTree("ms-settings");
}
catch
{
// return null;
// }
// catch (Exception ex)
// {
//#if DEBUG
// Log.Error(TAG, ex, "StartAsAdministratorByBypassUAC fail.");
//#endif
// }
// finally
// {
// if (classes != null)
// {
// try
// {
// classes.DeleteSubKeyTree("ms-settings");
// }
// catch
// {
}
classes.Dispose();
}
}
return null;
}
// }
// classes.Dispose();
// }
// }
// return null;
// }
/// <summary>
/// 以管理员权限启动进程
@@ -221,18 +221,18 @@ partial class WindowsPlatformServiceImpl
/// <param name="fileName"></param>
/// <param name="arguments"></param>
/// <returns></returns>
internal static async ValueTask<Process?> StartAsAdministrator(string fileName, string? arguments = null)
internal static /*async*/ ValueTask<Process?> StartAsAdministrator(string fileName, string? arguments = null)
{
#if !DEBUG
if (IsPrivilegedProcess)
return Process2.Start(fileName, arguments);
return ValueTask.FromResult(Process2.Start(fileName, arguments));
#endif
if (!DesktopBridge.IsRunningAsUwp)
{
var process = await StartAsAdministratorByBypassUAC(fileName, arguments);
if (process != null)
return process;
}
//if (!DesktopBridge.IsRunningAsUwp)
//{
// var process = await StartAsAdministratorByBypassUAC(fileName, arguments);
// if (process != null)
// return process;
//}
try
{
@@ -244,11 +244,11 @@ partial class WindowsPlatformServiceImpl
Verb = "runas",
};
var process_runas = Process.Start(psi);
return process_runas;
return ValueTask.FromResult(process_runas);
}
catch
{
return null;
return ValueTask.FromResult<Process?>(null);
}
}
}
@@ -1,3 +1,7 @@
#if WINDOWS
using System.Security.AccessControl;
#endif
// ReSharper disable once CheckNamespace
namespace BD.WTTS;
@@ -82,14 +86,31 @@ partial class Startup // 本应用程序单例管道
}
#endif
var currentMainModule = current.TryGetMainModule();
bool IsThisProgram(Process p, ProcessModule? pMainModule)
{
if (currentMainModule != null)
{
if (pMainModule != null)
{
return pMainModule.FileName == currentMainModule.FileName &&
pMainModule.ModuleName == currentMainModule.ModuleName;
}
else
{
#if WINDOWS
var path = Interop.Kernel32.QueryFullProcessImageName(p);
return path == currentMainModule.FileName;
#else
return false;
#endif
}
}
return true;
}
var query = from p in Process.GetProcessesByName(current.ProcessName)
let pMainModule = p.TryGetMainModule()
where p.Id != current.Id &&
p.ProcessName == current.ProcessName &&
(currentMainModule == null ||
(pMainModule != null &&
pMainModule.FileName == currentMainModule.FileName &&
pMainModule.ModuleName == currentMainModule.ModuleName))
p.ProcessName == current.ProcessName && IsThisProgram(p, pMainModule)
select p;
return query;
}
@@ -121,7 +142,7 @@ partial class Startup // 本应用程序单例管道
static string GetPipeName()
{
var processPath = Environment.ProcessPath ?? string.Empty;
return AssemblyInfo.APPLICATION_ID + "_v3_" + Hashs.String.Crc32(processPath);
return AssemblyInfo.APPLICATION_ID + "_v" + AssemblyInfo.InformationalVersion + "_" + Hashs.String.Crc32(processPath);
}
CancellationTokenSource? cts;
@@ -131,9 +152,35 @@ partial class Startup // 本应用程序单例管道
{
cts = new CancellationTokenSource();
var name = GetPipeName();
NamedPipeServerStream GetNamedPipeServerStream()
{
const PipeDirection direction = PipeDirection.In;
const int maxNumberOfServerInstances = 5;
const PipeTransmissionMode transmissionMode = PipeTransmissionMode.Byte;
const PipeOptions options = PipeOptions.None;
const int inBufferSize = 0;
const int outBufferSize = 0;
#if WINDOWS
if (WindowsPlatformServiceImpl.IsPrivilegedProcess)
{
// https://github.com/dotnet-campus/dotnetCampus.Ipc/blob/2.0.0-alpha403/src/dotnetCampus.Ipc/Internals/IpcPipeServerMessageProvider.cs#L99
SecurityIdentifier securityIdentifier = new(WellKnownSidType.AuthenticatedUserSid, null);
PipeSecurity pipeSecurity = new();
pipeSecurity.AddAccessRule(new PipeAccessRule(securityIdentifier,
PipeAccessRights.ReadWrite | PipeAccessRights.CreateNewInstance,
AccessControlType.Allow));
var result = NamedPipeServerStreamAcl.Create(name, direction, maxNumberOfServerInstances, transmissionMode, options, inBufferSize, outBufferSize, pipeSecurity);
return result;
}
#endif
return new NamedPipeServerStream(name, direction, maxNumberOfServerInstances, transmissionMode, options);
}
while (true)
{
using var pipeServer = new NamedPipeServerStream(name, PipeDirection.In, 1);
using var pipeServer = GetNamedPipeServerStream();
try
{
pipeServer.WaitForConnection();
@@ -177,7 +224,7 @@ partial class Startup // 本应用程序单例管道
using var pipeClient = new NamedPipeClientStream(".", name,
PipeDirection.Out, PipeOptions.None,
TokenImpersonationLevel.Impersonation);
pipeClient.Connect(TimeSpan.FromSeconds(25));
pipeClient.Connect(TimeSpan.FromSeconds(7.7D));
using StreamWriter sw = new StreamWriter(pipeClient);
sw.WriteLine(value);
return true;
+9 -9
View File
@@ -27,20 +27,20 @@ global using System.IO;
global using System.Buffers;
global using System.IO.Pipes;
global using PipeOptions = System.IO.Pipes.PipeOptions;
#if !NETFRAMEWORK_SINGLE_FILE && !RES_PROJ
#if !NETFRAMEWORK_SINGLE_FILE && !RES_PROJ && !__NOT_IMPORT_COMMON__
global using System.IO.Pipelines;
global using PipelineOptions = System.IO.Pipelines.PipeOptions;
#endif
#endif
global using System.IO.Compression;
#if !NETFRAMEWORK && !APP_HOST && !NETFRAMEWORK_SINGLE_FILE && !RES_PROJ
#if !NETFRAMEWORK && !APP_HOST && !NETFRAMEWORK_SINGLE_FILE && !RES_PROJ && !__NOT_IMPORT_COMMON__
global using System.IO.FileFormats;
#endif
global using System.Linq;
global using System.Linq.Expressions;
global using System.Net;
global using System.Net.Security;
#if !NETFRAMEWORK && !APP_HOST && !NETFRAMEWORK_SINGLE_FILE && !RES_PROJ
#if !NETFRAMEWORK && !APP_HOST && !NETFRAMEWORK_SINGLE_FILE && !RES_PROJ && !__NOT_IMPORT_COMMON__
global using System.Net.Http.Headers;
global using System.Net.Http.Json;
global using System.Net.Http.Client;
@@ -66,7 +66,7 @@ global using System.Text.Unicode;
#endif
global using System.Text.RegularExpressions;
global using System.Runtime;
#if !NETFRAMEWORK && !APP_HOST && !NETFRAMEWORK_SINGLE_FILE && !RES_PROJ
#if !NETFRAMEWORK && !APP_HOST && !NETFRAMEWORK_SINGLE_FILE && !RES_PROJ && !__NOT_IMPORT_COMMON__
global using DeploymentMode = System.Runtime.DeploymentMode;
global using System.Runtime.Devices;
#endif
@@ -74,16 +74,16 @@ global using System.Runtime.InteropServices;
global using System.Runtime.Versioning;
global using System.Runtime.Serialization.Formatters;
#if !NETFRAMEWORK && !APP_HOST && !NETFRAMEWORK_SINGLE_FILE && !RES_PROJ
#if !NETFRAMEWORK && !APP_HOST && !NETFRAMEWORK_SINGLE_FILE && !RES_PROJ && !__NOT_IMPORT_COMMON__
global using Microsoft.Extensions.DependencyInjection;
global using Microsoft.Extensions.DependencyInjection.Extensions;
#endif
#if WINDOWS && !APP_HOST && !APP_REVERSE_PROXY && !LIB_CLIENT_IPC
#if WINDOWS && !APP_HOST && !APP_REVERSE_PROXY && !LIB_CLIENT_IPC && !__NOT_IMPORT_COMMON__
global using System.Management;
#endif
#if !NONE_UI && (WINDOWS || APP_HOST)
#if !NONE_UI && (WINDOWS || APP_HOST) && !__NOT_IMPORT_COMMON__
global using WPFMessageBox = MS.Win32.MessageBox;
global using WPFMessageBoxButton = MS.Win32.MessageBoxButton;
global using WPFMessageBoxImage = MS.Win32.MessageBoxImage;
@@ -94,14 +94,14 @@ global using System.Xml;
global using System.Xml.Serialization;
global using System.Security.Cryptography.X509Certificates;
global using IPAddress = System.Net.IPAddress;
#if !NETFRAMEWORK && !APP_HOST && !NETFRAMEWORK_SINGLE_FILE && !RES_PROJ
#if !NETFRAMEWORK && !APP_HOST && !NETFRAMEWORK_SINGLE_FILE && !RES_PROJ && !__NOT_IMPORT_COMMON__
global using Ioc = System.Ioc;
global using DateTimeFormat = System.DateTimeFormat;
global using SerializationDateTimeFormat = System.Runtime.Serialization.DateTimeFormat;
global using HttpMethod = System.Net.Http.HttpMethod;
#endif
#if !NETFRAMEWORK && !APP_HOST && !NETFRAMEWORK_SINGLE_FILE && !RES_PROJ
#if !NETFRAMEWORK && !APP_HOST && !NETFRAMEWORK_SINGLE_FILE && !RES_PROJ && !__NOT_IMPORT_COMMON__
global using HttpHandlerCategory = System.Net.Http.Client.HttpHandlerCategory;
global using IHttpClientFactory = System.Net.Http.Client.IHttpClientFactory;
#endif
+2 -2
View File
@@ -8,7 +8,7 @@
#if !APP_HOST
#if !NETFRAMEWORK
#if !__NOT_IMPORT_COMMON_PRIMITIVES__
#if !__NOT_IMPORT_COMMON_PRIMITIVES__ && !__NOT_IMPORT_COMMON__
global using Polly;
global using BD.Common;
global using BD.Common.Columns;
@@ -22,7 +22,7 @@ global using BD.Common.Identity;
global using BD.Common.Identity.Abstractions;
#endif
#if !__NOT_IMPORT_COMMON_SERVICES__
#if !__NOT_IMPORT_COMMON_SERVICES__ && !__NOT_IMPORT_COMMON__
global using BD.Common.Services;
global using BD.Common.Services.Implementation;
#endif