远程启动应用程序时,无法从psexec接收异步输出

时间:2017-02-16 17:07:10

标签: c# asynchronous io-redirection psexec

问题

从C#开始执行PSExec并启用异步重定向我的数据接收事件处理程序永远不会被调用。

上下文

我有一个C#应用程序,用于连接和管理同一本地网络上多台其他计算机上的从属应用程序。主应用程序和从属应用程序都是Windows窗体应用程序。我的应用程序的一个功能是能够远程启动从属应用程序。由于这需要一些时间,我希望使用PSexec的输出来显示实际发生的事情。下面是我用来启动远程应用程序的代码。

        ProcessStartInfo start = new ProcessStartInfo();
        start.CreateNoWindow = true;
        start.RedirectStandardError = true;
        start.RedirectStandardOutput = true;
        start.RedirectStandardInput = true;
        start.UseShellExecute = false;
        start.WorkingDirectory = System.Windows.Forms.Application.StartupPath + "\\PSTools\\";
        start.FileName = start.WorkingDirectory + "PsExec.exe";
        start.Arguments = "\\\\" + ComName + " -u \"" + UserName + "\" -p \"" + Password +
            "\" -i -w " + RemoteDrectory + "\" \"" + RemoteDrectory + "\\" + ApplicationName + "\"";
        try
        {
            if (proc != null)
            {
                if (proc.HasExited == false)
                {
                    proc.Kill();
                    proc.Close();
                }
                proc.Dispose();
                proc.OutputDataReceived -= ProcDataReceaved;
                proc.ErrorDataReceived -= ProcDataReceaved;
            }
            proc = new Process();
            proc.EnableRaisingEvents = true;
            proc.OutputDataReceived += new DataReceivedEventHandler(ProcDataReceaved);
            proc.ErrorDataReceived += new DataReceivedEventHandler(ProcErrorReceaved);
            proc = Process.Start(start);
            proc.BeginOutputReadLine();
            proc.BeginErrorReadLine();
        }
        catch(Exception e)
        {
            Console.WriteLine("An error occurred while launching slave application\r\n" + e.ToString());
        }

这实际上具有在远程计算机上启动从属应用程序而没有问题的预期效果。此外,如果我禁用输出重定向,控制台将显示以下内容:

  

PsExec v2.2 - 远程执行进程   版权所有(C)2001-2016马克   Russinovich Sysinternals - www.sysinternals.com

     

在ComName上启动PSEXESVC服务...

建立连接后,最后一行将被删除。如果它现在很重要,事件处理程序定义如下:

    public void ProcDataReceaved(object sender, DataReceivedEventArgs e)
    {
        Console.WriteLine("Data Received from process\r\n" + e.Data);
    }
    public void ProcErrorReceaved(object sender, DataReceivedEventArgs e)
    {
        Console.WriteLine("Data Received from process\r\n" + e.Data);
    }

可选目标

从属应用程序预计不会有太多控制台输出如果有的话。但是,如果我可以通过PSexec输出准备从奴隶的任何输出,那将是甜蜜的。

潜在领导3/8/17

今天我和https://www.poweradmin.com/paexec/的代表进行了交谈,特别是一位名叫大卫的代表。有版本的PSExec(PAExec)使用WriteConsole命令来写入我试图接收的输出。因此,此输出不会写入stderr或stdout,而是直接写入控制台的屏幕缓冲区。显然这并没有说PSExec,因为他们不是同一个人。但它确实表明这可能是我的问题。如果是这样,我需要另一种方法来跟踪连接进度。

2 个答案:

答案 0 :(得分:1)

似乎一切都归结为速度。如果流程运行得太快,事件就不会提升。见下文。

function Cat(opt_data) {
  var data = opt_data || {};


  this.name = data['name'];
  this.fur  = data['fur'];

  this.updateTimestamp(data);
}
Cat.prototype = Object.create({
  updateTimestamp: function(data) {
    this.createdAt = data['created_at'] || new Date();
    this.updatedAt = data['updated_at'] || new Date();
  }
});

答案 1 :(得分:0)

我花了一些时间,但我找到了一个解决方案,我希望是这样的。

使输出变得简单的唯一方法是通过CMD回显结果。

我这样做是为了远程获取可用网站的信息,这些网站仅返回PSExec文本,并且没有返回AppCmd.exe(或psexesvc)返回的文本。

我找到了两个获取数据的解决方案。(字符串被转义,因为有一个带引号的小游戏)

[Hard Way] 使用此命令在远程计算机或本地计算机上创建文本文件**然后只检查我要查找的内容是否存在 "\\\\hostIP -u user -p password cmd /c \"%systemroot%\\system32\\inetsrv\\AppCmd.exe list sites > c:\\sites.txt\""

然后你可以使用命令读出sites.txt文件

\\\\hostIP -u user -p password find \"Site\" c:\\sites.txt"

[简单方法] 使用将反映为控制台输出的ECHO,因此您将能够读取psexesvc返回的文本。 我这样做的方式不起作用就是这样:

"\\\\hostIP -u user -p password cmd ECHO /c \"%systemroot%\\system32\\inetsrv\\AppCmd.exe list sites\""

希望这有帮助,享受。

相关问题