Frage

Ich weiß, wie ein Prozess mit Admin-Privilegien von einem Prozess starten mit:

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

wo proc ist ein System.Diagnostics.Process. Aber wie macht man das Gegenteil?

Wenn der Prozess, den Sie in sind bereits erhöht, wie starten Sie den neuen Prozess ohne Admin-Rechte? das neue Verfahren mit dem gleichen Berechtigungsebene wie Windows Explorer, so dass keine Änderung, wenn UAC genauer gesagt, starten wir brauchen, ist deaktiviert, aber wenn UAC aktiviert ist, aber unser Prozess ausgeführt wird erhöht, müssen wir eine bestimmte Operation un-erhöht auszuführen weil wir ein virtuelles Laufwerk und wenn es erstellt mit erhöhten Berechtigungen und Windows Explorer ausgeführt unerhöhten es wird nicht angezeigt.

sind die Schaffung

Fühlen Sie sich frei, den Titel zu etwas ändern besser, ich konnte nicht mit einer guten Beschreibung kommen.

War es hilfreich?

Lösung 2

Am Ende haben wir mit der Probe aus diesem Code Project Artikel: Hohe Höhe kann sein schlecht für Ihre Anwendung: Wie man einen nicht erhöhten Prozess am Ende der Installation starten

Es scheint so weit zu arbeiten, ich sammle sie spritzt in RUNDLL32.EXE, mein C ++ / Win32 ziemlich schwach ist, so dass ich nicht sehen viel in die eigentliche Implementierung, nur nutzt es. Bestätigt, dass es in Vista und Win7 sowohl x86 und x64 funktioniert (zumindest für uns, x86 und x64 erfordern unterschiedliche DLL, die für bei geprüfter Zeit installieren und die richtigen einer verwendet wird).

Andere Tipps

Die Lösung für Sie ist EXPLORER.exe Prozess zu verwenden.

Die Idee ist, den Prozess im UN-erweiterten Modus laufen zu lassen, Datei-Explorer-Prozess explorer.exe mit Fenstern der (

Wenn Sie einen unerhöhten Prozess starten von einem erhöhten, die Sie das Zugriffstoken des Shell-Prozess kopieren könnte und es verwenden, einen neuen Prozess zu starten.

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;
    }
}

Sie können mit ProcessStartInfo.UserName und ProcessStartInfo.Password spezifizieren die erklären Sie Ihren Prozess wollen unter auszuführen.

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());
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top