• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1699
  • Last Modified:

Returning an exit code from an MFC based application

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
pgibbs
Asked:
pgibbs
  • 7
  • 7
1 Solution
 
SteHCommented:
Override ExitInstance of the CWinApp derived class. The return code of this function is the one reported to the shell.
0
 
pgibbsAuthor Commented:
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
 
SteHCommented:
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: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

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.

 
pgibbsAuthor Commented:
I did - doesn't work! Sorry.
0
 
jkrCommented:
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
 
pgibbsAuthor Commented:
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
 
SteHCommented:
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
 
pgibbsAuthor Commented:
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
 
SteHCommented:
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
 
pgibbsAuthor Commented:
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
 
SteHCommented:
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
 
pgibbsAuthor Commented:
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
 
SteHCommented:
No, not at all.
0
 
SteHCommented:
No, not at all.
0
 
pgibbsAuthor Commented:
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
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: Microsoft Office 2010

This course will introduce you to the interfaces and features of Microsoft Office 2010 Word, Excel, PowerPoint, Outlook, and Access. You will learn about the features that are shared between all products in the Office suite, as well as the new features that are product specific.

  • 7
  • 7
Tackle projects and never again get stuck behind a technical roadblock.
Join Now