Question

Je sais comment lancer un processus avec des privilèges d'administrateur d'un processus en utilisant:

proc.StartInfo.UseShellExecute = true;
proc.StartInfo.Verb = "runas";

où proc est un System.Diagnostics.Process. Mais comment faire le contraire?

Si le processus que vous êtes déjà élevé, comment voulez-vous lancer le nouveau processus sans privilèges d'administrateur? Plus précisément, nous devons lancer le nouveau processus avec le même niveau d'autorisation que l'Explorateur Windows, donc pas de changement si UAC est désactivé, mais si l'UAC est activé, mais notre processus est en cours d'exécution élevée, il faut effectuer une certaine opération non élevée parce que nous nous créons un lecteur virtuel et si elle a créé avec des autorisations élevées et explorateur Windows est en cours d'exécution unelevated il ne sera pas affiché.

Sentez-vous libre de changer le titre à quelque chose de mieux, je ne pouvais pas trouver une bonne description.

Était-ce utile?

La solution 2

Nous avons fini par utiliser l'échantillon de ce Code article du projet: haute altitude peut être mauvais pour votre application: Comment commencer un processus non élevé à la fin de la d'installation

Il semble fonctionner à ce jour, je crois qu'il injecte dans RUNDLL32.EXE, mon C ++ / Win32 est assez faible pour que je ne regarde pas trop dans la mise en œuvre réelle, juste son utilisation. A confirmé que cela fonctionne dans Vista et Win7 x86 et x64 (au moins pour nous, x86 et x64 nécessitent différents pour lors de l'installation de dll qui est vérifié temps et celui approprié est utilisé).

Autres conseils

La solution pour vous est d'utiliser processus Explorer.exe.

L'idée est de lancer le processus en mode ELEVATED des Nations Unies, à l'aide de processus explorateur de fichiers de Windows explorer.exe (

Si vous voulez commencer un processus unelevated à partir d'un un élevé, vous pouvez copier le jeton d'accès du processus shell et l'utiliser pour lancer un nouveau processus.

public static class UnelevatedProcessStarter
{
    public static void Start(string cmdArgs)
    {
        // 1. Get the shell
        var shell = NativeMethods.GetShellWindow();
        if (shell == IntPtr.Zero)
        {
            throw new Exception("Could not find shell window");
        }

        // 2. Copy the access token of the process
        NativeMethods.GetWindowThreadProcessId(shell, out uint shellProcessId);
        var hShellProcess = NativeMethods.OpenProcess(0x00000400 /* QueryInformation */, false, (int)shellProcessId);
        if (!NativeMethods.OpenProcessToken(hShellProcess, 2 /* TOKEN_DUPLICATE */, out IntPtr hShellToken))
        {
            throw new Win32Exception();
        }

        // 3. Dublicate the acess token
        uint tokenAccess = 8 /*TOKEN_QUERY*/ | 1 /*TOKEN_ASSIGN_PRIMARY*/ | 2 /*TOKEN_DUPLICATE*/ | 0x80 /*TOKEN_ADJUST_DEFAULT*/ | 0x100 /*TOKEN_ADJUST_SESSIONID*/;
        var securityAttributes = new SecurityAttributes();

        NativeMethods.DuplicateTokenEx(
            hShellToken,
            tokenAccess,
            ref securityAttributes,
            2 /* SecurityImpersonation */,
            1 /* TokenPrimary */,
            out IntPtr hToken);

        // 4. Create a new process with the copied token
        var si = new Startupinfo();
        si.cb = Marshal.SizeOf(si);

        if (!NativeMethods.CreateProcessWithTokenW(
            hToken,
            0x00000002 /* LogonNetcredentialsOnly */,
            null,
            cmdArgs,
            0x00000010 /* CreateNewConsole */,
            IntPtr.Zero,
            null,
            ref si,
            out ProcessInformation _))
        {
            throw new Win32Exception();
        }
    }

    public class NativeMethods
    {

        [DllImport("user32.dll")]
        public static extern IntPtr GetShellWindow();
        [DllImport("user32.dll", SetLastError = true)]
        public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern IntPtr OpenProcess(int processAccess, bool bInheritHandle, int processId);
        [DllImport("advapi32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool OpenProcessToken(IntPtr processHandle, UInt32 desiredAccess, out IntPtr tokenHandle);
        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool DuplicateTokenEx(IntPtr hExistingToken, uint dwDesiredAccess,
            ref SecurityAttributes lpTokenAttributes,
            int impersonationLevel,
            int tokenType,
            out IntPtr phNewToken);
        [DllImport("advapi32", SetLastError = true, CharSet = CharSet.Unicode)]
        public static extern bool CreateProcessWithTokenW(
            IntPtr hToken, int dwLogonFlags,
            string lpApplicationName, string lpCommandLine,
            int dwCreationFlags, IntPtr lpEnvironment,
            string lpCurrentDirectory, [In] ref Startupinfo lpStartupInfo, out ProcessInformation lpProcessInformation);
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct ProcessInformation
    {
        public IntPtr hProcess;
        public IntPtr hThread;
        public int dwProcessId;
        public int dwThreadId;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct SecurityAttributes
    {
        public int nLength;
        public IntPtr lpSecurityDescriptor;
        public int bInheritHandle;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public 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;
    }
}

Vous pouvez utiliser ProcessStartInfo.UserName et ProcessStartInfo.Password pour spécifier la compte que vous voulez que votre processus exécuté sous.

class Program
{
    static void Main(string[] args)
    {
        var psi = new ProcessStartInfo(@"c:\windows\system32\whoami.exe");
        var password = new SecureString();
        password.AppendChar('s');
        password.AppendChar('e');
        password.AppendChar('c');
        password.AppendChar('r');
        password.AppendChar('e');
        password.AppendChar('t');
        psi.Password = password;
        psi.UserName = "username";
        psi.UseShellExecute = false;
        psi.RedirectStandardOutput = true;

        var p = new Process();
        p.StartInfo = psi;
        p.Start();
        p.WaitForExit();

        Console.WriteLine(p.StandardOutput.ReadToEnd());
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top