using System.IO.Pipes; using ZB.MOM.WW.OtOpcUa.Core.Scripting.Protocol; namespace ZB.MOM.WW.OtOpcUa.ScriptWorker; /// Entry point: connect to the host's pipe named in the environment and serve until told to stop. internal static class Program { private static async Task Main() { var pipeName = Environment.GetEnvironmentVariable(ScriptWorkerEnvironment.PipeName); var nonce = Environment.GetEnvironmentVariable(ScriptWorkerEnvironment.Nonce); if (string.IsNullOrEmpty(pipeName) || string.IsNullOrEmpty(nonce)) { await Console.Error.WriteLineAsync("ScriptWorker: launched without a pipe name or nonce; exiting."); return ScriptWorkerEnvironment.ExitProtocolFault; } _ = int.TryParse(Environment.GetEnvironmentVariable(ScriptWorkerEnvironment.ParentPid), out var parentPid); // CurrentUserOnly: the client verifies the server end is owned by this account as well. var pipe = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut, PipeOptions.Asynchronous | PipeOptions.CurrentUserOnly); try { // Synchronous, so the socket under a Unix pipe stays blocking (ScriptWorkerFrameCodec.BlockingStream). pipe.Connect(TimeSpan.FromSeconds(10)); } catch (Exception ex) { await Console.Error.WriteLineAsync($"ScriptWorker: could not connect to the host pipe: {ex.Message}"); return ScriptWorkerEnvironment.ExitProtocolFault; } var host = new WorkerHost(ScriptWorkerFrameCodec.BlockingStream(pipe), nonce, parentPid); return await host.RunAsync(); } }