I would like to execute several cmd
commands in C++ with the same shell. I precise the same shell because I would like to execute for example a command cd ..
and dir
or something else. I found this code on internet but I can't use it because when I launch it, it prompt an error : Exception thrown at 0x67B21010 (KernelBase.dll) in Shell.exe: 0xC0000005: Access violation writing location 0x007C6152.
What I am doing wrong ? This is the source code :
#include <iostream>
#include <atlstr.h>
CStringA shell(const wchar_t* cmd)
{
CStringA result;
HANDLE hPipeRead, hPipeWrite;
SECURITY_ATTRIBUTES saAttr = { sizeof(SECURITY_ATTRIBUTES) };
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
if (!CreatePipe(&hPipeRead, &hPipeWrite, &saAttr, 0))
return result;
STARTUPINFOW si = { sizeof(STARTUPINFOW) };
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
si.hStdOutput = hPipeWrite;
si.hStdError = hPipeWrite;
si.wShowWindow = SW_HIDE;
PROCESS_INFORMATION pi = { 0 };
BOOL fSuccess = CreateProcessW(NULL, (LPWSTR)cmd, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
if (!fSuccess)
{
CloseHandle(hPipeWrite);
CloseHandle(hPipeRead);
return result;
}
bool bProcessEnded = false;
for (; !bProcessEnded;)
{
bProcessEnded = WaitForSingleObject(pi.hProcess, 50) == WAIT_OBJECT_0;
for (;;)
{
char buf[1024];
DWORD dwRead = 0;
DWORD dwAvail = 0;
if (!::PeekNamedPipe(hPipeRead, NULL, 0, NULL, &dwAvail, NULL))
break;
if (!dwAvail)
break;
if (!::ReadFile(hPipeRead, buf, min(sizeof(buf) - 1, dwAvail), &dwRead, NULL) || !dwRead)
break;
buf[dwRead] = 0;
result += buf;
}
}
CloseHandle(hPipeWrite);
CloseHandle(hPipeRead);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return result;
}
int main()
{
std::cout << "Hello World!\n";
std::wcout << shell(L"cmd.exe") << std::endl;
std::wcout << shell(L"cd ..") << std::endl;
std::wcout << shell(L"dir") << std::endl;
}
User contributions licensed under CC BY-SA 3.0