forwarding a file write with ShellExecute in c++ [duplicate] - c++

I'm having a serious problem here. I need to execute a CMD command line via C++ without the console window displaying. Therefore I cannot use system(cmd), since the window will display.
I have tried winExec(cmd, SW_HIDE), but this does not work either. CreateProcess is another one I tried. However, this is for running programs or batch files.
I have ended up trying ShellExecute:
ShellExecute( NULL, "open",
"cmd.exe",
"ipconfig > myfile.txt",
"c:\projects\b",
SW_SHOWNORMAL
);
Can anyone see anything wrong with the above code? I have used SW_SHOWNORMAL until I know this works.
I really need some help with this. Nothing has come to light, and I have been trying for quite a while. Any advice anyone could give would be great :)

Redirecting the output to your own pipe is a tidier solution because it avoids creating the output file, but this works fine:
ShellExecute(0, "open", "cmd.exe", "/C ipconfig > out.txt", 0, SW_HIDE);
You don't see the cmd window and the output is redirected as expected.
Your code is probably failing (apart from the /C thing) because you specify the path as "c:\projects\b" rather than "c:\\projects\\b".

Here is my implementation of a DosExec function that allows to (silently) execute any DOS command and retrieve the generated output as a unicode string.
// Convert an OEM string (8-bit) to a UTF-16 string (16-bit)
#define OEMtoUNICODE(str) CHARtoWCHAR(str, CP_OEMCP)
/* Convert a single/multi-byte string to a UTF-16 string (16-bit).
We take advantage of the MultiByteToWideChar function that allows to specify the charset of the input string.
*/
LPWSTR CHARtoWCHAR(LPSTR str, UINT codePage) {
size_t len = strlen(str) + 1;
int size_needed = MultiByteToWideChar(codePage, 0, str, len, NULL, 0);
LPWSTR wstr = (LPWSTR) LocalAlloc(LPTR, sizeof(WCHAR) * size_needed);
MultiByteToWideChar(codePage, 0, str, len, wstr, size_needed);
return wstr;
}
/* Execute a DOS command.
If the function succeeds, the return value is a non-NULL pointer to the output of the invoked command.
Command will produce a 8-bit characters stream using OEM code-page.
As charset depends on OS config (ex: CP437 [OEM-US/latin-US], CP850 [OEM 850/latin-1]),
before being returned, output is converted to a wide-char string with function OEMtoUNICODE.
Resulting buffer is allocated with LocalAlloc.
It is the caller's responsibility to free the memory used by the argument list when it is no longer needed.
To free the memory, use a single call to LocalFree function.
*/
LPWSTR DosExec(LPWSTR command){
// Allocate 1Mo to store the output (final buffer will be sized to actual output)
// If output exceeds that size, it will be truncated
const SIZE_T RESULT_SIZE = sizeof(char)*1024*1024;
char* output = (char*) LocalAlloc(LPTR, RESULT_SIZE);
HANDLE readPipe, writePipe;
SECURITY_ATTRIBUTES security;
STARTUPINFOA start;
PROCESS_INFORMATION processInfo;
security.nLength = sizeof(SECURITY_ATTRIBUTES);
security.bInheritHandle = true;
security.lpSecurityDescriptor = NULL;
if ( CreatePipe(
&readPipe, // address of variable for read handle
&writePipe, // address of variable for write handle
&security, // pointer to security attributes
0 // number of bytes reserved for pipe
) ){
GetStartupInfoA(&start);
start.hStdOutput = writePipe;
start.hStdError = writePipe;
start.hStdInput = readPipe;
start.dwFlags = STARTF_USESTDHANDLES + STARTF_USESHOWWINDOW;
start.wShowWindow = SW_HIDE;
// We have to start the DOS app the same way cmd.exe does (using the current Win32 ANSI code-page).
// So, we use the "ANSI" version of createProcess, to be able to pass a LPSTR (single/multi-byte character string)
// instead of a LPWSTR (wide-character string) and we use the UNICODEtoANSI function to convert the given command
if (CreateProcessA(NULL, // pointer to name of executable module
UNICODEtoANSI(command), // pointer to command line string
&security, // pointer to process security attributes
&security, // pointer to thread security attributes
TRUE, // handle inheritance flag
NORMAL_PRIORITY_CLASS, // creation flags
NULL, // pointer to new environment block
NULL, // pointer to current directory name
&start, // pointer to STARTUPINFO
&processInfo // pointer to PROCESS_INFORMATION
)){
// wait for the child process to start
for(UINT state = WAIT_TIMEOUT; state == WAIT_TIMEOUT; state = WaitForSingleObject(processInfo.hProcess, 100) );
DWORD bytesRead = 0, count = 0;
const int BUFF_SIZE = 1024;
char* buffer = (char*) malloc(sizeof(char)*BUFF_SIZE+1);
strcpy(output, "");
do {
DWORD dwAvail = 0;
if (!PeekNamedPipe(readPipe, NULL, 0, NULL, &dwAvail, NULL)) {
// error, the child process might have ended
break;
}
if (!dwAvail) {
// no data available in the pipe
break;
}
ReadFile(readPipe, buffer, BUFF_SIZE, &bytesRead, NULL);
buffer[bytesRead] = '\0';
if((count+bytesRead) > RESULT_SIZE) break;
strcat(output, buffer);
count += bytesRead;
} while (bytesRead >= BUFF_SIZE);
free(buffer);
}
}
CloseHandle(processInfo.hThread);
CloseHandle(processInfo.hProcess);
CloseHandle(writePipe);
CloseHandle(readPipe);
// convert result buffer to a wide-character string
LPWSTR result = OEMtoUNICODE(output);
LocalFree(output);
return result;
}

You should use CreateProcess on cmd.exe with the /C parameter to tunnel the ipconfig command. The > does not work per se on the command line. You have to redirect programmatically the stdout.

I have a similar program [windows7 and 10 tested] on github
https://github.com/vlsireddy/remwin/tree/master/remwin
This is server program which
listens on "Local Area Connection" named interface in windows for UDP port (5555) and receives udp packet.
received udp packet content is executed on cmd.exe [please not cmd.exe is NOT closed after running the command and the output string [the output of the executed command] is fedback to the client program over same udp port].
In other words,
command received in udp packet -> parsed udp packet -> executed on cmd.exe -> output sent back on same port to client program
This does not show "console window"
No need for someone to execute manually command on cmd.exe
remwin.exe can be running in background and its a thin server program

To add to #Cédric Françoys answer, I fixed a few things in his code for a Windows build:
Missing function definition:
To make the code compile, add the following function definition:
#define UNICODEtoANSI(str) WCHARtoCHAR(str, CP_OEMCP)
LPSTR WCHARtoCHAR(LPWSTR wstr, UINT codePage) {
int len = (int)wcslen(wstr) + 1;
int size_needed = WideCharToMultiByte(codePage, 0, wstr, len, NULL, 0, NULL, NULL);
LPSTR str = (LPSTR)LocalAlloc(LPTR, sizeof(CHAR) * size_needed);
WideCharToMultiByte(codePage, 0, wstr, len, str, size_needed, NULL, NULL);
return str;
}
Unsafe CRT string function calls:
To make the code compile, replace strcpy and strcat with the following calls
strcpy_s(output, sizeof(output), "");
strcat_s(output, RESULT_SIZE, buffer);
Remove redundant null-termination:
Remove in the do-while loop:
buffer[bytesRead] = '\0';
because strcat_s takes care of that.

You could use
string command = "start /B cmd /c " + myCommand;
system(command.c_str());
Hopefully this works for you

Related

Read process's 'stdout' output in Win32 C++ Desktop Application

I started a Visual C++ Desktop Application (win32) and created a button, that creates a process.
Here is the button code:
INT_PTR CALLBACK Btn_Click(HWND hWnd)
{
wchar_t cmd[] = L"cmd.exe /c testprogram.exe";
STARTUPINFOW startInf;
memset(&startInf, 0, sizeof startInf);
PROCESS_INFORMATION procInf;
memset(&procInf, 0, sizeof procInf);
BOOL p = CreateProcess(NULL, cmd, NULL, NULL, TRUE,
CREATE_NO_WINDOW, NULL, NULL, &startInf, &procInf);
if (p)
{
CloseHandle(procInf.hProcess);
CloseHandle(procInf.hThread);
}
return TRUE;
}
I want to read the process's stdout output (cmd.exe or testprogram.exe) while it is 'running' and set it as a string. After setting the content of a created Text input.
I tried this answer, but it freezes the application. (because of ReadFile() and while() loop)
How to read output from cmd.exe using CreateProcess() and CreatePipe()
I searched the forum for a better answer, but every example is for a console app.
Update:
I can read the output of ping.exe but the window stays frozen until ping.exe closes. the for() loop (and ReadFile()) blocks the window .
wchar_t command[] = L"ping localhost";
STARTUPINFOW startInf;
memset(&startInf, 0, sizeof startInf);
PROCESS_INFORMATION procInf;
memset(&procInf, 0, sizeof procInf);
HANDLE cout_r = NULL;
HANDLE cout_w = NULL;
SECURITY_ATTRIBUTES sec_a;
//memset(&sec_a, 1, sizeof sec_a);
sec_a.nLength = sizeof(SECURITY_ATTRIBUTES);
sec_a.lpSecurityDescriptor = NULL;
CreatePipe(&cout_r, &cout_w, &sec_a, 0);
SetHandleInformation(cout_r, HANDLE_FLAG_INHERIT, 0);
//startInf.cb = sizeof(STARTUPINFO);
startInf.hStdOutput = cout_w;
startInf.dwFlags |= STARTF_USESTDHANDLES;
BOOL p = CreateProcess(NULL, command, NULL, NULL, TRUE,
NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW, NULL, NULL,
&startInf, &procInf);
if (p)
{
CloseHandle(procInf.hProcess);
CloseHandle(procInf.hThread);
CloseHandle(cout_w);
}
else
{
SetWindowTextA(hedit, "Failed");
}
char buf[1024];
CHAR chBuf[4096];
DWORD dwRead;
for (;;)
{
BOOL bSuccess = ReadFile(cout_r, chBuf, 4096, &dwRead, NULL);
if (!bSuccess || dwRead == 0) break;
std::string s(chBuf, dwRead);
std::wstring stemp = std::wstring(s.begin(), s.end());
OutputDebugStringW(stemp.c_str());
}
I searched for asynchronous I/O on ReadFile and pipes.
If anyone can provide me an example on how to do async Readfile without for() loop would be good.
If your UI thread stops pumping messages Windows treats it as frozen. This means you should not perform blocking I/O on this thread.
You could use asynchronous (overlapped) I/O with ReadFile but doing the whole child process operation in another thread is a lot easier. The button press would start the thread and once the thread has read stdout it can signal back to your main window by sending a WM_APP message.

CreateProcess api failing with error code 122 on windows 10

I am using CreateProcess api to start a batch file. The Code works fine on windows 7 but it is failing on Windows 10.
Below is the snippet of code:
CString param; //it holds the very long string of command line arguments
wstring excFile = L"C:\\program files\\BatchFile.bat";
wstring csExcuPath = L"C:\\program files";
wstring exeWithParam = excFile + _T(" ");
exeWithParam = exeWithParam.append(param);
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
TCHAR lpExeWithParam[8191];
_tcscpy_s(lpExeWithParam, exeWithParam.c_str());
BOOL bStatus = CreateProcess(NULL, lpExeWithParam, NULL, NULL, TRUE, CREATE_NEW_CONSOLE | CREATE_BREAKAWAY_FROM_JOB, NULL, csExcuPath.c_str(), &si, &pi);
DWORD err;
if (!bStatus)
{
err = GetLastError();
}
With the above code, it is invoking a batch file which will start an executable with given parameters. This code is not working only Windows 10 in our product.
GetLastError is returning error code 122 which code for error "The data area passed to a system call is too small." How to figure out what is causing this error and how it can be resolved?
However, when using the same code in a sample test application is not giving any error and passing.
Any clue/hint why is causing it to fail on Windows 10.
You need to execute cmd.exe with the .bat file as a parameter, don't try to execute the .bat directly.
Also, you don't need lpExeWithParam, you can pass exeWithParam directly to CreateProcess().
Try something more like this instead:
CString param; //it holds the very long string of command line arguments
...
wstring excFile = L"C:\\program files\\BatchFile.bat";
wstring csExcuPath = L"C:\\program files";
wstring exeWithParam = L"cmd.exe /c \"" + excFile + L"\" ";
exeWithParam.append(param);
STARTUPINFOW si = { sizeof(si) };
PROCESS_INFORMATION pi = {};
BOOL bStatus = CreateProcessW(NULL, &exeWithParam[0]/*or exeWithParam.data() in C++17*/, NULL, NULL, TRUE, CREATE_NEW_CONSOLE | CREATE_BREAKAWAY_FROM_JOB, NULL, csExcuPath.c_str(), &si, &pi);
if (!bStatus)
{
DWORD err = GetLastError();
...
}
else
{
...
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
Error 122 equates to ERROR_INSUFFICIENT_BUFFER and I think the clue here is "it holds the very long string of command line arguments".
Just how long is it? The limit may be lower on Windows 10 - I recommend you experiment (binary chop).
Also, the documentation for CreateProcess states that you must launch cmd.exe explicitly to run a batch file, so I guess you should do what it says.
I think to run a batch file you must set lpApplicationName to cmd.exe and set lpCommandLine to the following arguments: /c plus the name of the batch file

cmd.exe input/output pipe redirection in Unicode

I have got a GUI program which is a "wrapper" to cmd.exe.
From this GUI program I can send and receive command via cmd.exe
I am using pipe redirection, and already read various references:
Creating a Child Process with Redirected Input and Output
Redirect Input and Output of Powershell.exe to Pipes in C++
windows cmd pipe not unicode even with /U switch
First of all I launch an instance of "cmd.exe /U", so that I am telling cmd.exe to generate Unicode output
then I use ReadFile/WriteFile to read and write from/to pipe.
Everything works fine if I use ANSI, But I have got 2 problems related to Unicode:
1) If I want to pass data to the pipe using WriteFile, I have to convert it from Unicode to Ansi first. Passing data in Unicode does not work: specifically, when reading the output after my WriteFile, the cmd outputs a "More?" string.
If I write the input in ANSI, it works fine and cmd correctly outputs the result of the command.
The cmd has been launched with /U switch.
2) While the console output is successfully unicode for internal commands such as cd, dir, etc. when I launch from the cmd an external program such as ping, netstat, ipconfig etc. the output I receive is in ANSI, so I get corrupted data.
I suppose that the /U switch does not have effect when external programs are running through cmd? Is there a possible solution to this, and make everything in the cmd gets output in Unicode?
Here is a sample of my code, I placed comments on lines where the errors are:
bool StartCmdPipe()
{
static SECURITY_ATTRIBUTES SA;
static STARTUPINFOW SI;
static PROCESS_INFORMATION PI;
static HANDLE StdInPipeRead;
static HANDLE StdInPipeWrite;
static HANDLE StdOutPipeRead;
static HANDLE StdOutPipeWrite;
static wstring sWorkDir;
WCHAR* pBuffer;
unsigned long BytesRead;
sWorkDir = _wgetenv(L"SystemDrive");
sWorkDir += L"\\";
bJustOpened = true;
SA.nLength = sizeof(SA);
SA.bInheritHandle = true;
SA.lpSecurityDescriptor = NULL;
if (!CreatePipe(&StdInPipeRead, &StdInPipeWrite, &SA, 0) || !CreatePipe(&StdOutPipeRead, &StdOutPipeWrite, &SA, 0))
{
return false;
}
// Set Pipe for process to create
ZeroMemory(&SI, sizeof(SI));
SI.cb = sizeof(SI);
SI.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
SI.wShowWindow = SW_HIDE;
SI.hStdInput = StdInPipeRead; //GetStdHandle(STD_INPUT_HANDLE);
SI.hStdOutput = StdOutPipeWrite;
SI.hStdError = StdOutPipeWrite;
// Launch cmd process
g_bCreateProcessSuccess = CreateProcessW(
NULL,
L"cmd.exe /U",
NULL,
NULL,
true,
0,
NULL,
(WCHAR*)sWorkDir.c_str(),
&SI,
&PI);
g_sCommandLineInput = L"";
g_bkeepCmdRunning = true;
if (g_bCreateProcessSuccess)
{
do
{
DWORD TotalBytesAvail = 0;
PeekNamedPipe(StdOutPipeRead, 0, 0, 0, &TotalBytesAvail, 0);
pBuffer = (WCHAR*)malloc(TotalBytesAvail);
if (TotalBytesAvail > 0)
{
// First problem is: while internal commands work fine (dir, cd, etc.) and return output in unicode format,
// when I launch another process (ipconfig, netstat, ping, etc.), output is returned in ANSI format.
// Even if I launched cmd.exe with /U switch
ReadFile(StdOutPipeRead, pBuffer, TotalBytesAvail, &BytesRead, NULL);
}
else BytesRead = 0;
if (BytesRead > 0)
{
wprintf(pBuffer);
}
free(pBuffer);
// g_sCommandLineInput is a global wstring variable which gets filled each time user wants to send new command.
if (g_sCommandLineInput.length() > 0)
{
DWORD numberofbyteswritten = 0;
g_sCommandLineInput += L"\n"; //Append /n to make the cmd process interpret the data as a command to launch
// Second problem is, why do I have to send command in ANSI format, even if I launched cmd with the /U switch?
string sCommndLineAnsi = WStringToString(g_sCommandLineInput);
WriteFile(StdInPipeWrite, sCommndLineAnsi.c_str(), sCommndLineAnsi.length() * sizeof(CHAR), &numberofbyteswritten, NULL);
//Reset command
g_sCommandLineInput = L"";
}
Sleep(100);
}
while (g_bkeepCmdRunning);
TerminateProcess(PI.hProcess, 0);
CloseHandle(PI.hThread);
CloseHandle(PI.hProcess);
}
CloseHandle(StdOutPipeRead);
CloseHandle(StdOutPipeWrite);
return true;
}

the system command opens up a command prompt [duplicate]

I'm having a serious problem here. I need to execute a CMD command line via C++ without the console window displaying. Therefore I cannot use system(cmd), since the window will display.
I have tried winExec(cmd, SW_HIDE), but this does not work either. CreateProcess is another one I tried. However, this is for running programs or batch files.
I have ended up trying ShellExecute:
ShellExecute( NULL, "open",
"cmd.exe",
"ipconfig > myfile.txt",
"c:\projects\b",
SW_SHOWNORMAL
);
Can anyone see anything wrong with the above code? I have used SW_SHOWNORMAL until I know this works.
I really need some help with this. Nothing has come to light, and I have been trying for quite a while. Any advice anyone could give would be great :)
Redirecting the output to your own pipe is a tidier solution because it avoids creating the output file, but this works fine:
ShellExecute(0, "open", "cmd.exe", "/C ipconfig > out.txt", 0, SW_HIDE);
You don't see the cmd window and the output is redirected as expected.
Your code is probably failing (apart from the /C thing) because you specify the path as "c:\projects\b" rather than "c:\\projects\\b".
Here is my implementation of a DosExec function that allows to (silently) execute any DOS command and retrieve the generated output as a unicode string.
// Convert an OEM string (8-bit) to a UTF-16 string (16-bit)
#define OEMtoUNICODE(str) CHARtoWCHAR(str, CP_OEMCP)
/* Convert a single/multi-byte string to a UTF-16 string (16-bit).
We take advantage of the MultiByteToWideChar function that allows to specify the charset of the input string.
*/
LPWSTR CHARtoWCHAR(LPSTR str, UINT codePage) {
size_t len = strlen(str) + 1;
int size_needed = MultiByteToWideChar(codePage, 0, str, len, NULL, 0);
LPWSTR wstr = (LPWSTR) LocalAlloc(LPTR, sizeof(WCHAR) * size_needed);
MultiByteToWideChar(codePage, 0, str, len, wstr, size_needed);
return wstr;
}
/* Execute a DOS command.
If the function succeeds, the return value is a non-NULL pointer to the output of the invoked command.
Command will produce a 8-bit characters stream using OEM code-page.
As charset depends on OS config (ex: CP437 [OEM-US/latin-US], CP850 [OEM 850/latin-1]),
before being returned, output is converted to a wide-char string with function OEMtoUNICODE.
Resulting buffer is allocated with LocalAlloc.
It is the caller's responsibility to free the memory used by the argument list when it is no longer needed.
To free the memory, use a single call to LocalFree function.
*/
LPWSTR DosExec(LPWSTR command){
// Allocate 1Mo to store the output (final buffer will be sized to actual output)
// If output exceeds that size, it will be truncated
const SIZE_T RESULT_SIZE = sizeof(char)*1024*1024;
char* output = (char*) LocalAlloc(LPTR, RESULT_SIZE);
HANDLE readPipe, writePipe;
SECURITY_ATTRIBUTES security;
STARTUPINFOA start;
PROCESS_INFORMATION processInfo;
security.nLength = sizeof(SECURITY_ATTRIBUTES);
security.bInheritHandle = true;
security.lpSecurityDescriptor = NULL;
if ( CreatePipe(
&readPipe, // address of variable for read handle
&writePipe, // address of variable for write handle
&security, // pointer to security attributes
0 // number of bytes reserved for pipe
) ){
GetStartupInfoA(&start);
start.hStdOutput = writePipe;
start.hStdError = writePipe;
start.hStdInput = readPipe;
start.dwFlags = STARTF_USESTDHANDLES + STARTF_USESHOWWINDOW;
start.wShowWindow = SW_HIDE;
// We have to start the DOS app the same way cmd.exe does (using the current Win32 ANSI code-page).
// So, we use the "ANSI" version of createProcess, to be able to pass a LPSTR (single/multi-byte character string)
// instead of a LPWSTR (wide-character string) and we use the UNICODEtoANSI function to convert the given command
if (CreateProcessA(NULL, // pointer to name of executable module
UNICODEtoANSI(command), // pointer to command line string
&security, // pointer to process security attributes
&security, // pointer to thread security attributes
TRUE, // handle inheritance flag
NORMAL_PRIORITY_CLASS, // creation flags
NULL, // pointer to new environment block
NULL, // pointer to current directory name
&start, // pointer to STARTUPINFO
&processInfo // pointer to PROCESS_INFORMATION
)){
// wait for the child process to start
for(UINT state = WAIT_TIMEOUT; state == WAIT_TIMEOUT; state = WaitForSingleObject(processInfo.hProcess, 100) );
DWORD bytesRead = 0, count = 0;
const int BUFF_SIZE = 1024;
char* buffer = (char*) malloc(sizeof(char)*BUFF_SIZE+1);
strcpy(output, "");
do {
DWORD dwAvail = 0;
if (!PeekNamedPipe(readPipe, NULL, 0, NULL, &dwAvail, NULL)) {
// error, the child process might have ended
break;
}
if (!dwAvail) {
// no data available in the pipe
break;
}
ReadFile(readPipe, buffer, BUFF_SIZE, &bytesRead, NULL);
buffer[bytesRead] = '\0';
if((count+bytesRead) > RESULT_SIZE) break;
strcat(output, buffer);
count += bytesRead;
} while (bytesRead >= BUFF_SIZE);
free(buffer);
}
}
CloseHandle(processInfo.hThread);
CloseHandle(processInfo.hProcess);
CloseHandle(writePipe);
CloseHandle(readPipe);
// convert result buffer to a wide-character string
LPWSTR result = OEMtoUNICODE(output);
LocalFree(output);
return result;
}
You should use CreateProcess on cmd.exe with the /C parameter to tunnel the ipconfig command. The > does not work per se on the command line. You have to redirect programmatically the stdout.
I have a similar program [windows7 and 10 tested] on github
https://github.com/vlsireddy/remwin/tree/master/remwin
This is server program which
listens on "Local Area Connection" named interface in windows for UDP port (5555) and receives udp packet.
received udp packet content is executed on cmd.exe [please not cmd.exe is NOT closed after running the command and the output string [the output of the executed command] is fedback to the client program over same udp port].
In other words,
command received in udp packet -> parsed udp packet -> executed on cmd.exe -> output sent back on same port to client program
This does not show "console window"
No need for someone to execute manually command on cmd.exe
remwin.exe can be running in background and its a thin server program
To add to #Cédric Françoys answer, I fixed a few things in his code for a Windows build:
Missing function definition:
To make the code compile, add the following function definition:
#define UNICODEtoANSI(str) WCHARtoCHAR(str, CP_OEMCP)
LPSTR WCHARtoCHAR(LPWSTR wstr, UINT codePage) {
int len = (int)wcslen(wstr) + 1;
int size_needed = WideCharToMultiByte(codePage, 0, wstr, len, NULL, 0, NULL, NULL);
LPSTR str = (LPSTR)LocalAlloc(LPTR, sizeof(CHAR) * size_needed);
WideCharToMultiByte(codePage, 0, wstr, len, str, size_needed, NULL, NULL);
return str;
}
Unsafe CRT string function calls:
To make the code compile, replace strcpy and strcat with the following calls
strcpy_s(output, sizeof(output), "");
strcat_s(output, RESULT_SIZE, buffer);
Remove redundant null-termination:
Remove in the do-while loop:
buffer[bytesRead] = '\0';
because strcat_s takes care of that.
You could use
string command = "start /B cmd /c " + myCommand;
system(command.c_str());
Hopefully this works for you

Writing new line character in file

I just want write blank line into the file. i use following code but is not working.
char* RegID;
RegID = "10";
char* mndtime;
mndtime = "10";
char* resourcetype;
resourcetype = "Backup";
char* ressubtype;
ressubtype = "shadowprotect";
char* DataBuffer = new char[100];
StrCpy(DataBuffer,"<wpshadowprotectstatus>");
strcat(DataBuffer,"\n");
strcat(DataBuffer,"<mndtime>");
strcat(DataBuffer,RegID);
strcat(DataBuffer,"<\\mndtime>\n");
strcat(DataBuffer,"<resourcetype>");
strcat(DataBuffer,RegID);
strcat(DataBuffer,"<\\resourcetype>\n");
strcat(DataBuffer,"<ressubtype>");
strcat(DataBuffer,RegID);
strcat(DataBuffer,"<\\ressubtype>\n");
strcat(DataBuffer,"<jobname>");
strcat(DataBuffer,RegID);
strcat(DataBuffer,"<\\jobname>\n");
strcat(DataBuffer,"<jobstarttime>");
strcat(DataBuffer,RegID);
strcat(DataBuffer,"<\\jobstarttime>\n");
HANDLE hFile;
hFile = CreateFile("text.txt", // name of the write
GENERIC_WRITE, // open for writing
0, // do not share
NULL, // default security
CREATE_NEW, // create new file only
FILE_ATTRIBUTE_NORMAL, // normal file
NULL); // no attr. template
if (hFile == INVALID_HANDLE_VALUE)
{
return 0;
}
DWORD dwBytesToWrite = (DWORD)strlen(DataBuffer);
DWORD dwBytesWritten = 0;
BOOL bErrorFlag = FALSE;
bErrorFlag = WriteFile(hFile, // open file handle
DataBuffer, // start of data to write
dwBytesToWrite, // number of bytes to write
&dwBytesWritten, // number of bytes that were written
NULL); // no overlapped structure
but i dont known why new line is not dump in text file.
Note :-
1)I dont want to use std:: library c++.
2)Dont want to use xml parser.
Use \r\n for line breaks on Windows.
And your XML is malformed. XML closing tags use the / character, not the \ character. And you are writing the same RegID variable for all of the XML values instead of using your other variables (mndtime, resourcetype, etc).
Windows?
If so, replace \n with \r\n. For FILE* / iostream it is done automatically by runtime, but not for WriteFile.
And, of course, you need two line endings to get blank line.
BTW, generating long string with strcat has O(N^2) complexity, which is very bad.