Thread: two easy questions

  1. #1
    Registered User
    Join Date
    Feb 2002
    Posts
    465

    two easy questions

    to put my questions in context: i have a server-type program that i want to stay running on my computer. lately, it has been crashing unexpectedly when no one is around to restart it, but i need it to be running at all times.

    what i need is help doing the following:

    1. checking to see if the program is running
    2. running the program if its not

    can anyone give me a quick example of how to do this, or point me in the right direction on how to find it?
    I came up with a cool phrase to put down here, but i forgot it...

  2. #2
    It's full of stars adrianxw's Avatar
    Join Date
    Aug 2001
    Posts
    4,829
    Ultimately, a better solution is to find out why your program is crashing and fix it. It obviously has a bug.

    Otherwise, you need to write a "watchdog" program. This should, at a preset time interval, check to see if the other task is there, and if not start it.

    How you do the first depends on how sophisticated you want it. If, as you say, the task is actually exiting, then using, say FindWindow(), EnumProcesses() or similar will be good enough. If it has exited, the watchdog won't be able to find it and can restart it.

    If the application is hanging, then of course, FindWindow() etc. will work, but that is not what you want. In this case, get a handle to the other processes message loop and use PostMessage() to send it a message to which it should respond within an agreed time, if it does, great, if not, kill the task and restart it.

    Use CreateProcess() to run it again if necessary.

    When I do this kind of thing, I usually have the watchdog sit in the system tray without a window showing.
    Wave upon wave of demented avengers march cheerfully out of obscurity unto the dream.

  3. #3
    Registered User
    Join Date
    Feb 2002
    Posts
    465
    your post was very helpful

    Ultimately, a better solution is to find out why your program is crashing and fix it. It obviously has a bug.
    i agree with you there, but i admit i wasnt entirely honest in my first post. its not my program, its being run on another computer and i have no hand in troubleshooting it to find out the bug, and no one can figure out why it keeps crashing (its for a gaming server, and there are suspicions that its a bug within the game causing it but no one knows what that bug is). i am just offering a simple solution until the bug is found and fixed.

    your reply revealed my ignorance and has spawned a few more questions. first of all, im pretty newbie to windows programming, but i have a good understanding of the basics.

    my first followup question is, how do i get a handle to the other processes message loop?

    also, this is a question ive wanted to ask before but never got around to it:

    When I do this kind of thing, I usually have the watchdog sit in the system tray without a window showing.
    how do i do that?
    I came up with a cool phrase to put down here, but i forgot it...

  4. #4
    Registered User
    Join Date
    Feb 2002
    Posts
    465
    playing around with it, ive run into another problem.

    i can get the program to run (working on figuring out that until i can figure out how to check to see if the program is running), but this program needs to use a .cfg file to get some information. when i try to run this program with my program, it says it cant find the cfg file, but when i run the program normally it starts up just fine.

    is there some added twist i need to know to get this working?
    I came up with a cool phrase to put down here, but i forgot it...

  5. #5
    Registered User johnnie2's Avatar
    Join Date
    Aug 2001
    Posts
    186
    Originally posted by ...
    my first followup question is, how do i get a handle to the other processes message loop?
    Technically, you're not getting a handle to the other process's message loop directly; you're retrieving a handle to the process's window and using that in conjunction with SendMessage() or PostMessage() to ping that process. The fact that you can't modify the game server's message loop code (to add some logic to send a response when pinged by the watchdog program) renders that specific solution much more difficult.

    However, since SendMessage() waits until the recipient processes the message before returning, you could start a new thread within the watchdog program and call SendMessage() with some benign message (like WM_SIZE). If the server is functioning correctly, its procedure will process the message and the call will return quickly. If the server is hanging, SendMessage() will stall indefinitely. Back in the watchdog program, you could create a timer before launching the messaging thread. When you receive a WM_TIMER message in your watchdog's procedure, check to see if the thread is still running. If so, SendMessage() is still waiting for a message to be processed, and the server has most likely crashed. You could then kill the thread and kill and restart the server. If you choose this route, you might want to look into threading and timers. An easy way to check if the thread is still running is to have it enter a critical section. The timer code back in the watchdog window procedure would then attempt to enter the critical section with TryEnterCriticalSection(). If the critical section is successfully acquired (TryEnterCriticalSection() returns a non-zero value), the thread is not running, the message was processed, and the server isn't hanging.

    As for having the watchdog program sit as an icon in the tray, look into Shell_NotifyIcon().

    Originally posted by ...
    when i try to run this program with my program, it says it cant find the cfg file, but when i run the program normally it starts up just fine.
    Are you using CreateProcess() to spawn a game server from within your watchdog program? If so, you'll have to be careful with the lpCurrentDirectory parameter, which specifies the current directory for the new process. If you're setting this to NULL, the new server process receives the watchdog's current directory as its current directory. Then, when the server references the .cfg file by some relative file name (rather than an absolute path like c:\Program Files\GameServer\config.cfg), it searches in some directory off the *watchdog's* current directory, a directory that may not exist, etc. Thus, the server reports that it can't find the .cfg file and exits. If this is the problem, try setting lpCurrentDirectory to the directory in which the server executable resides--that is, the directory in which the server would normally execute.
    "Optimal decisions, once made, do not need to be changed." - Robert Sedgewick, Algorithms in C

  6. #6
    Registered User
    Join Date
    Feb 2002
    Posts
    465
    ok, i have the program opening correctly, but i am still at a loss when it comes to checking the status of the program. do you think you could give a quick example of how to use PostMessage() or SendMessage() to do what i need it to do? i dont have any windows programming referance material, and ive searched on the internet but havent found anything that gives me quite what i need (or explains it to my on my level).

    also, this server periodically saves its current state, and the game freezes up for everyone until the save is completed. will this affect the windows ability to send and recieve messages to my watchdog program?
    I came up with a cool phrase to put down here, but i forgot it...

  7. #7
    Registered User SAMSAM's Avatar
    Join Date
    Nov 2001
    Posts
    218
    EnumProcesses Example by MSDN;

    Code:
    #include <windows.h>
    #include <stdio.h>
    #include "psapi.h"
    
    void PrintProcessNameAndID( DWORD processID )
    {
        char szProcessName[MAX_PATH] = "unknown";
    
        // Get a handle to the process.
    
        HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
                                       PROCESS_VM_READ,
                                       FALSE, processID );
    
        // Get the process name.
    
        if (NULL != hProcess )
        {
            HMODULE hMod;
            DWORD cbNeeded;
    
            if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod), 
                 &cbNeeded) )
            {
                GetModuleBaseName( hProcess, hMod, szProcessName, 
                                   sizeof(szProcessName) );
            }
            else return;
        }
        else return;
    
        // Print the process name and identifier.
    
        printf( "%s (Process ID: %u)\n", szProcessName, processID );
    
        CloseHandle( hProcess );
    }
    
    void main( )
    {
        // Get the list of process identifiers.
    
        DWORD aProcesses[1024], cbNeeded, cProcesses;
        unsigned int i;
    
        if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
            return;
    
        // Calculate how many process identifiers were returned.
    
        cProcesses = cbNeeded / sizeof(DWORD);
    
        // Print the name and process identifier for each process.
    
        for ( i = 0; i < cProcesses; i++ )
            PrintProcessNameAndID( aProcesses[i] );
    }
    The main function obtains a list of processes by using 
    the EnumProcesses function. For each process, main calls the 
    
    PrintProcessNameAndID function, passing it the process identifier.
     PrintProcessNameAndID in turn calls the OpenProcess function
     to obtain the process handle. If OpenProcess fails, the output
     shows only the process identifier. For example, OpenProcess 
    fails for the Idle and CSRSS processes because their 
    access 
    restrictions prevent user-level code from opening them.
     Next,
     PrintProcessNameAndID calls the EnumProcessModules
     function to obtain the module handles. Finally, PrintProcessNameAndID calls the GetModuleBaseName
     function to obtain the name of the executable 
    
    
    
    
    Microsoft Windows CE 3.0   
    
    SendMessage
    This function sends the specified message to a window
     or 
    windows. SendMessage calls the window procedure for
     the specified window and does not return until the 
    window procedure has processed the message. 
    The PostMessage function, in contrast, posts a
     message to a thread's message queue and
     returns immediately. 
    
    LRESULT SendMessage(
    HWND hWnd, 
    UINT Msg, 
    WPARAM wParam, 
    LPARAM lParam ); 
    Parameters 
    
    hWnd 
    [in] Handle to the window whose window procedure will
     receive the message. If this parameter is 
    HWND_BROADCAST, the message is sent to all top-level 
    windows in the system, including disabled or invisible 
    unowned windows, overlapped windows, and pop-up
     windows; but the message is not sent to 
    child windows. 
    Msg 
    [in] Specifies the message to be sent. 
    wParam 
    [in] Specifies additional message-specific information. 
    lParam 
    [in] Specifies additional message-specific information. 
    Return Values
    
    The return value specifies
    FindWindow() example by me.


    hwnd = FindWindow("FileView", TEXT("Afx:400000:8:10011:0:0"));

    handle to window = FindWindow(window caption, class name);
    Last edited by SAMSAM; 03-24-2003 at 06:04 PM.

  8. #8
    It's full of stars adrianxw's Avatar
    Join Date
    Aug 2001
    Posts
    4,829
    If you don't have any reference material and are a little shaky with Win32 API programming, I think using what would have to be a multithreaded watchdog may be a little tricky.

    If this server is actually exiting, then use the other method, it is simpler to acheive.

    You obviously know the module details of the server, so use EnumProcesses() to see if it is there. If not, you now know how to start it.

    >>>
    also, this server periodically saves its current state, and the game freezes up for everyone until the save is completed. will this affect the windows ability to send and recieve messages to my watchdog program?
    <<<

    Yes it would. It sounds like the server is checkpointing within it's main windows loop, causing message processing to be suspended whilst it does so. This is poor design. This server sounds like it needs ditching.
    Wave upon wave of demented avengers march cheerfully out of obscurity unto the dream.

  9. #9
    Registered User
    Join Date
    Feb 2002
    Posts
    465
    its actually a good, and pretty powerful, emulator for a well known MMORPG. but im not on the design team so i have no say in how the program is designed. normally it doesnt need to be saved often, but because of all the crashing, they save about once every 2 hours. the crashing is most likely a bug between the emulator and a 3rd party program, so probably not the fault of the designers.

    anyway, i have already discussed the possibilities with the admin of the server and he says he has already taken into consideration using a watchdog program, but the server crash freezes up the entire computer, keeping the watchdog program from functioning.

    so ive given up in creating this program... maybe now would be a good time to get a windows programming book and learn the basics...
    I came up with a cool phrase to put down here, but i forgot it...

  10. #10
    It's full of stars adrianxw's Avatar
    Join Date
    Aug 2001
    Posts
    4,829
    >>>
    but the server crash freezes up the entire computer, keeping the watchdog program from functioning.
    <<<

    Yes, that would change the ground rules a little.

    Write a program that at a preset interval "pats" the parallel port or some other physical device. Connect up a device to the port whereby if the "pat" doesn't arrive before the device times out, the server power is cycled, an e-mail/SMS is sent to the administrator, a big red light comes on, or similar.

    This is hardware watchdogging. I have also used this in a duty/standby data acquisition system. A small purpose built micro was connected to a serial port on each of the two machines. Both pat the dog at regular intervals, if the "pat" doesn't arrive, a low level ethernet reboot request is sent to the failed machine, if it was the duty machine, the standby gets a "Go" message and takes over.
    Wave upon wave of demented avengers march cheerfully out of obscurity unto the dream.

  11. #11
    Registered User
    Join Date
    Feb 2002
    Posts
    465
    i wouldnt have a clue how to do that, and i dont think i would understand it if you explained it to me...
    I came up with a cool phrase to put down here, but i forgot it...

  12. #12
    It's full of stars adrianxw's Avatar
    Join Date
    Aug 2001
    Posts
    4,829
    LOL!

    When you say the server freezes, does it require a button push to restart it, or can you still CTL-ALT-DEL for example? It is possible that you may be able to run your watchdog software at a higher priority than the server and it's components, so if it goes South, the watchdog would still be able to get some CPU to kill it.

    It is very difficult to advise without a really much fuller description of the system.

    I would still say any resources would be better spent sorting out the server, rather than bodging something up to get round the bug. (Even if the crash is "caused" by an interaction with third party software, the server should handle the exception or whatever and act accordingly).
    Wave upon wave of demented avengers march cheerfully out of obscurity unto the dream.

  13. #13
    Registered User
    Join Date
    Feb 2002
    Posts
    465
    i agree, but i have no imediate access to the server (its about 1000 miles away) and no idea what its doing other than about once every day or two it will go down and i wont be able to play.

    i just wanted to do my part in helping it stay up, since i wont personally be able to troubleshoot any problems its having.
    I came up with a cool phrase to put down here, but i forgot it...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. questions....so many questions about random numbers....
    By face_master in forum C++ Programming
    Replies: 2
    Last Post: 07-30-2009, 08:47 AM
  2. Replies: 1
    Last Post: 06-17-2005, 07:29 AM
  3. Questions on Speed of Execution
    By wavering in forum C Programming
    Replies: 22
    Last Post: 01-20-2002, 02:04 PM
  4. questions about new and delete
    By Unregistered in forum C++ Programming
    Replies: 7
    Last Post: 09-07-2001, 01:48 PM
  5. questions questions questions.....
    By mfc2themax in forum A Brief History of Cprogramming.com
    Replies: 1
    Last Post: 08-14-2001, 07:22 AM