CreateProcess does not return extected value - visual-c++

I want to send the double quote character to my CreateProcess function. How can I do the correct way? I want to send all of this characters: "%h"
CreateProcess(L"C:\\identify -format ",L"\"%h\" trustedsnapshot.png",0,0,TRUE,NORMAL_PRIORITY_CLASS|CREATE_NO_WINDOW,0,0,&sInfo,&pInfo);
note: "identify" is an Imagemagick program.
Here is the full code:
int ExecuteExternalFile()
{
SECURITY_ATTRIBUTES secattr;
ZeroMemory(&secattr,sizeof(secattr));
secattr.nLength = sizeof(secattr);
secattr.bInheritHandle = TRUE;
HANDLE rPipe, wPipe;
//Create pipes to write and read data
CreatePipe(&rPipe,&wPipe,&secattr,0);
STARTUPINFO sInfo;
ZeroMemory(&sInfo,sizeof(sInfo));
PROCESS_INFORMATION pInfo;
ZeroMemory(&pInfo,sizeof(pInfo));
sInfo.cb=sizeof(sInfo);
sInfo.dwFlags=STARTF_USESTDHANDLES;
sInfo.hStdInput=NULL;
sInfo.hStdOutput=wPipe;
sInfo.hStdError=wPipe;
CreateProcess(L"C:\\identify",L" -format \"%h\" trustedsnapshot.png",0,0,TRUE,NORMAL_PRIORITY_CLASS|CREATE_NO_WINDOW,0,0,&sInfo,&pInfo);
CloseHandle(wPipe);
char buf[100];
DWORD reDword;
CString m_csOutput,csTemp;
BOOL res;
do
{
res=::ReadFile(rPipe,buf,100,&reDword,0);
csTemp=buf;
m_csOutput+=csTemp.Left(reDword);
}while(res);
//return m_csOutput;
float fvar;
//fvar = atof((const char *)(LPCTSTR)(m_csOutput)); ori
//fvar=atof((LPCTSTR)m_csOutput);
fvar = _tstof(m_csOutput);
const size_t len = 256;
wchar_t buffer[len] = {};
_snwprintf(buffer, len - 1, L"%d", fvar);
MessageBox(NULL, buffer, L"test print createprocess value", MB_OK);
return fvar;
}
I need this function to return the integer value from the CreateProcess.

The way you wrote it should work OK, or do you have any problems with it?

Your problem is not the quotes. There are two problems with the way you pass parameters to CreateProcess. The first is that the command line passed in the second argument should include the name of the command (that is, it should include the value for "argv[0]"), the second is that the redirection (> testt.txt) is not handled by the CreateProcess API,. Unless c:\identify expects such arguemnts, you should not include this in the command line.

Related

run an EXE file and receive return value from it using VC++

Please i want to creat a program/function in VC++ that allow me to run an EXE file and receive return value from it.
My EXE file tht i want to run is a console Application, it need two argument Arg1 (String) and Arg2 (Float), and return an OutPut (Float).
Something like :
OutPut = MyEXEFile.exe Arg1 Arg2
Command-line arguments come in only one data type: array of C-style string.
Input and output come in only one data type: stream of bytes.
You can supply any command-line and redirection the output if you use CreateProcess from the <windows.h> header file. Other data types such as float will need to be handled the same way you would handle them in a data file.
Here is an example on MSDN: Creating a Child Process with Redirected Input and Output
I find the solution, this is work fine for me, i test it, and it work well.
This is the link of the page where i find the solution, i fixe some errors, and now it ready for implement.
http://www.codeproject.com/Articles/10134/Execute-a-Console-Application-From-VC?fid=172409&fr=26#xx0xx
This is the exemple we need to execute. PS: this line is not a part of the our program, it's just here to explain the algorithm:
MyEXEFile.exe Arg1 Arg2 > sResult
The "MyEXEFile.exe" take two arguments (Arg1 and Arg2) and return a value in the sResult Variable.
Let us program this exemple with Visual C++ using CreatProcess :
CString ExePath="C:\\MyEXEFile.exe";
CString arg1="2";
CString arg2="3";
CString sResult="";
CString strCommandLine = ExePath + " " + arg1 + " " + arg2;
// Call the ExecuteExternalFile function
sResult = ExecuteExternalFile(strCommandLine);
This is the Function who will read the output of MyEXEFile.exe File :
CString ExecuteExternalFile(CString csExecute)
{
SECURITY_ATTRIBUTES secattr;
ZeroMemory(&secattr,sizeof(secattr));
secattr.nLength = sizeof(secattr);
secattr.bInheritHandle = TRUE;
HANDLE rPipe, wPipe;
//Create pipes to write and read data
CreatePipe(&rPipe,&wPipe,&secattr,0);
//
STARTUPINFO sInfo;
ZeroMemory(&sInfo,sizeof(sInfo));
PROCESS_INFORMATION pInfo;
ZeroMemory(&pInfo,sizeof(pInfo));
sInfo.cb=sizeof(sInfo);
sInfo.dwFlags=STARTF_USESTDHANDLES;
sInfo.hStdInput=NULL;
sInfo.hStdOutput=wPipe;
sInfo.hStdError=wPipe;
char command[1024];
strcpy(command,csExecute.GetBuffer(csExecute.GetLength()));
//Create the process here.
CreateProcess(0,command,0,0,TRUE,NORMAL_PRIORITY_CLASS|CREATE_NO_WINDOW,0,0,&sInfo,&pInfo);
CloseHandle(wPipe);
//now read the output pipe here.
char buf[100];
DWORD reDword;
CString m_csOutput,csTemp;
BOOL res;
do
{
res=::ReadFile(rPipe,buf,100,&reDword,0);
csTemp=buf;
m_csOutput+=csTemp.Left(reDword);
}while(res);
CloseHandle( pInfo.hProcess );
CloseHandle( pInfo.hThread );
return m_csOutput;
}
Creating a Child Process with Redirected Input and Output
You are going overkill.
For a command line app, the system command will do what you are looking for.
int status = system("MyEXEFile.exe Arg1 Arg2");

How to convert string to LPSTR in WinAPI function which stores output in string

I am trying to store some contents into a string variable by passing it as a parameter in various types of Windows API functions which accepts variable like char *.
For example, my code is:-
std::string myString;
GetCurrentDirectoryA( MAX_PATH, myString );
Now how do I convert the string variable to LPSTR in this case.
Please see, this function is not meant for passing the contents of string as input, but the function stores some contents into string variable after execution. So, myString.c_str( ) is ruled out.
Edit: I have a workaround solution of removing the concept of string and replacing it with something like
char myString[ MAX_PATH ];
but that is not my objective. I want to make use of string. Is there any way possible?
Also casting like
GetCurrentDirectoryA( MAX_PATH, ( LPSTR ) myString );
is not working.
Thanks in advance for the help.
Usually, people rewrite the Windows functions they need to be std::string friendly, like this:
std::string GetCurrentDirectoryA()
{
char buffer[MAX_PATH];
GetCurrentDirectoryA( MAX_PATH, buffer );
return std::string(buffer);
}
or this for wide char support:
std::wstring GetCurrentDirectoryW()
{
wchar_t buffer[MAX_PATH];
GetCurrentDirectoryW( MAX_PATH, buffer );
return std::wstring(buffer);
}
LPTSTR is defined as TCHAR*, so actually it is just an ordinary C-string, BUT it depends on whether you are working with ASCII or with Unicode in your code. So do
LPTSTR lpStr = new TCHAR[256];
ZeroMemory(lpStr, 256);
//fill the string using i.e. _tcscpy
const char* cpy = myString.c_str();
_tcscpy (lpStr, cpy);
//use lpStr
See here for a reference on _tcscpy and this thread.
Typically, I would read the data into a TCHAR and then copy it into my std::string. That's the simplest way.

How can I get argv from "struct linux_binprm"?

I want to extract all argv from an existing struct linux_binprm. On kernel 3.4, I tried this piece of code: http://www.mail-archive.com/kernelnewbies#nl.linux.org/msg00278.html in do_excve_common, but it doesn't work. It returns (null). What is the problem and how can I get ALL the arguments in a char * string?
. If you want to get the full command line before the binary loader executing in do_execve_common(), you can try following:
there is one argument *argv in the function do_execve_common() parameter table, why bother to get the argv from "struct linux_binprm"? You can use the *argv directly with following codes. In the do_execve_common(), insert some codes as following:
argc = count(argv, MAX_ARG_STRINGS);
i = 0;
while (i < argc)
{
const char __user *str;
int len;
ret = -EFAULT;
str = get_user_arg_ptr(argv, i);
if (IS_ERR(str))
goto out;
len = strnlen_user(str, MAX_ARG_STRLEN);
if (!len)
goto out;
//copy the str to kernel temporary storage
//NOTE: tmp[] is a string array,
// the memory should have been allocated already for strings storage,
// each string is ended with \0
memcpy(tmp[i], str, len)
}
After executing these codes, I think the argv strings will be all saved in tmp[] array.
. While if you want to get the full command line after binary loader executing, I think at this time the argument page has been setup correctly, then you can try following approach to get the full command line:
There is a function proc_pid_cmdline() in ./fs/proc/base.c file, you can re-use most codes in proc_pid_cmdline() function to get the full command line from the argument page.

Converting an int or String to a char array on Arduino

I am getting an int value from one of the analog pins on my Arduino. How do I concatenate this to a String and then convert the String to a char[]?
It was suggested that I try char msg[] = myString.getChars();, but I am receiving a message that getChars does not exist.
To convert and append an integer, use operator += (or member function concat):
String stringOne = "A long integer: ";
stringOne += 123456789;
To get the string as type char[], use toCharArray():
char charBuf[50];
stringOne.toCharArray(charBuf, 50)
In the example, there is only space for 49 characters (presuming it is terminated by null). You may want to make the size dynamic.
Overhead
The cost of bringing in String (it is not included if not used anywhere in the sketch), is approximately 1212 bytes of program memory (flash) and 48 bytes RAM.
This was measured using Arduino IDE version 1.8.10 (2019-09-13) for an Arduino Leonardo sketch.
Risk
There must be sufficient free RAM available. Otherwise, the result may be lockup/freeze of the application or other strange behaviour (UB).
Just as a reference, below is an example of how to convert between String and char[] with a dynamic length -
// Define
String str = "This is my string";
// Length (with one extra character for the null terminator)
int str_len = str.length() + 1;
// Prepare the character array (the buffer)
char char_array[str_len];
// Copy it over
str.toCharArray(char_array, str_len);
Yes, this is painfully obtuse for something as simple as a type conversion, but somehow it's the easiest way.
You can convert it to char* if you don't need a modifiable string by using:
(char*) yourString.c_str();
This would be very useful when you want to publish a String variable via MQTT in arduino.
None of that stuff worked. Here's a much simpler way .. the label str is the pointer to what IS an array...
String str = String(yourNumber, DEC); // Obviously .. get your int or byte into the string
str = str + '\r' + '\n'; // Add the required carriage return, optional line feed
byte str_len = str.length();
// Get the length of the whole lot .. C will kindly
// place a null at the end of the string which makes
// it by default an array[].
// The [0] element is the highest digit... so we
// have a separate place counter for the array...
byte arrayPointer = 0;
while (str_len)
{
// I was outputting the digits to the TX buffer
if ((UCSR0A & (1<<UDRE0))) // Is the TX buffer empty?
{
UDR0 = str[arrayPointer];
--str_len;
++arrayPointer;
}
}
With all the answers here, I'm surprised no one has brought up using itoa already built in.
It inserts the string representation of the integer into the given pointer.
int a = 4625;
char cStr[5]; // number of digits + 1 for null terminator
itoa(a, cStr, 10); // int value, pointer to string, base number
Or if you're unsure of the length of the string:
int b = 80085;
int len = String(b).length();
char cStr[len + 1]; // String.length() does not include the null terminator
itoa(b, cStr, 10); // or you could use String(b).toCharArray(cStr, len);

VC++ read variable length char*

I'm trying to read a variable length char* from the user input. I want to be able to specify the length of the string to read when the function is called;
char *get_char(char *message, unsigned int size) {
bool correct = false;
char *value = (char*)calloc(size+1, sizeof(char));
cout << message;
while(!correct) {
int control = scanf_s("%s", value);
if (control == 1)
correct = true;
else
cout << "Enter a correct value!" <<endl
<< message;
while(cin.get() != '\n');
}
return value;
}
So, upon running the program and trying to enter a string, I get a memory access violation, so I figured something has gone wrong when accessing the allocated space. My first idea was it went wrong because the size of the scanned char * is not specified within scanf(), but it doesn't work with correct length strings either. Even if I give the calloc a size of 1000 and try to enter one character, the program crashes.
What did I do wrong?
You have to specify the size of value to scanf_s:
int control = scanf_s("%s", value, size);
does the trick.
See the documentation of scanf_s for an example of how to use the function:
Unlike scanf and wscanf, scanf_s and wscanf_s require the buffer size to be specified for all input parameters of type c, C, s, S, or [. The buffer size is passed as an additional parameter immediately following the pointer to the buffer or variable.
I omit the rest of the MSDN description here because in the example they're providing, they use scanf instead of scanf_s what is quite irritating...

Resources