// This BG process is the first one and will be the only one. // It has to maintain connection to the UWP app, watch lifecycle and child processes, // and try to re-establish the connection with the APP if it's closed and opened again. static void StartAsMaster() { // Kickstart static constructors. // NOTE: All classes are static instead of instance, because they're tightly coupled singletons. // But static constructors are called on demand (at first access or call to the class), not at startup. IPC.Init(); // Open named pipe that is used exclusively by this background broker process and potentional future // broker instances. It is used to signal wheter there's already existing broker to ensure there's always // only one broker at a time. It's necessary because new instance of UWP app cannot reconnect to preexisting // background process that was spawned by previous instance of the app. var slavePipe = new NamedPipe(UWP.name, 100); // If new connection occurs on the pipe, it means another broker process has been spawned by a new UWP instance // that has no way of knowing of existence of (let alone connecting to) this broker process. // But we can connect to the UWP from here. slavePipe.Connection += () => UWP.Connect(); // Lifecycle & selfclose watchdog. WatchReferences(); // Open exclusive mutex to signify that this is the master mutex process for the app. mutex = new Mutex(false, UWP.name); // TODO: is this even needed? Application.EnableVisualStyles(); // TODO: remove? Application.SetCompatibleTextRenderingDefault(false); // TODO: remove? // Run blockingly. And release the mutex when the app quits. Application.Run(); Close(); }
private void SetupStdioPipes() { // Only long running processes created with spawn() can be communicate asynchronously through custom pipes. Pipes = new NamedPipe[Stdio.Length]; List <String> pipeNames = new List <String>(); // Skip the holy trinity of STDIO (IN/OUT/ERR) and start at custom pipes. // Few variables used for creation of pipe name. var brokerPid = Process.GetCurrentProcess().Id; // Create custom pipes for the other remaining (defined by user) stdio pipes. for (int fd = 3; fd < Stdio.Length; fd++) { var name = $"uwp-node\\{Cid}-{fd}-{brokerPid}"; pipeNames.Add(name); var pipe = new NamedPipe(name); pipe.fd = fd; Pipes[fd] = pipe; } // SIDE-NOTE: Because there's no easy way of creating libuv-style named-pipes that would get picked up by node // natively, we have to pass in through env vars custom list of names of pipes that we're creating in C# // that JS side of of uwp-node has too bind to. Info.EnvironmentVariables.Add("uwp-node-stdio-pipes", string.Join("|", pipeNames)); // Internal IPC used for internal uwp-node communications. Info.EnvironmentVariables.Add("uwp-node-stdio-iipc", UWP.name); if (Stdio.Contains("ipc")) { // Classic node's 'ipc' pipe created with cp.spawn(). int ipcFd = Array.FindIndex(Stdio, item => item == "ipc"); Info.EnvironmentVariables.Add("uwp-node-stdio-ipc", ipcFd.ToString()); } }
public MockAppServiceConnection() { var pipeId = (new Random()).Next(0, 10000); var pipeName = $"uwp-node-broker-tester-{pipeId}"; pipe = new NamedPipe(pipeName); pipe.Data += OnBytes; //pipe.Data += OnBytes; Console.WriteLine($"CREATED IPC PIPE: {pipeName}"); // DO NOT DELETE }
static public void CreateIipcPipe() { //Console.WriteLine($"C#: {UWP.name}"); // Create one pipe (and allow creation of up to 1000) for communication with children. //iipcPipe = new NamedPipe(UWP.name); iipcPipe = new NamedPipe(UWP.name, 250); //Console.WriteLine($"C#: CREATED IIPC {UWP.name}"); string temp = ""; iipcPipe.Data += (buffer, pipe) => { try { temp += Encoding.Default.GetString(buffer); var messages = temp.Split('\n'); temp = messages.Last(); foreach (string message in messages.Take(messages.Length - 1)) { Message?.Invoke(message, pipe); } } catch { } }; }