Jump to content

Another program error message

- - - - -

  • Please log in to reply
11 replies to this topic

#1
Gerg? Magyar

Gerg? Magyar

    Newbie

  • Members
  • PipPip
  • 22 posts
How to catch another program error message?


[B]function[/B] GetModuleFileNameEx(hProcess:DWORD;

                             hModule:DWORD;

                             Buffer:PChar;

                             nSize:DWORD):DWORD; [B]stdcall; external[/B] 'PSAPI.DLL'[B] name[/B] 'GetModuleFileNameExA';


[B]procedure[/B] WinEventProc(hWinEventHook :THandle;

                       event         :DWORD;

                       hwnd          :HWND;

                       idObject,

                       idChild       :Longint;

                       idEventThread,

                       dwmsEventTime :DWORD); [B]stdcall;[/B]

[B]var[/B]   

    buffer    :[B]array[/B] [0..MAX_PATH] [B]of[/B] char;

    ModuleName:[B]string[/B];

    ClassName :[B]string[/B];

    Caption   :[B]string[/B];

    pID       :DWORD;

    hProc     :DWORD;

[B]begin[/B]

    SetString(ClassName,buffer,GetClassName(hwnd,buffer,MAX_PATH));

    SetString(Caption,buffer,GetWindowText(hwnd,buffer,MAX_PATH));

    SetString(ModuleName,buffer,GetWindowModuleFileName(hwnd,buffer,MAX_PATH));

    [B]if [/B]ModuleName=EmptyStr [B]then[/B]

      [B]begin[/B]

        GetWindowThreadProcessId(hwnd,@pID);

        hProc:=OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ or SYNCHRONIZE,TRUE,pID);

       [B] if[/B] hProc>0 [B]then[/B]

         [B] try[/B]

            SetString(ModuleName,buffer,GetModuleFileNameEx(hProc,0,buffer,MAX_PATH));

          [B]finally[/B]

            CloseHandle(hProc);

          [B]end;

      end;[/B]


  //TODO[SIZE=4] [B]What is the next step?[/B][/SIZE]

[B]end;[/B]


Edited by Gerg? Magyar, 08 December 2011 - 08:06 AM.


#2
Gerg? Magyar

Gerg? Magyar

    Newbie

  • Members
  • PipPip
  • 22 posts
What I thought is that maybe I should rewrite it, only to watch the errors.
hProc:=OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ or SYNCHRONIZE,TRUE,pID);


#3
Gerg? Magyar

Gerg? Magyar

    Newbie

  • Members
  • PipPip
  • 22 posts
Any other idea?

#4
LuthfiHakim

LuthfiHakim

    Programming God

  • Members
  • PipPipPipPipPipPipPip
  • 765 posts
The only possible solution that I can think of is to install hook to the other program error handler routine. In this case you have to know the address of the routine. The basic hook installing is something like this:
  • Allocate memory in the other program memory space
  • Wrote your code to the allocated memory
  • Patch the original error handler code so at some point it redirects to your code in the allocated memory

Beside allocating memory in the other program, you can use a dll. The use of a dll will simplify things since you can skip the first two steps.

#5
Gerg? Magyar

Gerg? Magyar

    Newbie

  • Members
  • PipPip
  • 22 posts
So what I wrote above, it's can't do anything with it?
Because this procedure is actively watching the program.

#6
LuthfiHakim

LuthfiHakim

    Programming God

  • Members
  • PipPipPipPipPipPipPip
  • 765 posts
If you choose the remote memory allocation path, then you have to use OpenProcess first, with write access. So the OpenProcess is a requirement.

With your current approach, the problem is that there is no uniform way for a program to report error. Some programs chose to display a dialog. Others may only show errors in status box, or some only log errors without showing them immediately.

If you only want to catch when a program showing error dialog, you can try to detect existence of the error dialog window class. Beforehand you must know the class name of the dialog. You can use WinSight32 for this. Then you must poll the program (from its main window for the start) for existence of the window class name. When found, you may want to use WM_GETTEXT to see what is the displayed text. Note that you must familiar with the structure of the windows to make this approach reliable. WinSight32 or similar program will help you with this. In this case however, you don't need OpenProcess.

#7
Gerg? Magyar

Gerg? Magyar

    Newbie

  • Members
  • PipPip
  • 22 posts
Can you show an example?

#8
LuthfiHakim

LuthfiHakim

    Programming God

  • Members
  • PipPipPipPipPipPipPip
  • 765 posts
I don't have handy example right now. But check out these win api, and you will easily see what needs to be done.

  • EnumWindows
  • FindWindow
  • FindWindowEx
  • GetClassName

Basically first you must find the top level window of the monitored application. Use FindWindow for this. After you get this top level window, you can then use FindWindowEx or EnumWindows (nested if need to enter into sublevels) to find your error dialog window. If found, then use WM_GETTEXT message to retrieve actual error message.

#9
Gerg? Magyar

Gerg? Magyar

    Newbie

  • Members
  • PipPip
  • 22 posts
Unfortunately, the problem is that you haven't done it before.

#10
LuthfiHakim

LuthfiHakim

    Programming God

  • Members
  • PipPipPipPipPipPipPip
  • 765 posts
Humm??? How come it's me causing the problem? Lol. I just don't have time to extract codes from my own application just for so simple example. Like I said, it is very easy and straightforward.

Have you tried to read more on win api that I have just given you and figure out how to use them? Will take you less than an hour to come up with simple demo project using those apis.

#11
Gerg? Magyar

Gerg? Magyar

    Newbie

  • Members
  • PipPip
  • 22 posts
Sorry not you!

This list all process: (only button click)

procedure TForm2.Button1Click(Sender: TObject);

var

  MyHandle: THandle;

  Struct: TProcessEntry32;

begin

  Memo1.Clear;

  try

    MyHandle:=CreateToolHelp32SnapShot(TH32CS_SNAPPROCESS, 0);

    Struct.dwSize:=Sizeof(TProcessEntry32);

    if Process32First(MyHandle, Struct) then

      Memo1.Lines.Add(Struct.szExeFile);

    while Process32Next(MyHandle, Struct) do

      Memo1.Lines.Add(Struct.szExeFile);

  except

    ShowMessage('Error showing process list');

  end;

end;


This is would it?
Delphi Inter Process Communication (IPC) using SendMessage

Edited by Gerg? Magyar, 10 December 2011 - 08:06 AM.


#12
LuthfiHakim

LuthfiHakim

    Programming God

  • Members
  • PipPipPipPipPipPipPip
  • 765 posts
Why don't you explain the real problem you want to solve? Because it looks like you want to catch error message from any running program. There is no single good solution for this task, because there is no uniform way for any program to handle/record/report error. Therefore you only can build solution based on what program you want to monitor. Solution for one program hardly usable for another.

If you still need to catch error from most programs (and if the programs were written with quality :p ), you try to monitor windows logs. Manually you can view the logs using Event Viewer. See Control Panel - Administrative tools - Event viewer. Many good programs uses windows log to record their activities and problems. In this case you don't have to directly open/monitor the corresponding program handle or window handle. Just monitor windows log. However, again, note that not all programs use windows log to record their problem.




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users