English 中文(简体)
。 NET 权利较高的启动过程
原标题:.NET Start Process with higher rights

我正试图通过C#申请执行一个含有行政权利的方案,而这种申请只得到用户权利的援引。

法典

        ProcessStartInfo psi;
        try
        {
            psi = new ProcessStartInfo(@"WINZIP32.EXE");

            psi.UseShellExecute = false;
            SecureString pw = new SecureString();
            pw.AppendChar( p );
            pw.AppendChar( a );
            pw.AppendChar( s );
            pw.AppendChar( s );   
            pw.AppendChar( w );
            pw.AppendChar( o );
            pw.AppendChar( r );
            pw.AppendChar( d );
            psi.Password = pw;
            psi.UserName = "administrator";

            Process.Start(psi);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }

它的确开始胜诉,但只拥有用户的权利。 我是否做过错,或者甚至有可能开始权利较高的进程?

谢谢!

Edit: Here is the reason behind the question, maybe it helps to understand what i actually need.

例如,我用“双赢”来获取一个与我守则不正确的总体想法。 实际问题是,我们的公司使用两种方案。 但是,在你开始使用任何版本之前,你需要进口一个包含行政权利的小批文件。 现在我想写一个方案,让用户选择版本、进口批次并开始正确应用。

问题回答

http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.useshellexecute.aspx”rel=“noreferer” ProcessStartInfo.UseShellExecute to true and ProcessStartInfo.Verb to runas:

Process process = null;
ProcessStartInfo processStartInfo = new ProcessStartInfo();

processStartInfo.FileName = "WINZIP32.EXE";

processStartInfo.Verb = "runas";
processStartInfo.WindowStyle = ProcessWindowStyle.Normal;
processStartInfo.UseShellExecute = true;

process = Process.Start(processStartInfo);

这将使申请成为管理人。 不过,国际助老会将促使用户确认。 如果这样做不可取,那么你需要增加一个mani >,以永久提升东道国的原始程序。

You can run a process as another user(even an administrator) using the CreateProcessAsUser function (Win32 API). CreateProcessAsUser accepts a user token as the first parameter, that is an impersonation token.

你们必须利用DLLImport从Windows DLL上载电。

审视一下在我的一个项目中曾经使用的这个例子:

    [StructLayout(LayoutKind.Sequential)]
internal struct PROCESS_INFORMATION
{
    public IntPtr hProcess;
    public IntPtr hThread;
    public uint dwProcessId;
    public uint dwThreadId;
}

[StructLayout(LayoutKind.Sequential)]
internal struct SECURITY_ATTRIBUTES
{
    public uint nLength;
    public IntPtr lpSecurityDescriptor;
    public bool bInheritHandle;
}

[StructLayout(LayoutKind.Sequential)]
public struct STARTUPINFO
{
    public uint cb;
    public string lpReserved;
    public string lpDesktop;
    public string lpTitle;
    public uint dwX;
    public uint dwY;
    public uint dwXSize;
    public uint dwYSize;
    public uint dwXCountChars;
    public uint dwYCountChars;
    public uint dwFillAttribute;
    public uint dwFlags;
    public short wShowWindow;
    public short cbReserved2;
    public IntPtr lpReserved2;
    public IntPtr hStdInput;
    public IntPtr hStdOutput;
    public IntPtr hStdError;

}

internal enum SECURITY_IMPERSONATION_LEVEL
{
    SecurityAnonymous,
    SecurityIdentification,
    SecurityImpersonation,
    SecurityDelegation
}

internal enum TOKEN_TYPE
{
    TokenPrimary = 1,
    TokenImpersonation
}

public class ProcessAsUser
{

    [DllImport("advapi32.dll", SetLastError = true)]
    private static extern bool CreateProcessAsUser(
    IntPtr hToken,
    string lpApplicationName,
    string lpCommandLine,
    ref SECURITY_ATTRIBUTES lpProcessAttributes,
    ref SECURITY_ATTRIBUTES lpThreadAttributes,
    bool bInheritHandles,
    uint dwCreationFlags,
    IntPtr lpEnvironment,
    string lpCurrentDirectory,
    ref STARTUPINFO lpStartupInfo,
    out PROCESS_INFORMATION lpProcessInformation);

    [DllImport("advapi32.dll", EntryPoint = "DuplicateTokenEx", SetLastError = true)]
    private static extern bool DuplicateTokenEx(
    IntPtr hExistingToken,
    uint dwDesiredAccess,
    ref SECURITY_ATTRIBUTES lpThreadAttributes,
    Int32 ImpersonationLevel,
    Int32 dwTokenType,
    ref IntPtr phNewToken);

    [DllImport("advapi32.dll", SetLastError = true)]
    private static extern bool OpenProcessToken(
    IntPtr ProcessHandle,
    UInt32 DesiredAccess,
    ref IntPtr TokenHandle);

    [DllImport("userenv.dll", SetLastError = true)]
    private static extern bool CreateEnvironmentBlock(
    ref IntPtr lpEnvironment,
    IntPtr hToken,
    bool bInherit);

    [DllImport("userenv.dll", SetLastError = true)]
    private static extern bool DestroyEnvironmentBlock(
    IntPtr lpEnvironment);

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

    private const short SW_SHOW = 5;
    private const uint TOKEN_QUERY = 0x0008;
    private const uint TOKEN_DUPLICATE = 0x0002;
    private const uint TOKEN_ASSIGN_PRIMARY = 0x0001;
    private const int GENERIC_ALL_ACCESS = 0x10000000;
    private const int STARTF_USESHOWWINDOW = 0x00000001;
    private const int STARTF_FORCEONFEEDBACK = 0x00000040;
    private const uint CREATE_UNICODE_ENVIRONMENT = 0x00000400;
    private const int STARTF_RUNFULLSCREEN = 0x00000020;

    private static bool LaunchProcessAsUser(string cmdLine, IntPtr token, IntPtr envBlock)
    {
        bool result = false;

        PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
        SECURITY_ATTRIBUTES saProcess = new SECURITY_ATTRIBUTES();
        SECURITY_ATTRIBUTES saThread = new SECURITY_ATTRIBUTES();
        saProcess.nLength = (uint)Marshal.SizeOf(saProcess);
        saThread.nLength = (uint)Marshal.SizeOf(saThread);

        STARTUPINFO si = new STARTUPINFO();
        si.cb = (uint)Marshal.SizeOf(si);

        //if this member is NULL, the new process inherits the desktop
        //and window station of its parent process. If this member is
        //an empty string, the process does not inherit the desktop and
        //window station of its parent process; instead, the system
        //determines if a new desktop and window station need to be created.
        //If the impersonated user already has a desktop, the system uses the
        //existing desktop.

        si.lpDesktop = @"WinSta0Default"; //Modify as needed
        si.dwFlags = STARTF_USESHOWWINDOW | STARTF_FORCEONFEEDBACK;
        si.wShowWindow = SW_SHOW;

        //Set other si properties as required.

        result = CreateProcessAsUser(
        token,
        null,
        cmdLine,
        ref saProcess,
        ref saThread,
        false,
        CREATE_UNICODE_ENVIRONMENT,
        envBlock,
        null,
        ref si,
        out pi);

        if (result == false)
        {
            int error = Marshal.GetLastWin32Error();
            string message = String.Format("CreateProcessAsUser Error: {0}", error);
            Debug.WriteLine(message);

        }

        return result;
    }

    /// <summary>
    /// LaunchProcess As User Overloaded for Window Mode 
    /// </summary>
    /// <param name="cmdLine"></param>
    /// <param name="token"></param>
    /// <param name="envBlock"></param>
    /// <param name="WindowMode"></param>
    /// <returns></returns>
    private static bool LaunchProcessAsUser(string cmdLine, IntPtr token, IntPtr envBlock,uint WindowMode)
    {
        bool result = false;

        PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
        SECURITY_ATTRIBUTES saProcess = new SECURITY_ATTRIBUTES();
        SECURITY_ATTRIBUTES saThread = new SECURITY_ATTRIBUTES();
        saProcess.nLength = (uint)Marshal.SizeOf(saProcess);
        saThread.nLength = (uint)Marshal.SizeOf(saThread);

        STARTUPINFO si = new STARTUPINFO();
        si.cb = (uint)Marshal.SizeOf(si);

        //if this member is NULL, the new process inherits the desktop
        //and window station of its parent process. If this member is
        //an empty string, the process does not inherit the desktop and
        //window station of its parent process; instead, the system
        //determines if a new desktop and window station need to be created.
        //If the impersonated user already has a desktop, the system uses the
        //existing desktop.

        si.lpDesktop = @"WinSta0Default"; //Default Vista/7 Desktop Session
        si.dwFlags = STARTF_USESHOWWINDOW | STARTF_FORCEONFEEDBACK;

        //Check the Startup Mode of the Process 
        if (WindowMode == 1)
            si.wShowWindow = SW_SHOW;
        else if (WindowMode == 2)
        { //Do Nothing
        }
        else if (WindowMode == 3)
            si.wShowWindow = 0; //Hide Window 
        else if (WindowMode == 4)
            si.wShowWindow = 3; //Maximize Window
        else if (WindowMode == 5)
            si.wShowWindow = 6; //Minimize Window
        else
            si.wShowWindow = SW_SHOW;


        //Set other si properties as required.
        result = CreateProcessAsUser(
        token,
        null,
        cmdLine,
        ref saProcess,
        ref saThread,
        false,
        CREATE_UNICODE_ENVIRONMENT,
        envBlock,
        null,
        ref si,
        out pi);

        if (result == false)
        {
            int error = Marshal.GetLastWin32Error();
            string message = String.Format("CreateProcessAsUser Error: {0}", error);
            Debug.WriteLine(message);

        }

        return result;
    }

    private static IntPtr GetPrimaryToken(int processId)
    {
        IntPtr token = IntPtr.Zero;
        IntPtr primaryToken = IntPtr.Zero;
        bool retVal = false;
        Process p = null;

        try
        {
            p = Process.GetProcessById(processId);
        }

        catch (ArgumentException)
        {

            string details = String.Format("ProcessID {0} Not Available", processId);
            Debug.WriteLine(details);
            throw;
        }

        //Gets impersonation token
        retVal = OpenProcessToken(p.Handle, TOKEN_DUPLICATE, ref token);
        if (retVal == true)
        {

            SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES();
            sa.nLength = (uint)Marshal.SizeOf(sa);

            //Convert the impersonation token into Primary token
            retVal = DuplicateTokenEx(
            token,
            TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_QUERY,
            ref sa,
            (int)SECURITY_IMPERSONATION_LEVEL.SecurityIdentification,
            (int)TOKEN_TYPE.TokenPrimary,
            ref primaryToken);

            //Close the Token that was previously opened.
            CloseHandle(token);
            if (retVal == false)
            {
                string message = String.Format("DuplicateTokenEx Error: {0}", Marshal.GetLastWin32Error());
                Debug.WriteLine(message);
            }

        }

        else
        {

            string message = String.Format("OpenProcessToken Error: {0}", Marshal.GetLastWin32Error());
            Debug.WriteLine(message);

        }

        //We ll Close this token after it is used.
        return primaryToken;

    }

    private static IntPtr GetEnvironmentBlock(IntPtr token)
    {

        IntPtr envBlock = IntPtr.Zero;
        bool retVal = CreateEnvironmentBlock(ref envBlock, token, false);
        if (retVal == false)
        {

            //Environment Block, things like common paths to My Documents etc.
            //Will not be created if "false"
            //It should not adversley affect CreateProcessAsUser.

            string message = String.Format("CreateEnvironmentBlock Error: {0}", Marshal.GetLastWin32Error());
            Debug.WriteLine(message);

        }
        return envBlock;
    }

    public static bool Launch(string appCmdLine /*,int processId*/)
    {

        bool ret = false;

        //Either specify the processID explicitly
        //Or try to get it from a process owned by the user.
        //In this case assuming there is only one explorer.exe

        Process[] ps = Process.GetProcessesByName("explorer");
        int processId = -1;//=processId
        if (ps.Length > 0)
        {
            processId = ps[0].Id;
        }

        if (processId > 1)
        {
            IntPtr token = GetPrimaryToken(processId);

            if (token != IntPtr.Zero)
            {

                IntPtr envBlock = GetEnvironmentBlock(token);
                ret = LaunchProcessAsUser(appCmdLine, token, envBlock);
                if (envBlock != IntPtr.Zero)
                    DestroyEnvironmentBlock(envBlock);

                CloseHandle(token);
            }

        }
        return ret;
    }

Ref:
How to start a Process as administrator mode in C#
Elevating process privilege programmatically?

  var psi = new ProcessStartInfo
    {
        FileName = "notepad",
        UserName = "admin",
        Domain = "",
        Password = pass,
        UseShellExecute = true,
        RedirectStandardOutput = true,
        RedirectStandardError = true,
        Verb = "runas";
    };
    Process.Start(psi);

页: 1

var pass = new SecureString();
pass.AppendChar( s );
pass.AppendChar( e );
pass.AppendChar( c );
pass.AppendChar( r );
pass.AppendChar( e );
pass.AppendChar( t );
Process.Start("notepad", "admin", pass, "");

页: 1Vista or higher check

if (System.Environment.OSVersion.Version.Major >= 6)
{
   p.StartInfo.Verb = "runas";
}

Ref: How to run/start a new process with admin rights? ASP.net Forum

Another way is to impersonate the admin user. You can do this by calling the Logon function and impersonate the user whose token you will get then. For impersonating a user in code, look at: WindowsImpersonationContext Class . Use the check http:页: 1www.csharpfriends.com/Forums/ShowPost.aspx?PostID=31611 for GetCurrentUser to see whether impersonation succeeded.

《刑法》:

System.Diagnostics.Process process = null;
System.Diagnostics.ProcessStartInfo processStartInfo;

processStartInfo = new System.Diagnostics.ProcessStartInfo();

processStartInfo.FileName = "regedit.exe";

if (System.Environment.OSVersion.Version.Major >= 6)  页: 1 Windows Vista or higher
{
   processStartInfo.Verb = "runas";
}
else
{
   页: 1 No need to prompt to run as admin
}

processStartInfo.Arguments = "";
processStartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal;
processStartInfo.UseShellExecute = true;

try
{
   process = System.Diagnostics.Process.Start(processStartInfo);
}
catch (Exception ex)
{
   MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
   if (process != null)
   {
      process.Dispose();
   }
}

页: 1Try this with administrator login, i have not tested yet..

[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
            int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        public extern static bool CloseHandle(IntPtr handle);

        页: 1 Test harness.
        页: 1 If you incorporate this code into a DLL, be sure to demand FullTrust.
        [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
        private void button1_Click(object sender, EventArgs e)
        {
            SafeTokenHandle safeTokenHandle;
            const int LOGON32_PROVIDER_DEFAULT = 0;
            页: 1This parameter causes LogonUser to create a primary token.
            const int LOGON32_LOGON_INTERACTIVE = 2;
            bool returnValue = LogonUser("administrator", "", "password",
                LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
                out safeTokenHandle);

            Console.WriteLine("LogonUser called.");

            if (false == returnValue)
            {
                int ret = Marshal.GetLastWin32Error();
                Console.WriteLine("LogonUser failed with error code : {0}", ret);
                throw new System.ComponentModel.Win32Exception(ret);
            }
            using (safeTokenHandle)
            {
                Console.WriteLine("Did LogonUser Succeed? " + (returnValue ? "Yes" : "No"));
                Console.WriteLine("Value of Windows NT token: " + safeTokenHandle);

                页: 1 Check the identity.
                Console.WriteLine("Before impersonation: "
                    + WindowsIdentity.GetCurrent().Name);
                页: 1 Use the token handle returned by LogonUser.
                WindowsIdentity newId = new WindowsIdentity(safeTokenHandle.DangerousGetHandle());
                using (WindowsImpersonationContext impersonatedUser = newId.Impersonate())
                {
                    System.Diagnostics.Process process = null;
                    System.Diagnostics.ProcessStartInfo processStartInfo;


                    processStartInfo = new System.Diagnostics.ProcessStartInfo();

                    processStartInfo.FileName = "regedit.exe";

                    页: 1if (System.Environment.OSVersion.Version.Major >= 6)  页: 1 Windows Vista or higher
                    页: 1{
                    页: 1    processStartInfo.Verb = "runas";
                    页: 1}
                    页: 1else
                    页: 1{
                    页: 1    页: 1 No need to prompt to run as admin
                    页: 1}

                    processStartInfo.Arguments = "";
                    processStartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal;
                    processStartInfo.UseShellExecute = true;

                    try
                    {
                        process = System.Diagnostics.Process.Start(processStartInfo);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    finally
                    {
                        if (process != null)
                        {
                            process.Dispose();
                        }
                    }

                    页: 1 Check the identity.
                    Console.WriteLine("After impersonation: "
                        + WindowsIdentity.GetCurrent().Name);
                }
                页: 1 Releasing the context object stops the impersonation
                页: 1 Check the identity.
                Console.WriteLine("After closing the context: " + WindowsIdentity.GetCurrent().Name);
            }
        }




相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签