Getting exe's return with ShellExecute

I'm calling ShellExecute to run an EXE file. This EXE file returns a value. How do I catch That return value?

Saranga Amarasinghe

Analyst/Programmer
sRetStat = (long) ShellExecute(NULL, "open", "c:\\windows\\system32\\CrownHoneywellNetworkAPIBridge.exe", cPointName, NULL, SW_SHOWNORMAL);

Open in new window

LVL 2
szarangerAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

jkrCommented:
'ShellExecute()' is inept for that, since it won't give you a process handle. Try rhe following to get the exit code and call it like

string strCmd = "c:\\windows\\system32\\CrownHoneywellNetworkAPIBridge.exe";

strCmd += " ";
strCmd +=  cPointName;

DWORD dwRetCode = ExecuteAndWaitForCompletion(strCmd.c_str());
DWORD ExecuteAndWaitForCompletion   (   LPSTR   pszCmd)
{
   STARTUPINFO         si;
   PROCESS_INFORMATION pi;
 
   BOOL                bRes;
 
   DWORD               dwCode  =   0;
 
   MSG				   msg;
 
   ZeroMemory  (   &si,    sizeof  (   STARTUPINFO));
 
   si.cb           =   sizeof  (   STARTUPINFO);
   si.dwFlags      =   STARTF_USESHOWWINDOW;
   si.wShowWindow  =   SW_SHOWNORMAL;
 
   bRes    =   CreateProcess   (   NULL,
                                   pszCmd,
                                   NULL,
                                   NULL,
                                   TRUE,
                                   NORMAL_PRIORITY_CLASS,
                                   NULL,
                                   NULL,
                                   &si,
                                   &pi
                               );
 
   while   (   WAIT_OBJECT_0   !=  MsgWaitForMultipleObjects   (   1,
                                                                   &pi.hProcess,
                                                                   FALSE,
                                                                   INFINITE,
                                                                   QS_ALLINPUT
                                                               )
           )
           {
               while   (   PeekMessage (   &msg,   NULL,   0,  0,  PM_REMOVE))
                       {
                           DispatchMessage     (   &msg);
                       }
           }
 
   GetExitCodeProcess  (   pi.hProcess,    &dwCode);
 
   CloseHandle (   pi.hProcess);
   CloseHandle (   pi.hThread);
 
   return  (   dwCode);
}

Open in new window

0
szarangerAuthor Commented:
It works perfectly! GREAT help !!! Thank you so much !!!!
0
jkrCommented:
You're most welcome ;o)
0
Cloud Class® Course: Certified Penetration Testing

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

jkrCommented:
BTW, there are alternatives such as 'exec*()', 'spawn*()' or 'system()' (not a good idea in general), but the above is the native windows way with probably the least overhead.
0
szarangerAuthor Commented:
yes it baffles me.....!
0
jkrCommented:
Sorry, if you meant to do that like this, but I have been thinking of a bug and used "admin powers" to accept the Q (which I thought was within what you wanted to do). If you want me to reopen it though, just say so. Ia have informed the sidte admins also that I was acting on my own behalf here.
0
szarangerAuthor Commented:
Yes it is fine with me to reopen it.. Mean while I ran the return value of  :

GetExitCodeProcess  (   pi.hProcess,    &dwCode);

The dwCode doesn't look like returning the correct value
0
jkrCommented:
What the problem with the exit code? What do you get, and what do you expect?
0
jkrCommented:
... and the problem is...?
0
szarangerAuthor Commented:
I have an VB.EXE which I  expect to get a return value. Looks like I have made something worng in my VB.EXE which makes it not returning any value back to calling program
Option Explicit
 
Sub Main()
    
    Dim Args() As String
    Dim State As Long
    
    Args = Split(Command, " ")
    
    State = setState("bisdevebi02", Args(0)) '"ATOM-10-SW"
 
End Sub
 
Public Function setState(ByVal server As String, ByVal pointName As String) As Long
    
    ' Make sure the pointName end's with a '-sw'
    If UCase(Right(pointName, 3)) = "-SW" Then
        
        Dim dataPointValues(1) As Param_Byname_Data
        
        dataPointValues(0).point_name = pointName
        dataPointValues(0).param_name = "op"
        dataPointValues(0).param_offset = 1  'the number of sets of parameters
        dataPointValues(0).param_type = HscNetapi.ParamTypesEnum.DT_INT2
        dataPointValues(0).param_value = 1
        
        setState = rHsc_Param_Value_Put_Bynames(server, 1, dataPointValues)
    
    Else
        setState = -1
    End If

Open in new window

0
jkrCommented:
My VB is a bit rusty, but where are you assigning the exit value?
0
szarangerAuthor Commented:
Well I thinking of writing the exit state to a log file and then use C code to read the value from there. It looks like passing values from one exe to another is difficult
0
jkrCommented:
OK, gave it a try again and it works fine, just as expected:
// getret.cpp
 
#include <windows.h>
#include <stdio.h>
 
DWORD ExecuteAndWaitForCompletion   (   LPSTR   pszCmd)
{
   STARTUPINFO         si;
   PROCESS_INFORMATION pi;
 
   BOOL                bRes;
 
   DWORD               dwCode  =   0;
 
   MSG                             msg;
 
   ZeroMemory  (   &si,    sizeof  (   STARTUPINFO));
 
   si.cb           =   sizeof  (   STARTUPINFO);
   si.dwFlags      =   STARTF_USESHOWWINDOW;
   si.wShowWindow  =   SW_SHOWNORMAL;
 
   bRes    =   CreateProcess   (   NULL,
                                   pszCmd,
                                   NULL,
                                   NULL,
                                   TRUE,
                                   NORMAL_PRIORITY_CLASS,
                                   NULL,
                                   NULL,
                                   &si,
                                   &pi
                               );
 
   while   (   WAIT_OBJECT_0   !=  MsgWaitForMultipleObjects   (   1,
                                                                   &pi.hProcess,
                                                                   FALSE,
                                                                   INFINITE,
                                                                   QS_ALLINPUT
                                                               )
           )
           {
               while   (   PeekMessage (   &msg,   NULL,   0,  0,  PM_REMOVE))
                       {
                           DispatchMessage     (   &msg);
                       }
           }
 
   GetExitCodeProcess  (   pi.hProcess,    &dwCode);
 
   CloseHandle (   pi.hProcess);
   CloseHandle (   pi.hThread);
 
   return  (   dwCode);
}
 
void main ()
{
  DWORD dwRet = ExecuteAndWaitForCompletion("retval.exe");
  printf("RetVal: %d\n", dwRet);
}
 
// retval.cpp
 
int main () 
{
  return 42;
}

Open in new window

0
szarangerAuthor Commented:
It returns the status of the execution of the file . What I have been looking for  was if an exe can obtain a custom build return variable from an exe like output parameter
0
jkrCommented:
>>It returns the status of the execution of the file

Yes, that's what you asked in "This EXE file returns a value. How do I catch That return value?"

>>What I have been looking for  was if an exe can obtain a custom build return
>>variable from an exe like output parameter

Err, by simply returning it from that executable in the manner mentioned above...
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C

From novice to tech pro — start learning today.