Запуск процесса без отображения окна C#

127
17 декабря 2020, 11:10

Я хочу запустить процесс но не отображать графическое окно при этом, подскажите как это реализовать ? Я пробовал следующий код:

Process p = new Process();
p.StartInfo.FileName = // путь к запускаемому GUI 
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p.Start();

Однако при подобном подходе окно все равно отображается. Подскажите есть ли способ запуска процесса без отображения окна ?

Answer 1

Попробуй мой пример, мне помог скрыть процесс. Даже Viber скрывает, только в трее висит, но раскрыть нельзя. Сейчас несколько программ протестировал, вроде скрывает. Не знаю что у тебя за программа, но попробуй, может поможет. Тестировал на Windows 10 x64.

    [DllImport("shell32.dll", CharSet = CharSet.Auto)]
    public static extern bool ShellExecuteEx(ref SHELLEXECUTEINFO lpExecInfo);
    [StructLayout(LayoutKind.Sequential)]
    public struct SHELLEXECUTEINFO
    {
        public int cbSize;
        public uint fMask;
        public IntPtr hwnd;
        [MarshalAs(UnmanagedType.LPTStr)]
        public string lpVerb;
        [MarshalAs(UnmanagedType.LPTStr)]
        public string lpFile;
        [MarshalAs(UnmanagedType.LPTStr)]
        public string lpParameters;
        [MarshalAs(UnmanagedType.LPTStr)]
        public string lpDirectory;
        public int nShow;
        public IntPtr hInstApp;
        public IntPtr lpIDList;
        [MarshalAs(UnmanagedType.LPTStr)]
        public string lpClass;
        public IntPtr hkeyClass;
        public uint dwHotKey;
        public IntPtr hIcon;
        public IntPtr hProcess;
    }
    public enum ShowCommands : int
    {
        SW_HIDE = 0,
        SW_SHOWNORMAL = 1,
        SW_NORMAL = 1,
        SW_SHOWMINIMIZED = 2,
        SW_SHOWMAXIMIZED = 3,
        SW_MAXIMIZE = 3,
        SW_SHOWNOACTIVATE = 4,
        SW_SHOW = 5,
        SW_MINIMIZE = 6,
        SW_SHOWMINNOACTIVE = 7,
        SW_SHOWNA = 8,
        SW_RESTORE = 9,
        SW_SHOWDEFAULT = 10,
        SW_FORCEMINIMIZE = 11,
        SW_MAX = 11
    }
    [Flags]
    public enum ShellExecuteMaskFlags : uint
    {
        SEE_MASK_DEFAULT = 0x00000000,
        SEE_MASK_CLASSNAME = 0x00000001,
        SEE_MASK_CLASSKEY = 0x00000003,
        SEE_MASK_IDLIST = 0x00000004,
        SEE_MASK_INVOKEIDLIST = 0x0000000c,   // Note SEE_MASK_INVOKEIDLIST(0xC) implies SEE_MASK_IDLIST(0x04) 
        SEE_MASK_HOTKEY = 0x00000020,
        SEE_MASK_NOCLOSEPROCESS = 0x00000040,
        SEE_MASK_CONNECTNETDRV = 0x00000080,
        SEE_MASK_NOASYNC = 0x00000100,
        SEE_MASK_FLAG_DDEWAIT = SEE_MASK_NOASYNC,
        SEE_MASK_DOENVSUBST = 0x00000200,
        SEE_MASK_FLAG_NO_UI = 0x00000400,
        SEE_MASK_UNICODE = 0x00004000,
        SEE_MASK_NO_CONSOLE = 0x00008000,
        SEE_MASK_ASYNCOK = 0x00100000,
        SEE_MASK_HMONITOR = 0x00200000,
        SEE_MASK_NOZONECHECKS = 0x00800000,
        SEE_MASK_NOQUERYCLASSSTORE = 0x01000000,
        SEE_MASK_WAITFORINPUTIDLE = 0x02000000,
        SEE_MASK_FLAG_LOG_USAGE = 0x04000000,
    }
    public Form1()
    {
        InitializeComponent();
        RunProcess();
    }
    void RunProcess()
    {
        bool res = false;
        string program = @"C:\Директория где находится программа для запуска";
        SHELLEXECUTEINFO sh = new SHELLEXECUTEINFO();
        sh.cbSize = Marshal.SizeOf(sh);
        sh.lpVerb = "open";
        sh.lpParameters = "";
        sh.lpFile = "Viber.exe";
        sh.lpDirectory = program;
        sh.fMask = (uint)ShellExecuteMaskFlags.SEE_MASK_NOCLOSEPROCESS;
        sh.nShow = (int)ShowCommands.SW_HIDE;
        res = ShellExecuteEx(ref sh);
    }
Answer 2

Как вариант, создать новый рабочий стол и запустить процесс в нем:

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace ConsoleApp1
{
    class Program
    {
        const uint NORMAL_PRIORITY_CLASS = 0x0020;
        [DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr CreateDesktop(string lpszDesktop, IntPtr lpszDevice, IntPtr pDevmode, int dwFlags, uint dwDesiredAccess, IntPtr lpsa);
        [DllImport("user32.dll")]
        static extern bool CloseDesktop(IntPtr handle);
        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool CloseHandle(IntPtr hObject);
        enum DESKTOP_ACCESS : uint
        {
            DESKTOP_NONE = 0,
            DESKTOP_READOBJECTS = 0x0001,
            DESKTOP_CREATEWINDOW = 0x0002,
            DESKTOP_CREATEMENU = 0x0004,
            DESKTOP_HOOKCONTROL = 0x0008,
            DESKTOP_JOURNALRECORD = 0x0010,
            DESKTOP_JOURNALPLAYBACK = 0x0020,
            DESKTOP_ENUMERATE = 0x0040,
            DESKTOP_WRITEOBJECTS = 0x0080,
            DESKTOP_SWITCHDESKTOP = 0x0100,
            GENERIC_ALL = (DESKTOP_READOBJECTS | DESKTOP_CREATEWINDOW | DESKTOP_CREATEMENU |
                            DESKTOP_HOOKCONTROL | DESKTOP_JOURNALRECORD | DESKTOP_JOURNALPLAYBACK |
                            DESKTOP_ENUMERATE | DESKTOP_WRITEOBJECTS | DESKTOP_SWITCHDESKTOP),
        }
        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        static extern bool CreateProcess(
            string lpApplicationName,
            string lpCommandLine,
            IntPtr lpProcessAttributes,
            IntPtr lpThreadAttributes,
            bool bInheritHandles,
            uint dwCreationFlags,
            IntPtr lpEnvironment,
            string lpCurrentDirectory,
            [In] ref STARTUPINFO lpStartupInfo,
            out PROCESS_INFORMATION lpProcessInformation);
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        struct STARTUPINFO
        {
            public Int32 cb;
            public string lpReserved;
            public string lpDesktop;
            public string lpTitle;
            public Int32 dwX;
            public Int32 dwY;
            public Int32 dwXSize;
            public Int32 dwYSize;
            public Int32 dwXCountChars;
            public Int32 dwYCountChars;
            public Int32 dwFillAttribute;
            public Int32 dwFlags;
            public Int16 wShowWindow;
            public Int16 cbReserved2;
            public IntPtr lpReserved2;
            public IntPtr hStdInput;
            public IntPtr hStdOutput;
            public IntPtr hStdError;
        }
        [StructLayout(LayoutKind.Sequential)]
        struct PROCESS_INFORMATION
        {
            public IntPtr hProcess;
            public IntPtr hThread;
            public int dwProcessId;
            public int dwThreadId;
        }
        static void Main(string[] args)
        {
            IntPtr hDesktop = CreateDesktop("NewDesktop", IntPtr.Zero, IntPtr.Zero, 0,
                (uint)DESKTOP_ACCESS.GENERIC_ALL, IntPtr.Zero);
            if (hDesktop == IntPtr.Zero) throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
            bool retValue;
            string Application = "...";
            string CommandLine = "...";
            PROCESS_INFORMATION pInfo = new PROCESS_INFORMATION();
            STARTUPINFO sInfo = new STARTUPINFO();
            sInfo.cb = Marshal.SizeOf(sInfo);
            sInfo.lpDesktop = "NewDesktop";            
            retValue = CreateProcess(Application, CommandLine,IntPtr.Zero, IntPtr.Zero, false, NORMAL_PRIORITY_CLASS,
            IntPtr.Zero, null, ref sInfo, out pInfo);
            if(retValue == false) throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
            //...            
            CloseHandle(pInfo.hProcess);
            CloseHandle(pInfo.hThread);
            CloseDesktop(hDesktop);
        }
    }
}
READ ALSO
Не находит строку (StreamReader)

Не находит строку (StreamReader)

У меня скачан html файл в котором есть такая строка:

127
Как обратиться к переменной из другого скрипта и из другой сцены, в Unity?

Как обратиться к переменной из другого скрипта и из другой сцены, в Unity?

Как обратиться к переменной из другого скрипта и из другой сцены? Например в настройках игры я ставлю управление мышкой( переменная будет...

108
entity framework , PK and FK

entity framework , PK and FK

После добавления данных в CustomerId записывается NULL, почему?

134
Присвоение ID пользователю

Присвоение ID пользователю

подскажите кто разбирается в чем проблема, присваиваю ID пользователю в классе User, программно ID присваивается нормально, но как создаю нового...

101