Example #1
0
        // 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();
        }
Example #2
0
        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());
            }
        }
Example #3
0
        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
        }
Example #4
0
        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 { }
            };
        }