"WOL" pour une application ? [EDIT: c# startProcess from service]

Répondre
Partager Rechercher
Pour lancer une commande depuis un service dans une session utilisateur... Attention, dans l'exemple ci-dessous ça l'exécute dans toutes les sessions trouvées s'il y en a plusieurs.

A peaufiner (si besoin de séparer la commande en exécutable/arguments notamment), c'est plutôt brut et un peu "goret". Je ne sais plus où j'avais trouvé ça...

Fonctionne sous W8.1 ; non testé sous W10 mais ça devrait être pareil.


Code:
[DllImport("advapi32.dll", EntryPoint = "CreateProcessAsUser", SetLastError = true, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public extern static bool CreateProcessAsUser(IntPtr hToken,
                                                       String lpApplicationName,
                                                       String lpCommandLine,
                                                       ref SECURITY_ATTRIBUTES lpProcessAttributes,
                                                       ref SECURITY_ATTRIBUTES lpThreadAttributes,
                                                       bool bInheritHandle,
                                                       int dwCreationFlags,
                                                       IntPtr lpEnvironment,
                                                       String lpCurrentDirectory,
                                                       ref STARTUPINFO lpStartupInfo,
                                                       out PROCESS_INFORMATION lpProcessInformation);

        [DllImport("kernel32.dll")]
        public static extern bool ProcessIdToSessionId(uint dwProcessId,
                                                ref uint pSessionId);

        [DllImport("advapi32.dll", EntryPoint = "DuplicateTokenEx")]
        public extern static bool DuplicateTokenEx(IntPtr ExistingTokenHandle,
                                                   uint dwDesiredAccess,
                                                   ref SECURITY_ATTRIBUTES lpThreadAttributes,
                                                   int TokenType,
                                                   int ImpersonationLevel,
                                                   ref IntPtr DuplicateTokenHandle);

        [DllImport("kernel32.dll")]
        public static extern IntPtr OpenProcess(uint dwDesiredAccess,
                                         bool bInheritHandle,
                                         uint dwProcessId);

        [DllImport("advapi32", SetLastError = true), SuppressUnmanagedCodeSecurityAttribute]
        public static extern bool OpenProcessToken(IntPtr ProcessHandle,
                                            int DesiredAccess,
                                            ref IntPtr TokenHandle);

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool CloseHandle(IntPtr hSnapshot);

        private static string ExecuteCommandInUserContext(string Command)
        {
            StringBuilder stbResponse = new StringBuilder();
            string strSep = string.Empty;

            try
            {
                // retrieve winlogon process list
                Process[] processes = Process.GetProcessesByName("logonUI");

                if (processes.Count() == 0)
                {
                    // retrieve winlogon process list
                    processes = Process.GetProcessesByName("winlogon");

                    // loop on each process
                    foreach (Process p in processes)
                    {
                        strSep = (stbResponse.Length == 0 ? string.Empty : ", ");

                        // declare objects
                        PROCESS_INFORMATION processInfo = new PROCESS_INFORMATION();
                        STARTUPINFO startupInfo = new STARTUPINFO();
                        startupInfo.cb = Marshal.SizeOf(startupInfo);
                        startupInfo.lpDesktop = @"winsta0\default";
                        startupInfo.dwFlags = STARTF_USESHOWWINDOW;
                        startupInfo.wShowWindow = (short)WINDOW_SHOW_STYLE.Hide;

                        SECURITY_ATTRIBUTES securityAttributes = new SECURITY_ATTRIBUTES();
                        securityAttributes.Length = Marshal.SizeOf(securityAttributes);

                        // declare variables
                        IntPtr hUserTokenDup = IntPtr.Zero;
                        IntPtr hProcessToken = IntPtr.Zero;
                        IntPtr hProcess = IntPtr.Zero;

                        // retrieve handle of the process from its pid
                        hProcess = OpenProcess(MAXIMUM_ALLOWED, false, (uint)p.Id);

                        // retrieve token of the process from its handle
                        if (OpenProcessToken(hProcess, TOKEN_DUPLICATE, ref hProcessToken))
                        {
                            // token duplication ok?
                            if (DuplicateTokenEx(hProcessToken, MAXIMUM_ALLOWED, ref securityAttributes, (int)SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, (int)TOKEN_TYPE.TokenPrimary, ref hUserTokenDup))
                            {
                                // yes...

                                // try to execute process
                                bool boolResult = CreateProcessAsUser(hUserTokenDup,
                                                                      null,
                                                                      Command,
                                                                      ref securityAttributes,
                                                                      ref securityAttributes,
                                                                      false,
                                                                      NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE,
                                                                      IntPtr.Zero,
                                                                      null,
                                                                      ref startupInfo,
                                                                      out processInfo);

                                // execution ok?
                                if (boolResult == false)
                                {
                                    // no... then retrieve error code
                                    int intError = Marshal.GetLastWin32Error();
                                    string strError = new System.ComponentModel.Win32Exception(intError).Message;
                                    stbResponse.AppendFormat("{0}KO (error encountered: {1})", strSep, strError);
                                }

                                else
                                {
                                    // yes...
                                    stbResponse.AppendFormat("{0}OK", strSep);
                                }

                                // close handles
                                CloseHandle(hProcess);
                                CloseHandle(hProcessToken);
                                CloseHandle(hUserTokenDup);
                            }

                            else
                            {
                                // close handles
                                CloseHandle(hProcess);
                                CloseHandle(hProcessToken);

                                stbResponse.AppendFormat("{0}KO (error encountered in token duplication)", strSep);
                            }
                        }

                        else
                        {
                            // close handle
                            CloseHandle(hProcess);

                            stbResponse.AppendFormat("{0}KO (error encountered in token open)", strSep);
                        }
                    }
                }
                else
                {
                    stbResponse.Append("KO (logon screen displayed)");
                }
            }
            catch (Exception ex)
            {
                stbResponse.AppendFormat("{0}KO (error encountered: {1})", strSep, ex.Message.Replace('\r', ' '));
            }

            return stbResponse.ToString();
        }
@+
Répondre

Connectés sur ce fil

 
1 connecté (0 membre et 1 invité) Afficher la liste détaillée des connectés