C++ 代码可以在CLR项目中工作,但不能在Win32中工作
我想跑C++ 代码可以在CLR项目中工作,但不能在Win32中工作,c++,visual-studio,winapi,C++,Visual Studio,Winapi,我想跑 std::string exec(const char* cmd) { std::shared_ptr<FILE> pipe(_popen(cmd, "r"), _pclose); if (!pipe) return "ERROR"; char buffer[128]; std::string result = ""; while (!feof(pipe.get())) { if (fgets(buffer, 128,
std::string exec(const char* cmd) {
std::shared_ptr<FILE> pipe(_popen(cmd, "r"), _pclose);
if (!pipe) return "ERROR";
char buffer[128];
std::string result = "";
while (!feof(pipe.get())) {
if (fgets(buffer, 128, pipe.get()) != NULL)
result += buffer;
}
return result;
}
string domainNameList = exec("powershell.exe -Command \"$computers = Get-WsusComputer -All; $computers | foreach-object{ Write-Output $_.FullDomainName; }\"");
我不知道为什么管道会在其中一个断开字符串,而在另一个断开字符串,但我希望在我的Win32应用程序中能够实现这一点,以便我可以链接必要的DLL 如缔约国所述:
\u popen函数创建一个管道,并使用指定的字符串命令异步执行生成的命令处理器副本
因此,在本例中,Win32代码实际上启动了cmd.exe
的一个实例,然后通过管道将字符串连接到该实例
|
对cmd.exe
有特殊意义。由于将命令放入cmd.exe
,需要使用管道,因此它实际上会将|
解释为一个字符串(即使它位于输入字符串中的引号内)。它获取左侧命令的输出,并将其发送到右侧命令的输入。因此,在您的情况下,您实际上是在尝试执行命令:
powershell.exe -Command "$computers = Get-WsusComputer -All; $computers
并将其输出发送到此命令的输入:
foreach-object{ Write-Output $_.FullDomainName; }"
这就是为什么您会得到一个关于foreach对象{
是未知命令的错误
要执行您正在尝试的操作,请尝试转义|
字符,以便在解析期间将其视为普通字符:
exec("powershell.exe -Command \"$computers = Get-WsusComputer -All; $computers ^| foreach-object{ Write-Output $_.FullDomainName; }\"");
有关更多详细信息,请参阅本页:
转义字符
^ Escape character.
在命令符号之前添加转义字符可以将其视为普通文本。
当管道传输或重定向这些字符时,应以转义字符作为前缀:&\<>^ |
e.g. ^\ ^& ^| ^> ^< ^^
要读取输出,您可以告诉CreateProcess()
从CreatePipe()
将启动进程的STDOUT
句柄重定向到匿名管道,然后使用ReadFile()
从中读取:
至于为什么在CLR中一切都正常工作,我不知道。我只能猜测,可能CLR使用的是与
cmd.exe
不同的命令处理器,它以不同的方式解析您的命令字符串。您能提供此函数的示例调用吗?@andlabs我有字符串exec(…)函数,我用最后一行从main调用。domainNameList=exec(“powershell.exe-Command…对,因为我认为错误来自powershell本身…您使用的是与上面发布的exec()
的CLR实现相同的代码,还是使用了不同的exec()
实现?
e.g. ^\ ^& ^| ^> ^< ^^
std::basic_string<TCHAR> cmd = TEXT("cmd.exe /C \"powershell.exe -Command \"\"$computers = Get-WsusComputer -All; $computers | foreach-object{ Write-Output $_.FullDomainName; }\"\"\"");
CreateProcess(NULL, const_cast<TCHAR*>(cmd.c_str()), ...);