从提升的子进程获取错误和标准输出

Posted

技术标签:

【中文标题】从提升的子进程获取错误和标准输出【英文标题】:Get error and standard output from an elevated child process 【发布时间】:2011-10-26 12:36:53 【问题描述】:

我创建了一个进程处理程序,它启动两种类型的进程: 使用管理员用户名和密码提升的一种 另一个无需任何用户名和密码输入即可正常运行。

我正在努力弄清楚如何从提升的流程中获得输出。启动进程的应用程序不需要管理员凭据即可运行,管理员凭据输入到单独的加密 xml 文件中,应用程序在脚本和其他需要管理员凭据的地方使用该文件。

由于应用程序是使用普通用户运行的,因此访问应用程序已启动的提升进程似乎是不可能的。我可以启动一个进程,并且可以轻松检查它是否完成了它应该做的事情,但我无法将它的操作读取到字符串或日志中。

public bool CreateProcessWithAdminRights(string filePath, string commandlineArgument, bool log)

    if (!string.IsNullOrEmpty(filePath) && !string.IsNullOrEmpty(commandlineArgument) && _user.UserDataExsists())
    
        var securePassword = GetSecureString(_user.Password);

        ToolsProvider.Logger.Debug("Creating process with the following filepath: 0 and commandline argument: 1", filePath, commandlineArgument.Replace(_user.Password, "<REPLACED>"));
        ToolsProvider.Logger.Info("Creating Process with admin rights for 0 against 1", _user.Name );

        _proc = new Process
        
            StartInfo =
            
                FileName = @filePath,
                Arguments = commandlineArgument,
                ErrorDialog = false,
                RedirectStandardInput = false,
                RedirectStandardOutput = _log,
                RedirectStandardError = _log,
                UseShellExecute = false,
                CreateNoWindow = true,
                WindowStyle = ProcessWindowStyle.Hidden,
                UserName = _user.Name,
                Password = securePassword,
                Domain = _user.Domain
            
        ;
        _proc.ErrorDataReceived += ErrorDataReceived;
        _proc.OutputDataReceived += OutputDataReceived;
        return true;
    
    return false;

进程开始使用:

private bool StartProcess()

    if (_proc != null)
    
        try
        
            _proc.Start();
            _proc.BeginErrorReadLine();
            _proc.BeginOutputReadLine();
            _proc.WaitForExit();
            _proc.CancelOutputRead();
            _proc.CancelErrorRead();

            if (_standardOutput.Length > 2)
            
                // use writeline, the builder itself will add the DEBUG / info tag
                ToolsProvider.Logger.WriteLine(_standardOutput.ToString());
            

            if (_errorBuilder.Length > 2)
            
                // use writeline, the builder itself will add the DEBUG / info tag
                ToolsProvider.Logger.WriteLine(_errorBuilder.ToString());
            

            return true;
        
        catch (Win32Exception ex)
        
            ToolsProvider.Logger.Error(
                "Missing file while trying to run an action: " + _proc.StartInfo.FileName, ex.Message);
        
    
    ToolsProvider.Logger.Error("");
    return false;

我也尝试过使用 Impersonator 类来启动进程,无论是否添加了管理员凭据到进程中。模仿者类什么也没做,只是告诉我我没有访问权限,尽管我在模仿管理员......

我从这里得到了 Impersonator 类:

http://freshclickmedia.co.uk/2008/11/programmatic-impersonation-in-c/

那么,如何在未提升的进程中从提升的进程中获取标准和错误输出?

【问题讨论】:

你可以使用Named Pipes:msdn.microsoft.com/en-us/library/bb546085.aspx 【参考方案1】:

您只能通过入侵系统和/或利用某些错误和/或编写一些内核级代码(即驱动程序)来规避这些安全措施...

想想这种可能性意味着什么 - 提升将变得毫无意义,因为系统中总会有一些提升的进程可以通过这种方式进行操作......所以答案是否定的......

您应该能够将输出重定向到一个文件(例如&gt; C:\MyLog.txt),然后再读取该文件...

考虑一种不需要这种访问权限的不同设计...

【讨论】:

通过将输出重定向到文件,那你在想什么?通过将其添加到运行的命令或进程对象本身中? 试过了,没用。不过,我正在考虑启动应用程序的其他方式。以普通用户身份启动应用程序后是否可以提升应用程序?还是必须重启? 检查this hack,虽然它是用C++编写的。

以上是关于从提升的子进程获取错误和标准输出的主要内容,如果未能解决你的问题,请参考以下文章

关于标准输入,标准输出,标准错误

如何获取子进程的输出

持久的子进程管道 - 没有读取标准输出

获取 node.js 中所有嵌套子进程的标准输出

阻止写入标准输出

检查 python 中正在运行的子进程的标准输出