0

我有一个有趣的情况。我正在尝试从命令行运行程序,但由于某种原因我无法以编程方式重定向其输入。我正在运行的可执行文件被调用。Spideroakone.exe。该可执行文件要求输入密码。当我输入密码时,可以说密码是“asd”,我实际上可以看到我以纯文本输入的内容。我收到一条错误消息:

'asd' is not recognized as an internal or external command ...

如果我像这样运行可执行文件:

cmd /c Spideroakone.exe

然后我又看到了同样的问题,我被要求输入密码。然后我输入 asd。但是我看不到我正在输入的内容,并且密码有效并且没有错误。

现在我要做的是编写一个应用程序来执行Spideroak.exe并在标准输入上传递密码。然而,由于 Spideroak 的奇怪行为,我无法将任何标准输入传递给它,也无法读取标准输出。当尝试这样做时,我的应用程序会阻止 writeline 命令。我本来希望在标准输出中看到“密码:”这个词。我已经尝试了一些异步示例和多线程,但这些都不起作用。标准输出缓冲区总是空的。我想知道这个文本是什么我看到的“密码:”如果它没有写入它写入的标准输出?

这是我使用的代码。哪个块就ReadToEnd()行了。这个确切的代码适用于我制作的控制台应用程序,所以这让我觉得我试图执行的可执行文件是以一种奇怪的方式编写的,但在命令行窗口中它工作正常:

Process myProcess = new Process();

myProcess.StartInfo.FileName = @"c:\windows\system32\cmd.exe";
myProcess.StartInfo.Arguments = @"/c ""C:\Program Files\SpiderOakONE\SpiderOakONE.exe"" --headless";
myProcess.StartInfo.UseShellExecute = false;
myProcess.StartInfo.RedirectStandardOutput = true;
myProcess.StartInfo.RedirectStandardInput = true;

myProcess.Start();

string s = myProcess.StandardOutput.ReadToEnd();
myProcess.WaitForExit();

这是确切的调试窗口的屏幕截图和它阻塞的行:

这是我在命令行窗口中看到的:

4

1 回答 1

1

好吧,没有人回应,同时我找到了答案。我没有找到 stdout 和 stdin 不工作的确切原因,但我读了一篇文章,有人抱怨说使用 getch() 用 C 语言编写的旧程序会以这种方式运行。我想以更漂亮的方式来做,但这就是我想出的。基本上将击键发送到控制台窗口。我不确定这是否可行,因为我正在任务计划程序中启动该过程并且没有创建可视窗口,但它似乎工作正常。

我在一个单独的线程中启动该过程:

new Thread(() =>
        {
        Process myProcess = new Process();

        myProcess.StartInfo.FileName = @"c:\windows\system32\cmd.exe";
        myProcess.StartInfo.Arguments = @"/c ""C:\Program Files\SpiderOakONE\SpiderOakONE.exe"" --headless";
        myProcess.StartInfo.UseShellExecute = false;
        myProcess.Start();

        myProcess.WaitForExit();
        }).Start();

然后我枚举所有窗口:

EnumWindows(EnumTheWindows, IntPtr.Zero);

然后我寻找我的进程窗口并将所需的击键发送给它。中间的睡眠是必需的,但它不起作用。我发送的示例密码是“asd”

private static bool EnumTheWindows(IntPtr hWnd, IntPtr lParam)
    {
        uint pidCurWindow;
        uint CurWindowThreadId = GetWindowThreadProcessId(hWnd, out pidCurWindow);
        int CurrentPID = System.Diagnostics.Process.GetCurrentProcess().Id;

        if (pidCurWindow == CurrentPID)
        {
            Thread.Sleep(50);
            PostMessage(hWnd, WM_KEYDOWN, VkKeyScan('a'), 0);
            Thread.Sleep(50);
            PostMessage(hWnd, WM_KEYDOWN, VkKeyScan('s'), 0);
            Thread.Sleep(50);
            PostMessage(hWnd, WM_KEYDOWN, VkKeyScan('d'), 0);
            Thread.Sleep(50);
            PostMessage(hWnd, WM_KEYDOWN, VK_RETURN, 1);
            Thread.Sleep(50);
        }
        return true;
    }

我希望这可以帮助某人节省时间。

于 2017-09-18T09:26:55.967 回答