Solved

Returning an exit code from an MFC based application

Posted on 2003-11-25
16
1,213 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
 

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
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.

 

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

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

In this article, I'll describe -- and show pictures of -- some of the significant additions that have been made available to programmers in the MFC Feature Pack for Visual C++ 2008.  These same feature are in the MFC libraries that come with Visual …
If you use Adobe Reader X it is possible you can't open OLE PDF documents in the standard. The reason is the 'save box mode' in adobe reader X. Many people think the protected Mode of adobe reader x is only to stop the write access. But this fe…
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.
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

758 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

19 Experts available now in Live!

Get 1:1 Help Now