Solved

Returning an exit code from an MFC based application

Posted on 2003-11-25
16
1,301 Views
Last Modified: 2013-11-20
Hi,

I'm in the process of writing an MFC-based application that runs commands on a remote UNIX server and routes any standard error text back to the Windows client where it is displayed in a pop-up error dialog. I need to be able to pass command line parameters into the client app which are then used to invoke the command on the server. This all works fine.

The problem I've got is that I need to be able to exit the invoking client application with the same exit code as seen on the server. This is because the client app is invoked by a 3rd party SCM tool and it needs to know whether the command succeeded or not. I originally wrote the client as a console application and this was fine - I simply had to call exit() with the relevant exit code. The problem with that approach is that I got a Console Window popping up when the client app was invoked from the 3rd party tool. This looked quite ugly. By rewriting the application as an MFC project then I obviously don't get the Console Window popping up but I can't return an exit code either!

I don't want to use "start" or any similar mechanism to start the client - I just want to run it from the command line (with all its parameters) and have it exit (say when the InitInstance() function finishes) with the appropriate exit code.

I'm using VC++ 6.0

I guess the questions are:

1) Is this even possible with MFC or do I have to use more low-level function calls?
2) Would it be simpler to write a console app and somehow suppress the console window from appearing? if so - how can I do that?

500 points riding on this one!

Cheers
0
Comment
Question by:pgibbs
  • 7
  • 7
16 Comments
 
LVL 13

Expert Comment

by:SteH
ID: 9818689
Override ExitInstance of the CWinApp derived class. The return code of this function is the one reported to the shell.
0
 

Author Comment

by:pgibbs
ID: 9818786
SteH,

Thanks for that. However, all my processing is in InitInstance(). As far as I understand it, ExitInstance() is invoked from Run(). Therefore, overriding ExitInstance() doesn't work in this case.

I *may* not open any windows if everything is working so I don't THINK I want to use Run and the normal message pump scenario. Unless you can advise me otherwise!
0
 
LVL 13

Expert Comment

by:SteH
ID: 9818865
I would guess that ExitInstance is called nevertheless. All per Instance memory allocations need to use ExitInstance for cleanup. This is not needed for a dlg based app but have a try.
0
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 

Author Comment

by:pgibbs
ID: 9818906
I did - doesn't work! Sorry.
0
 
LVL 86

Expert Comment

by:jkr
ID: 9818920
Why not just using 'ExitProcess()' and passing the exit code there? I'd also go for the 'ExitInstance()' approach, just save the exit code in a member of your application object and return that from 'ExitInstance()'.
0
 

Author Comment

by:pgibbs
ID: 9819069
I can put ExitProcess() at the end of Initinstance() but that doesn't get passed back to the calling shell.

Basically, when I invoke my client from the command line, the MS-DOS prompt comes back IMMEDIATELY. The application then runs as a normal windows app. However, the exit code (as displayed by %ERRORLEVEL% in the dos window is 0. That's because the windows app has just launched and is still busily running when the prompt returns.

If we stick to our "launching from a DOS window" scenario - what I'd LIKE to happen is the prompt does not return until I call ExitProcess() (or ExitInstance() or exit() or whatever!) Then, when I DO call one of these functions, the exit status is passed back to the invoking shell in the normal way - just as if I'd called exit() from a console-based app.
0
 
LVL 13

Accepted Solution

by:
SteH earned 500 total points
ID: 9819160
The following works as it returns a value to VS.

int CMyApp::ExitInstance()
{
      // TODO: Add your specialized code here and/or call the base class
      
      CWinApp::ExitInstance(); // do not return value of base class.
    return -15;                          // the value should be stored in a class member.
}

Windows apps don't run in the context of the command prompt. So it will be difficult to get the return type on that command line. Could be easier from another app knowing the process (number) which then waits for the process to end.

0
 

Author Comment

by:pgibbs
ID: 9819277
Yes - I was thinking about using another app and using something like CreateProcess(). However, if I do that, wouldn't it also have to be an MFC app (to prevent the Console appearing)? And if so, doesn't that just put me back to square one?
0
 
LVL 13

Expert Comment

by:SteH
ID: 9823076
How do you start your programs at the moment? Not from a command line? If from a command line there is no need to pop up another console. Just the existing one is sufficient.
0
 

Author Comment

by:pgibbs
ID: 9825280
Well, if I rewrite it as a console app then run it from the command line then it just uses the existing console and everything is fine. If, however, I get our 3rd Party SCM tool (which has a GUI interface) to invoke it then a console pops up. That's what I'm trying to get rid of by writing the app in MFC.

At the moment I've rewritten it as a console app with a FreeConsole() call in main(). This means the console flashes up but very briefly. Still annoying but better. However, it would be better still if I could get the invoking application to wait until the process has exited and for it to be able to read the exit status.

Incidently, someone else is asking the same question: Q_20714251. Must be a popular one!
0
 
LVL 13

Expert Comment

by:SteH
ID: 9825399
MFC apps start in another process so they don't block the other application. Perhaps you have some look with a win32 app which spawns your process and wait for its termination and returning then.
0
 

Author Comment

by:pgibbs
ID: 9828414
Don't win32 apps do the same thing? I've tried /subsystem:windows and /subsystem:console in the link window of VC++ and windows apps (regardless of whether they're win32 or MFC) "return" right away when invoked from the command-line.

I beginning to think that the only viable approach is to write it as a console app but somehow prevent the console window from appearing. I've seen hints around this site (and others) that you can achieve this with #pragma directives to the linker or by changing the default entry point. I've not managed to get this working though - have you any experience of this?
0
 
LVL 13

Expert Comment

by:SteH
ID: 9830219
No, not at all.
0
 
LVL 13

Expert Comment

by:SteH
ID: 9830221
No, not at all.
0
 

Author Comment

by:pgibbs
ID: 11855295
Ooops sorry, completely forgot about this. Apologies to all concerned.

I've awarded the points to SteH since I did end up using ExitInstance() but in a different way.
0

Featured Post

Networking for the Cloud Era

Join Microsoft and Riverbed for a discussion and demonstration of enhancements to SteelConnect:
-One-click orchestration and cloud connectivity in Azure environments
-Tight integration of SD-WAN and WAN optimization capabilities
-Scalability and resiliency equal to a data center

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Generic progress indicator 6 117
conditional code and condition difference 9 84
difference between String.subString() and String.subSequence() 6 234
sumHeights2  challenge 7 114
This is to be the first in a series of articles demonstrating the development of a complete windows based application using the MFC classes.  I’ll try to keep each article focused on one (or a couple) of the tasks that one may meet.   Introductio…
Introduction: Dialogs (2) modeless dialog and a worker thread.  Handling data shared between threads.  Recursive functions. Continuing from the tenth article about sudoku.   Last article we worked with a modal dialog to help maintain informat…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Email security requires an ever evolving service that stays up to date with counter-evolving threats. The Email Laundry perform Research and Development to ensure their email security service evolves faster than cyber criminals. We apply our Threat…

856 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