문제

다음을 사용하여 프로세스에서 관리자 권한으로 프로세스를 시작하는 방법을 알고 있습니다.

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

여기서 Proc는 System.diagnostics.process입니다. 그러나 어떻게 반대 되는가?

현재 진행중인 프로세스가 이미 상승한 경우 관리자 권한없이 새 프로세스를 어떻게 시작합니까? 보다 정확하게는 Windows 탐색기와 동일한 권한 수준으로 새로운 프로세스를 시작해야하므로 UAC가 비활성화 된 경우 변경 사항이 없지만 UAC가 활성화되어 있지만 프로세스가 높아지면 특정 작업을 수행하지 않아야합니다. 우리는 가상 드라이브를 생성하고 높은 권한으로 만들어지고 Windows 탐색기가 실행되지 않으면 표시되지 않습니다.

제목을 더 나은 것으로 바꾸면 좋은 설명을 할 수 없었습니다.

도움이 되었습니까?

해결책 2

우리는이 코드 프로젝트 기사의 샘플을 사용하게되었습니다. 높은 고도는 응용 프로그램에 좋지 않을 수 있습니다. 설치가 끝날 때 비기화되지 않은 프로세스를 시작하는 방법

지금까지 작동하는 것 같습니다. 나는 그것을 rundll32.exe에 넣습니다. 내 C ++/Win32는 상당히 약해서 실제 구현에 너무 많이 보이지 않았고 사용됩니다. Vista와 Win7에서 x86과 x64 모두에서 작동한다는 것을 확인했습니다 (적어도 우리에게는 x86과 x64는 설치 시간에 확인되고 적절한 것을 사용하는 다른 DLL이 필요합니다).

다른 팁

당신을위한 해결책은 Explorer.exe 프로세스를 사용하는 것입니다.

아이디어는 Windows의 파일 탐색기 프로세스를 사용하여 처리되지 않은 모드로 프로세스를 실행하는 것입니다. explorer.exe (정보). 우리가 출시하고자하는 프로세스가 켜져 있다고 가정 해 봅시다. $TEMP\MyUnElevatedProcess.exe.

따라서 NSIS 코드의 경우 다음과 같이 쓸 것입니다. (그러나 어떤 언어로든 실행할 수 있습니다)

 Exec '"$WINDIR\explorer.exe" "$TEMP\MyUnElevatedProcess.exe"'

예제 코드 (NSIS 설치 프로그램을 사용합니다)

Exec '"$WINDIR\explorer.exe" "$TEMP\MyUnElevatedProcess.exe"'

*** 코드에서 가져온 코드 http://mdb-blog.blogspot.com/2013/01/nsis-lunch-program-as-user-from-uac.html

높은 프로세스에서 비정상적인 프로세스에서 시작하려면 쉘 프로세스의 액세스 토큰을 복사하여 새로운 프로세스를 사용하여 새로운 프로세스를 시작할 수 있습니다.

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

당신이 사용할 수있는 ProcessStartInfo.username 그리고 ProcessStartInfo.Password 계정을 지정하려면 프로세스가 실행되기를 원하는 계정을 지정합니다.

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());
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top