Пример #1
0
        private static ProcessInfo RunProcess(ref StartInfoExtended sInfoEx, string commandLine)
        {
            int securityAttributeSize = Marshal.SizeOf <SecurityAttributes>();
            var pSec = new SecurityAttributes {
                nLength = securityAttributeSize
            };
            var tSec = new SecurityAttributes {
                nLength = securityAttributeSize
            };
            var success = ProcessApi.CreateProcess(
                lpApplicationName: null,
                lpCommandLine: commandLine,
                lpProcessAttributes: ref pSec,
                lpThreadAttributes: ref tSec,
                bInheritHandles: false,
                dwCreationFlags: Constants.EXTENDED_STARTUPINFO_PRESENT,
                lpEnvironment: IntPtr.Zero,
                lpCurrentDirectory: null,
                lpStartupInfo: ref sInfoEx,
                lpProcessInformation: out ProcessInfo pInfo
                );

            if (!success)
            {
                throw InteropException.CreateWithInnerHResultException("Could not create process.");
            }

            return(pInfo);
        }
Пример #2
0
        private static StartInfoExtended ConfigureProcessThread(IntPtr hPC, IntPtr attributes)
        {
            // this method implements the behavior described in https://docs.microsoft.com/en-us/windows/console/creating-a-pseudoconsole-session#preparing-for-creation-of-the-child-process

            var lpSize  = IntPtr.Zero;
            var success = ProcessApi.InitializeProcThreadAttributeList(
                lpAttributeList: IntPtr.Zero,
                dwAttributeCount: 1,
                dwFlags: 0,
                lpSize: ref lpSize
                );

            if (success || lpSize == IntPtr.Zero) // we're not expecting `success` here, we just want to get the calculated lpSize
            {
                throw InteropException.CreateWithInnerHResultException("Could not calculate the number of bytes for the attribute list.");
            }

            var startupInfo = new StartInfoExtended();

            startupInfo.StartupInfo.cb  = Marshal.SizeOf <StartInfoExtended>();
            startupInfo.lpAttributeList = Marshal.AllocHGlobal(lpSize);

            success = ProcessApi.InitializeProcThreadAttributeList(
                lpAttributeList: startupInfo.lpAttributeList,
                dwAttributeCount: 1,
                dwFlags: 0,
                lpSize: ref lpSize
                );

            if (!success)
            {
                throw InteropException.CreateWithInnerHResultException("Could not set up attribute list.");
            }

            success = ProcessApi.UpdateProcThreadAttribute(
                lpAttributeList: startupInfo.lpAttributeList,
                dwFlags: 0,
                attribute: attributes,
                lpValue: hPC,
                cbSize: (IntPtr)IntPtr.Size,
                lpPreviousValue: IntPtr.Zero,
                lpReturnSize: IntPtr.Zero
                );

            if (!success)
            {
                throw InteropException.CreateWithInnerHResultException("Could not set pseudoconsole thread attribute.");
            }

            return(startupInfo);
        }
Пример #3
0
        private static void SetConsoleModeToVirtualTerminal()
        {
            SafeFileHandle stdIn = ConsoleApi.GetStdHandle(StdHandle.InputHandle);

            if (!ConsoleApi.GetConsoleMode(stdIn, out uint outConsoleMode))
            {
                throw InteropException.CreateWithInnerHResultException("Could not get console mode.");
            }

            outConsoleMode |= Constants.ENABLE_VIRTUAL_TERMINAL_PROCESSING | Constants.DISABLE_NEWLINE_AUTO_RETURN;
            if (!ConsoleApi.SetConsoleMode(stdIn, outConsoleMode))
            {
                throw InteropException.CreateWithInnerHResultException("Could not enable virtual terminal processing.");
            }
        }
Пример #4
0
        public static PseudoConsole Create(SafeFileHandle inputReadSide, SafeFileHandle outputWriteSide, short width, short height)
        {
            int createResult = ConPtyApi.CreatePseudoConsole(
                new Coordinates {
                X = width, Y = height
            },
                inputReadSide, outputWriteSide,
                0, out IntPtr hPC);

            if (createResult != 0)
            {
                throw InteropException.CreateWithInnerHResultException($"Could not create pseudo console. Error Code: {createResult}");
            }

            return(new PseudoConsole(hPC));
        }
Пример #5
0
        private void MakeHandleNoninheritable(ref SafeFileHandle handler, IntPtr processHandle)
        {
            // Create noninheritable read handle and close the inheritable read handle.
            IntPtr handleClone;

            if (!ConsoleApi.DuplicateHandle(
                    processHandle,
                    handler.DangerousGetHandle(),
                    processHandle,
                    out handleClone,
                    0,
                    false,
                    Constants.DUPLICATE_SAME_ACCESS))
            {
                throw InteropException.CreateWithInnerHResultException("Couldn't duplicate the handle.");
            }

            SafeFileHandle toRelease = handler;

            handler = new SafeFileHandle(handleClone, true);
            toRelease.Dispose();
        }
        public static bool Receive(MethodProxy resultProxy, bool socketSuccess)
        {
            try
            {
                var taskToReturn = MethodDispatcher.GetTaskDispatcher(resultProxy.TaskIdentity);

                if (taskToReturn == null)
                {
                    return(false);
                }

                if (socketSuccess && resultProxy.TaskSuccess)
                {
                    MethodDispatcher.SetTaskResult(resultProxy.TaskIdentity, resultProxy);
                }
                else
                {
                    InteropException exception = null;

                    //If success value (from javascript) is false, like unable to connect to websocket
                    //or if the native task failed with an exception, cancel the current task, that will throw
                    if (!socketSuccess)
                    {
                        exception = new InteropException($"BlazorMobile was unable to connect to native through websocket server to execute task {resultProxy.TaskIdentity}");
                    }
                    else if (resultProxy.ExceptionDescriptor != null)
                    {
                        //We have some message to send in this case
                        if (!resultProxy.ExceptionDescriptor.HasInnerException)
                        {
                            exception = new InteropException(resultProxy.ExceptionDescriptor.Message);
                        }
                        else
                        {
                            exception = new InteropException(
                                resultProxy.ExceptionDescriptor.Message,
                                resultProxy.ExceptionDescriptor.InnerException);
                        }
                    }
                    else
                    {
                        //Sending uncustomized message
                        exception = new InteropException($"Task {resultProxy.TaskIdentity} has thrown an exception on native side. See log for more info.");
                    }

                    MethodDispatcher.SetTaskAsFaulted(resultProxy.TaskIdentity, exception);
                }

                taskToReturn.RunSynchronously();

                //Clear task from task list. Should then call the task to execute. It will throw if it has been cancelled
                MethodDispatcher.ClearTask(resultProxy.TaskIdentity);
            }
            catch (Exception ex)
            {
                ConsoleHelper.WriteException(ex);
                return(false);
            }

            return(true);
        }