mirror of
https://jihulab.com/DGP-Studio/Snap.Hutao.git
synced 2025-11-19 21:02:53 +08:00
apply suggestion
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Snap.Hutao.Core.LifeCycle.InterProcess.Model;
|
||||
|
||||
internal sealed class ElevationStatusResponse
|
||||
{
|
||||
public bool IsElevated { get; set; }
|
||||
}
|
||||
@@ -6,9 +6,9 @@ namespace Snap.Hutao.Core.LifeCycle.InterProcess;
|
||||
internal enum PipePacketCommand : byte
|
||||
{
|
||||
None = 0,
|
||||
Exit = 1,
|
||||
|
||||
RedirectActivation = 10,
|
||||
RequestElevatedStatus = 11,
|
||||
|
||||
Exit = 30,
|
||||
RequestElevationStatus = 11,
|
||||
ResponseElevationStatus = 12,
|
||||
}
|
||||
@@ -17,6 +17,26 @@ internal static class PipeStreamExtension
|
||||
return content;
|
||||
}
|
||||
|
||||
public static unsafe PipePacketHeader ReadPacket<TData>(this PipeStream stream, out TData? data)
|
||||
where TData : class
|
||||
{
|
||||
data = default;
|
||||
|
||||
Span<byte> headerSpan = stackalloc byte[sizeof(PipePacketHeader)];
|
||||
stream.ReadExactly(headerSpan);
|
||||
fixed (byte* pHeader = headerSpan)
|
||||
{
|
||||
PipePacketHeader* header = (PipePacketHeader*)pHeader;
|
||||
if (header->ContentType is PipePacketContentType.Json)
|
||||
{
|
||||
ReadOnlySpan<byte> content = stream.GetValidatedContent(header);
|
||||
data = JsonSerializer.Deserialize<TData>(content);
|
||||
}
|
||||
|
||||
return *header;
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe void WritePacket(this PipeStream stream, PipePacketHeader* header, byte[] content)
|
||||
{
|
||||
header->ContentLength = content.Length;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Microsoft.Windows.AppLifecycle;
|
||||
using Snap.Hutao.Core.LifeCycle.InterProcess.Model;
|
||||
using System.IO.Pipes;
|
||||
|
||||
namespace Snap.Hutao.Core.LifeCycle.InterProcess;
|
||||
@@ -17,30 +18,20 @@ internal sealed partial class PrivateNamedPipeClient : IDisposable
|
||||
{
|
||||
if (clientStream.TryConnectOnce())
|
||||
{
|
||||
bool serverElevated = false;
|
||||
{
|
||||
// Connect
|
||||
PipePacketHeader connectPacket = default;
|
||||
connectPacket.Version = 1;
|
||||
connectPacket.Type = PipePacketType.Request;
|
||||
connectPacket.Command = PipePacketCommand.RequestElevatedStatus;
|
||||
connectPacket.Command = PipePacketCommand.RequestElevationStatus;
|
||||
|
||||
clientStream.Write(new(&connectPacket, sizeof(PipePacketHeader)));
|
||||
}
|
||||
|
||||
{
|
||||
// Get previous instance elevated status
|
||||
Span<byte> headerSpan = stackalloc byte[sizeof(PipePacketHeader)];
|
||||
clientStream.ReadExactly(headerSpan);
|
||||
fixed (byte* pHeader = headerSpan)
|
||||
{
|
||||
PipePacketHeader* header = (PipePacketHeader*)pHeader;
|
||||
ReadOnlySpan<byte> content = clientStream.GetValidatedContent(header);
|
||||
serverElevated = JsonSerializer.Deserialize<bool>(content);
|
||||
}
|
||||
}
|
||||
clientStream.ReadPacket(out ElevationStatusResponse? serverElevationStatus);
|
||||
ArgumentNullException.ThrowIfNull(serverElevationStatus);
|
||||
|
||||
if (!serverElevated && runtimeOptions.IsElevated)
|
||||
if (runtimeOptions.IsElevated && !serverElevationStatus.IsElevated)
|
||||
{
|
||||
// Kill previous instance to use current elevated instance
|
||||
PipePacketHeader killPacket = default;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Core.LifeCycle.InterProcess.Model;
|
||||
using System.IO.Pipes;
|
||||
using System.Security.AccessControl;
|
||||
using System.Security.Principal;
|
||||
@@ -74,42 +75,44 @@ internal sealed partial class PrivateNamedPipeServer : IDisposable
|
||||
|
||||
private unsafe void RunPacketSession(NamedPipeServerStream serverStream, CancellationToken token)
|
||||
{
|
||||
Span<byte> headerSpan = stackalloc byte[sizeof(PipePacketHeader)];
|
||||
bool sessionTerminated = false;
|
||||
while (serverStream.IsConnected && !sessionTerminated && !token.IsCancellationRequested)
|
||||
while (serverStream.IsConnected && !token.IsCancellationRequested)
|
||||
{
|
||||
serverStream.ReadExactly(headerSpan);
|
||||
fixed (byte* pHeader = headerSpan)
|
||||
PipePacketHeader header = serverStream.ReadPacket(out HutaoActivationArguments? hutaoArgs);
|
||||
switch ((header.Type, header.Command))
|
||||
{
|
||||
PipePacketHeader* header = (PipePacketHeader*)pHeader;
|
||||
case (PipePacketType.Request, PipePacketCommand.RequestElevationStatus):
|
||||
RespondElevationStatus();
|
||||
break;
|
||||
case (PipePacketType.Request, PipePacketCommand.RedirectActivation):
|
||||
messageDispatcher.RedirectActivation(hutaoArgs);
|
||||
break;
|
||||
case (PipePacketType.SessionTermination, _):
|
||||
serverStream.Disconnect();
|
||||
if (header.Command is PipePacketCommand.Exit)
|
||||
{
|
||||
messageDispatcher.Exit();
|
||||
}
|
||||
|
||||
switch ((header->Type, header->Command, header->ContentType))
|
||||
{
|
||||
case (PipePacketType.Request, PipePacketCommand.RequestElevatedStatus, _):
|
||||
PipePacketHeader elevatedPacket = default;
|
||||
elevatedPacket.Version = 1;
|
||||
elevatedPacket.Type = PipePacketType.Response;
|
||||
elevatedPacket.ContentType = PipePacketContentType.Json;
|
||||
|
||||
byte[] elevatedBytes = JsonSerializer.SerializeToUtf8Bytes(runtimeOptions.IsElevated);
|
||||
serverStream.WritePacket(&elevatedPacket, elevatedBytes);
|
||||
|
||||
break;
|
||||
case (PipePacketType.Request, PipePacketCommand.RedirectActivation, PipePacketContentType.Json):
|
||||
ReadOnlySpan<byte> content = serverStream.GetValidatedContent(header);
|
||||
messageDispatcher.RedirectActivation(JsonSerializer.Deserialize<HutaoActivationArguments>(content));
|
||||
break;
|
||||
case (PipePacketType.SessionTermination, _, _):
|
||||
serverStream.Disconnect();
|
||||
sessionTerminated = true;
|
||||
if (header->Command is PipePacketCommand.Exit)
|
||||
{
|
||||
messageDispatcher.Exit();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void RespondElevationStatus()
|
||||
{
|
||||
PipePacketHeader elevatedPacket = default;
|
||||
elevatedPacket.Version = 1;
|
||||
elevatedPacket.Type = PipePacketType.Response;
|
||||
elevatedPacket.Command = PipePacketCommand.ResponseElevationStatus;
|
||||
elevatedPacket.ContentType = PipePacketContentType.Json;
|
||||
|
||||
ElevationStatusResponse resp = new()
|
||||
{
|
||||
IsElevated = runtimeOptions.IsElevated,
|
||||
};
|
||||
|
||||
byte[] elevatedBytes = JsonSerializer.SerializeToUtf8Bytes(resp);
|
||||
serverStream.WritePacket(&elevatedPacket, elevatedBytes);
|
||||
serverStream.Flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
"profiles": {
|
||||
"Snap.Hutao": {
|
||||
"commandName": "MsixPackage",
|
||||
"nativeDebugging": true,
|
||||
"nativeDebugging": false,
|
||||
"doNotLaunchApp": false,
|
||||
"allowLocalNetworkLoopbackProperty": true
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user