3

I'm trying to write a windows batch file in order to resume a windows process that gets Suspended. I'm using pssuspend (from pstools) to resume the process. However, I'm trying to write windows batch file script that will continually get the status of a process (e.g. myExe.exe). If the script is not suspended, I would like for it to keep checking if it is suspended. If it is suspended, I would like it to run the pssuspend code. I'm unsure how to obtain the Suspend status. So far I have this:

if myExe.exe == "Suspend" (
    pssuspend -r myExe.exe
    suspend_fix.bat
) else (
    suspend_fix.bat
)

Thanks for your help!

Alex Shapiro
  • 31
  • 1
  • 2
  • 1
    Unfortunately, processes cannot be suspended. When you use pssuspend it just suspends all threads. So you can only heuristically detect that a process is suspended. In fact, if another thread happens to be created after suspension Process Explorer no longer allows you to resume because the process is no longer detected as suspended. – usr Jul 22 '14 at 21:40
  • It should be safe to resume a process that isn't actually suspended, so you probably don't need to check. – Harry Johnston Jul 22 '14 at 22:57

1 Answers1

1

Windows services (that are created with the right attributes) can be suspended, but I am not sure how an executable can be suspended, or what exactly you mean by that.

If you mean that the program has been stopped, and when it does, you want to restart it, then here are a couple of code blocks that I have used to determine if a program is running:

1) by checking to see if the exe name exists, i.e., is running.
By the way, I recommend this one from my interpretation of your post:

BOOL ExeExists(char *exe)
{
    HANDLE pss = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0); 
    PROCESSENTRY32 pe = { 0 };
    pe.dwSize = sizeof(pe);
    if (Process32First(pss, &pe)) 
    {
        do
        {
            if (strstr(pe.szExeFile,exe))
            {
                CloseHandle(pss);
                return TRUE;
            }
        }
        while(Process32Next(pss, &pe));
    } 
    CloseHandle(pss);

    return FALSE;
}  

2) by checking to see if the PID exists

BOOL PidExists(int pid)
{ 
    HANDLE pss = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0); 
    PROCESSENTRY32 pe = { 0 };
    pe.dwSize = sizeof(pe);
    if (Process32First(pss, &pe)) 
    {
        do
        {
            if (pe.th32ProcessID == pid)
            {
                CloseHandle(pss);
                return TRUE;
            }
        }
        while(Process32Next(pss, &pe));
    } 
    CloseHandle(pss);

    return FALSE;
}  

By the way this is used to get the process ID (it is defined in winbase.h)
of the application making the call.

int GetProcessIdApp(void)
{
    return GetProcessId(GetCurrentProcess());//defined in WinBase.h
}  

Inside WinBase.h

WINBASEAPI
DWORD
WINAPI
GetProcessId(
    __in HANDLE Process
    );  

In my scenario, An application broadcasts its PID at start up, such that
my monitoring program (the Windows service) can read it, then use it to make an ongoing determination of the application's status. If the app is discovered to be dead, and if other criteria indicate it should still be running, my service will start it back up.

ryyker
  • 22,849
  • 3
  • 43
  • 87
  • This is not bad. You should probably iterate over the threads and resume them. See my comment. – usr Jul 22 '14 at 21:52
  • @usr - Thank you. In my applications, when using threads, I do iterate through, and using these calls, get process status. They are written as discretes so I can use them as needed. – ryyker Jul 22 '14 at 22:06
  • @usr - One note about these: This code segment: `while(Process32Next(pss, &pe));` can be very expensive. Its workload is completely dependent on how many things are running at the time of the call. It can loop through the whole list, before finding the target process on the last loop iteration. I have not found a way to make Windows provide a sorted list of exe names or process IDs :) – ryyker Jul 22 '14 at 22:15