打开cmd并对其进行读写
我需要启动一个启动命令行的进程(它不应该弹出,所以类似于后台进程)。
然后我需要向其中写入内容并定期读取 cmd 的最后一行。
由于我的 C++ 技能不是很好,我不知道如何实现这一目标。
我以伪代码的方式思考了这样的事情:
startProcess();
writeToCmd();
readFromCmd() { // Call that every given interval (e.g. 1000 ms)
if(returnValue >= 100) {
stopProcess();
}
}
我很确定这不会那么容易。如果有人能在这里帮助我,那就太好了。 该程序适用于 Windows。
根据建议进行编辑: 这就是我到目前为止所做的(我做得有点不同。)
int errorCode;
// Variables for CreateProcess()
SECURITY_ATTRIBUTES sa;
STARTUPINFO si;
PROCESS_INFORMATION pi;
PHANDLE hInRead, hInWrite;
LPDWORD bytesWritten, bytesRead;
// The CommandLine input
TCHAR tcsCommandLine[] = _T("cmd /c format H: /fs:FAT32 /V:device");
//TCHAR tcsCommandLine[] = _T("cmd /c start D:\\foo.txt");
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = true;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.wShowWindow = SW_SHOW; // SW_HIDE FOR PRODUCTION
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
si.hStdInput = hInRead;
si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
ZeroMemory(&pi, sizeof(pi));
errorCode = CreatePipe(hInRead, hInWrite, &sa, 0);
info = GetDriveInfo(m_wsNANDMountPoint);
if(info.m_uSizeInMB > 2048) {
log("Wrong Mounting Point. Device has more than 2GB space.");
return false;
}
else {
// Start Formatting
if(!CreateProcess(NULL, tcsCommandLine,
NULL, NULL,
TRUE, CREATE_NEW_CONSOLE | NORMAL_PRIORITY_CLASS, NULL, NULL,
&si,
&pi)) {
log("CreateProcess failed. Could not format Drive");
return false;
}
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
WriteFile(hInWrite, "#13#10'J'#13#10", 5, bytesWritten, NULL);
CloseHandle(hInWrite);
// Wait until child process exits
WaitForSingleObject(pi.hProcess, 1100);
}
return true;
经过一些调试,我认识到代码不会在 ZeroMemory()
处中断,而是
errorCode = CreatePipe(hInRead, hInWrite, &sa, 0);
在写入位置访问冲突
错误。我不知道我做错了什么。 如果你们能帮助我,那就太好了。
I need to start a process that starts the commandline (it should not pop up, so something like a background process).
Then I need to write stuff to it and periodically read the last line of the cmd.
Since my C++ skills aren't that great I don't know how to achieve this.
In a pseudocode way I thought about something like this:
startProcess();
writeToCmd();
readFromCmd() { // Call that every given interval (e.g. 1000 ms)
if(returnValue >= 100) {
stopProcess();
}
}
I'm pretty sure it'll not be that easy. It would be really great if someone can help me out here.
The programm is for windows.
Edit after the suggestions:
This is what I've done so far (I did it a little bit different.)
int errorCode;
// Variables for CreateProcess()
SECURITY_ATTRIBUTES sa;
STARTUPINFO si;
PROCESS_INFORMATION pi;
PHANDLE hInRead, hInWrite;
LPDWORD bytesWritten, bytesRead;
// The CommandLine input
TCHAR tcsCommandLine[] = _T("cmd /c format H: /fs:FAT32 /V:device");
//TCHAR tcsCommandLine[] = _T("cmd /c start D:\\foo.txt");
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = true;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.wShowWindow = SW_SHOW; // SW_HIDE FOR PRODUCTION
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
si.hStdInput = hInRead;
si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
ZeroMemory(&pi, sizeof(pi));
errorCode = CreatePipe(hInRead, hInWrite, &sa, 0);
info = GetDriveInfo(m_wsNANDMountPoint);
if(info.m_uSizeInMB > 2048) {
log("Wrong Mounting Point. Device has more than 2GB space.");
return false;
}
else {
// Start Formatting
if(!CreateProcess(NULL, tcsCommandLine,
NULL, NULL,
TRUE, CREATE_NEW_CONSOLE | NORMAL_PRIORITY_CLASS, NULL, NULL,
&si,
&pi)) {
log("CreateProcess failed. Could not format Drive");
return false;
}
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
WriteFile(hInWrite, "#13#10'J'#13#10", 5, bytesWritten, NULL);
CloseHandle(hInWrite);
// Wait until child process exits
WaitForSingleObject(pi.hProcess, 1100);
}
return true;
After a little bit of debugging, I recognized that the code doesn't break at ZeroMemory()
, but on
errorCode = CreatePipe(hInRead, hInWrite, &sa, 0);
with an Access violation writing location
error. I have no idea what I'm doing wrong.
It would be really great if you guys could help me out.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在这种情况下,您需要做的是创建一个带有隐藏窗口的控制台。如果您使用 CreateProcess 要启动控制台,您应该能够通过 STARTUPINFO 结构。
下一步是重定向控制台的输入和输出。您可以通过将 3 个控制台句柄(输入、输出、错误)附加到管道并从父进程中读取它来完成此操作。 这篇 MSDN 文章 详细介绍了如何执行此操作。
What you need to do in this instance is to create a console with a hidden window. If you use CreateProcess to launch the console, you should be able to set the visibility of the window through the STARTUPINFO structure.
The next step is to redirect the input and output of your console. You can do this by attaching the 3 console handles (input, output, error) to pipes and reading that from your parent process. This MSDN article describes how to do exactly this.
命令行由您感兴趣的两部分组成。
由于您不需要屏幕可见,因此您的程序中需要这两部分。所以从现在开始,忘掉cmd吧。
要执行程序中的程序,您有多种方法。如果您希望执行行看起来与您在 cmd 中编写的方式完全相同,则可以使用
system
(尽管 Windows 版本的 fork/exec 更有意义)。例如:以
--option
和file.txt
作为参数执行my_prog.exe
。现在是第二个,你说你想从 cmd 读取最后一行。实现这一点的想法是将所有内容的输出放在文件中,而不是放在 cmd 中。
如果您只对每个实例的最后一行感兴趣,您可以将程序的输出重定向到如下文件:
或者如果您想保留整个历史记录,您可以追加而不是覆盖:
如果您还想重定向
stderr
,你可以这样写:符号可能是linuxy的,在你的windows中尝试一下看看它是否有效(在普通cmd中手动)。您还可以在谷歌上搜索“shell重定向”,您会得到很多结果。
无论如何,如果您希望 cmd 的最后一行也包含命令本身,您可以在程序中自己将命令行覆盖/附加到该特定行。
The command line consists of two parts you would be interested in.
Since you don't need the screen to be visible, then you need these two things in your program. So from here on, forget about cmd.
To execute programs in your program, you have many ways. If you want the execution lines to look exactly the way you write it in cmd, you can use
system
(although Windows versions of fork/exec make more sense). For example:Which executes
my_prog.exe
with--option
andfile.txt
as arguments.Now the second one, you said you wanted to read the last line from cmd. The idea to realize this is to have the output of everything in a file, instead of in cmd.
If you are only interested in the last line at every instance, you can redirect the output of your programs to a file like this:
or if you want to keep the whole history, you can append instead of overwrite:
If you also want to redirect
stderr
, you can write:The notation may be linuxy, try it in your windows see if it works (manually in a normal cmd). You could also search google for "shell redirect" and you get a lot of results.
Anyway, if you want the last line of cmd to also include the command itself, you can overwrite/append the command line to that particular yourself in the program.
让我将其添加到这些出色的答案中:
这个很棒的链接演示了控制台读写: http:// /www.adrianxw.dk/SoftwareSite/Consoles/Consoles2.html
要定期执行某些操作,请使用
SetTimer()
。http://msdn.microsoft。 com/en-us/library/windows/desktop/ms644906(v=vs.85).aspx
SetTimer
函数执行一个函数每 x 毫秒。例子:
以下控制台程序的工作原理如下:它使用 SetTimer 设置计时器
然后在消息循环中循环。消息循环接收并处理
WM_TIMER
消息并且每个时间间隔都会调用计时器回调。
只需将您想要完成的事情放入
TimerProc()
函数中即可。Let me add this to these excellent answers:
This great link demonstrates console read and write : http://www.adrianxw.dk/SoftwareSite/Consoles/Consoles2.html
To do stuff periodically, use
SetTimer()
.http://msdn.microsoft.com/en-us/library/windows/desktop/ms644906(v=vs.85).aspx
The
SetTimer
function executes a function every x milliseconds.Example:
The following console program works like this: It sets a timer using SetTimer
then loops in a message loop. The message loop receives and processes
WM_TIMER
messagesand the timer callback also is called for each time interval.
Simply put the stuff you want done in the
TimerProc()
function.