babalae/better-genshin-impact · error · InvalidOperationException
无法取得命名管道客户端的进程或 Session 信息。
Error message
无法取得命名管道客户端的进程或 Session 信息。
What it means
Thrown by HandleConnectionOpenAsync when either connection.ClientProcessId or connection.ClientSessionId is null. These are populated in the InstanceConnection constructor via native interop: GetNamedPipeClientProcessId and ProcessIdToSessionId (kernel32.dll) called on the server-side pipe's SafePipeHandle. If the native call fails (returns false), both remain null and the connection cannot be registered because the root needs the client's PID and Windows Session ID for routing and authorization.
Source
Thrown at BetterGenshinImpact/Service/Instance/MessageHandlers/InstanceRequestHandler.cs:150
/// v2 不再校验父实例 ID 或启动记录,而是使用根管道客户端的真实 PID 和 Session。
/// </summary>
private async Task<InstanceIpcEnvelope> HandleConnectionOpenAsync(
InstanceConnection connection,
InstanceIpcEnvelope request,
CancellationToken cancellationToken)
{
if (_context.InstanceType != BetterGiInstanceType.Primary)
{
throw new InvalidOperationException("只有根实例可以接受客户端连接登记。");
}
if (connection.RemoteEndpoint is not null)
{
throw new InvalidOperationException("当前管道连接已经完成登记。");
}
if (connection.ClientProcessId is not { } processId
|| connection.ClientSessionId is not { } sessionId)
{
throw new InvalidOperationException("无法取得命名管道客户端的进程或 Session 信息。");
}
var open =
request.Data?.ToObject<ConnectionOpenRequest>(InstanceIpcProtocol.Serializer)
?? throw new ArgumentException("连接登记请求缺少数据。");
if (open.RequestedType == BetterGiInstanceType.WebView)
{
var endpoint = CreateEndpoint(
BetterGiInstanceType.WebView,
processId,
sessionId);
connection.RemoteEndpoint = endpoint;
RegisteredInstanceConnection? replaced = null;
lock (_state.RegistrationLock)
{
if (_state.WebViewConnectionsByProcessId.TryGetValue(
processId,
out var existing)View on GitHub (pinned to a7cb36712d)
Solutions
- Ensure the client process stays alive long enough for the server to query its PID — if the client crashes on startup, fix the crash.
- Verify the named pipe is created with PIPE_TYPE_MESSAGE and proper security attributes (InstancePipeFactory.CreateServer) so client identity is queryable.
- Check the SetLastError code from GetNamedPipeClientProcessId if it returns false — log it in InstancePipePeerInfo for diagnostics.
- If this occurs in a specific Windows environment (e.g., Server Core, container), verify kernel32 pipe info APIs are available.
- Handle gracefully by returning a Failure response to the client rather than throwing, so the client can retry.
Defensive patterns
Strategy: try-catch
Validate before calling
// After accepting a connection, verify peer info is available before proceeding
if (connection.ClientProcessId is null || connection.ClientSessionId is null)
{
_logger.LogWarning("无法获取管道客户端进程信息,关闭连接");
await connection.DisposeAsync();
return;
} Try / catch
// In HandleConnectionOpenAsync, this throws InvalidOperationException
// which is caught by HandleAsync's catch block and returned as a Failure response:
catch (Exception exception) when (exception is ArgumentException
or InvalidOperationException or IOException or TimeoutException or JsonException)
{
return InstanceIpcEnvelope.Failure(request, "invalid_request", exception.Message);
} Prevention
- Ensure clients stay alive long enough for the server to query their PID.
- Verify InstancePipeFactory.CreateServer creates pipes with proper attributes for peer info queries.
- Log the Win32 error code from GetNamedPipeClientProcessId when it fails.
- Return a Failure response instead of throwing for a more graceful client experience.
When it happens
Trigger: The root's InstanceConnection constructor receives a NamedPipeServerStream but InstancePipePeerInfo.TryGetClientProcessAndSession fails. GetNamedPipeClientProcessId can fail if the pipe handle is invalid, if the client has already disconnected before the server reads peer info, or if the OS denies the information query. ProcessIdToSessionId can fail if the process has exited.
Common situations: The client process connected and immediately disconnected (crash, force-kill) before the server could query its PID; running under a constrained security context where GetNamedPipeClientProcessId is denied; a Windows version or configuration that does not support this native API; an anonymized pipe where client identity is not available; the pipe handle was disposed before the constructor ran.
Related errors
- 根实例拒绝连接。
- 根实例连接响应缺少数据。
- 不支持的实例 IPC 版本:{envelope.Version}。
- 预期 JSON 帧,实际为 {frame.PayloadType}。
- 命名管道 JSON 消息为空。
AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13).
Data as JSON: /api/errors/36e09c346eb08a2a.
Report an issue: GitHub.