Solved

Help using ShellExecuteEx

Posted on 2000-04-10
8
204 Views
Last Modified: 2010-04-02
I have developed two applications (A, B). What I wanted to do is to run B from A. I used the following code, in the application A, to execute B:

SHELLEXECUTEINFO aShellExecStruct;
      aShellExecStruct.cbSize = sizeof(SHELLEXECUTEINFO);
      aShellExecStruct.fMask = SEE_MASK_NOCLOSEPROCESS;
      aShellExecStruct.hwnd = ::GetDesktopWindow();
      aShellExecStruct.lpVerb = "open";
      aShellExecStruct.lpFile ="B.exe";
      aShellExecStruct.lpParameters = lpszPathName;
      aShellExecStruct.lpDirectory = "c:\\temp";
      aShellExecStruct.nShow = SW_SHOWNORMAL;
      
      
      BOOL aResult = ::ShellExecuteEx(&aShellExecStruct);      
      if (aResult)
      {
            HANDLE aProcHandle = aShellExecStruct.hProcess;
            if (aProcHandle)
            {
                  ::WaitForSingleObject(aProcHandle, INFINITE);
            }
      }
      else
      {
            AfxMessageBox("cannot run B");
      }

The problem I have now is that, after closing B, it should return two variables so I could use them in A. I can't figure out how to do this.
Any help will be greatly appreciated,
regards,
Carlos
0
Comment
Question by:qocarlos
  • 3
  • 3
  • 2
8 Comments
 
LVL 86

Accepted Solution

by:
jkr earned 50 total points
Comment Utility
There are several ways of doing IPC, but as you only want to pass 2 variables, I assume named pipes, mailslots and sockets will be quite an overhead.

My suggestions (in order of preference) would be to
- use the registry as an intermediate storage (e.g. HKLM\Software\MyCompany\B) and add the variables as values here or
- let B.exe write the results to a file which can be read by A.

Feel free to ask if you need more information!
0
 
LVL 9

Expert Comment

by:ShaunWilde
Comment Utility
Have you tried GetExitCodeProcess(...)

some pseudo code (i.e. I've not tested this)

if (aProcHandle)
{
   HANDLE hDupProcess;
   ::WaitForSingleObject(aProcHandle, INFINITE);
   DWORD dwExitCode;
   ::GetExitCodeProcess(aProcHandle,&dwExitCode);

}

- you may have to dupicate the process handle before WaitForSingleObject(...)

some more pseudo code

if (aProcHandle)
{
   HANDLE hDupProcess;
   ::DuplicateHandle(...,aProcHandle,...,hDupProcess,...);
   ::WaitForSingleObject(aProcHandle, INFINITE);
   DWORD dwExitCode;
   ::GetExitCodeProcess(hDupProcess,&dwExitCode);

}

0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
It's not necessary to 'DuplicateHandle()' - well, I also thought of using the exit code, but as qocarlos wants to pass two variables, it doesn't seem to be an option (hmm, and we still don't know what type of data these variables contain...)
0
 
LVL 3

Author Comment

by:qocarlos
Comment Utility
Hi jkr,
Thanks for your answer!
I can write the variables from B (either to the registry or to a file) but I need to do it only in the case that B has be executed from A. If B was executed like a stand-alone application,
I don't want to write this file.
How can I know this? and also, which is the best place in B to save the variables (they belong to the document derived class)?

Carlos
0
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 
LVL 3

Author Comment

by:qocarlos
Comment Utility
About the GetExitCodeProcess(...) function:
The variables I need to get are in double floating format (for instance, numbers 123.732 and -89.12)
I think I can't do this with GetExitCodeProcess or am I wrong?

Carlos
0
 
LVL 9

Expert Comment

by:ShaunWilde
Comment Utility
oops sorry - I thought he wanted to get the return code (1 value) not two seperate values :)

yup - registry or file - or you could send a message to the other app with the data in
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
>>If B was executed like a stand-alone
>>application, I don't want to write
>>this file.

You could do this by passing an additional argument on the command line, e.g.

"b.exe /saveresults"

and check it from within b.exe by using

if ( strstr ( GetCommandLine(), "/saveresults"))
{
 // ...
}

I think the best place to store them is either

HKLM\Software\MyCompany\b

or

HKCU\Software\MyCompany\b

The problem with using a file is that both apps have to agree on a location where to store/look for it...

0
 
LVL 3

Author Comment

by:qocarlos
Comment Utility
Thanks!
0

Featured Post

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now