Archive: alternative for FindWindow


alternative for FindWindow
hey.

i need to detect if a game is running, that my installer want's to modify.
FindWindow won't work, because the window-caption includes date-information, which is impossible for me to get on any other system than my own.
but i know the .exe-name.
is there any other possibility?
i need to detect the running state, warn the user with a messagebox, and exit the game, if the user clicks on 'yes'.
i know how to do the last thing with SendMessage, but i don't know how to detect the window.


It might set a mutex or you can write a plug-in that gets the list of processes.


It might set a mutex ...
and that means ... ? :)

... or you can write a plug-in that gets the list of processes.
yes, i could, if i'd know how. someone other may do this. :)

another possibility:
is there an api-call availiable to get the window-class of a thread, by his filename?
or some calls one by one to do this job?
so it would look like that:

System::<something>
<something other>
FindWindow <something>

u know what i mean?

You can search for a class name using FindWindow.


You can use Process Explorer (sysinternals) to c if the program creates a mutex...


@joost:
what i mean, is, that the FindWindow command needs the window-caption to find the window-class.
but the caption is variable. the only constant is the filename.
so, i need a command, that gets the window-caption (or class) from the filename.

@anders:
i already asked: what is a mutex?
and i don't know c very well, too less to write a plugin or something similar.

so, if there's an api-call, that i can use with the system-plugin, it'd be very nice :)


cant u just use findwindow and then just find the first few letters to determain the info you need, and leave out the date info?

in regular programming, thats how i would do it.

also seeing the process list would work to find the exe.


hmm, tried it already, but didn't work :)
and, yes, through the taskmanager, _I_ could get the name, but the installer has to do this himself.
or, joost, what do u say, is there any possibility to use wildcards, or just parts of the name?


hmm, as i saw this archive page, i thougt that might be work for me too, in a slightly different way.
how could i detect and perhaps shutdown a task by it's mutex?


FindWindow()
GetWindowThreadProcessId()
GetModuleFileNameEx()

But if this is your game, you can set window user_data
SetWindowLong(hDlg, GWL_USERDATA, YOUR_PROG_ID);

This is my macro

!macro TerminateMgr

loop:
FindWindow $1 "#32770" "" 0 $1
IntCmp $1 0 done
IsWindow $1 0 done
System::Call "user32.dll::GetWindowLong(i r1, i -21) i.r0"
IntCmpU $0 0x4d475201 0 loop loop
SendMessage $1 0x0010 0 0
Sleep 600
goto loop
done:

!macroend


thank u very much!
i'll try that immidiately.
but which code do i have to customize for my application?
and what does your macro detect? the filename or the window-caption, like FindWindow?

another thing i found while searching the inet:
http://eric.aling.***********/PB/tips/pbtip41.htm

this may help too.

and, no, it's not my game.


This macro gives you all top level window handles

!macro FindWin

loop:
FindWindow $1 GAME_WINDOW_CLASS "" 0 $1
IntCmp $1 0 done
IsWindow $1 0 done

#insert here 2 WIN API calls
#GetWindowThreadProcessId() - this gives you process ID for $1 window handle
#GetModuleFileNameEx() - gives path\file for process ID.
#both like System::Call ... - appendix C of NSIS help

# next sends WM_CLOSE to window found - may be you don't need this. And WM_CLOSE may not terminate any application
SendMessage $1 0x0010 0 0

# if few games are running and 1 sec to finish game

Sleep 1000
goto loop
done:

!macroend

I wrote macro (above) to terminate my program both on install and uninstall.


And you can get game window class (string instead of GAME_WINDOW_CLASS I used above) using MS VS tool Spy++ for example.


erm, that's the problem:
the GAME_WINDOW_CLASS is variable.


attached the current development state of my function to check for a running game.
any help with the api-calls would be appreciated.
maybe some of our freaks here know some answers, like kichik or lobo-lunar?


sorry, i forgot onething:
you need to copy the attached dll to your nsis/plugins folder.

(it's no txt, but dll's can't be attached directly. just rename)


GAME_WINDOW_CLASS is not script variable, it's a window class name :) For example Windows Notepad main window class is "Notepad", Internet Explorer Window - "CabinetWClass". If you don't know how to get game window class name (or this may vary), use
FindWindow $1 "" "" 0 $1
instead and check up all top level windows.


yes, but that's the point!!!
from version to version, the window-class name of the game changes!
that's just what i ment. i don't know the complete name.

/edit:
ok, got it, but how do i get all the window-class names?
the first 13 chars of the title are constant, that may help.

/edit2:
i'm sorry, i didn't read your posts carefully enough.
this would work:
GetWindowThreadProcessId()
GetModuleFileNameEx()
but could you tell me the correct syntax for these functions?


if you just need to close active program, then you could use:
KillProcDLL::KillProc "game.exe"
information about it:
http://nsis.sourceforge.net/archive/...php?pageid=271


hmm, that's a very nice thing.

but, i first wanted to pop-up a messagebox, to ask the user.
so, that's not the perfect solution for me. i want to do the steps, that this dll does, myself with nsis.


no problem:)


can you help me with the syntax of these commands?


i think it should work..just edited my own script a little

Function "close"
MessageBox MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON1 "wanna close?" IDNO cancel
KillProcDLL::KillProc "game.exe"
goto +2
cancel:
DetailPrint "you prefered not to close program"
FunctionEnd


but the messagebox should only come up, if the process is really running. so, i can't use the dll. i'll have to check for the process myself.


i found the following function, that imho may be the solution:
http://msdn.microsoft.com/library/de...windowlong.asp
but i always get errors with the attached code.
could someone help me out with the correct syntax?


forgot the attachment ...


finally, i got it working!!!!!
attached the complete script to get all the classnames of every open window.

i'll post it at the archive later.
hope, it'll help other people too.


ok, i postet the interesting part of my final solution at the nsis-archive. check it out here.


Updated Wiki Page


The solution above with the window class name (or a part of it) wont work for me, because the app i search for is a vb6 program and those have all the same window class name 'ThunderRT6FormDC'. So this class name leads not to a unique program.

Is there a way to have an enhanced FindWindow function which works with only a part of the window title? The window title of my program consists of a known and a unknown part, so the classic FindWindow function (which needs the exact window title) wont work.

Greets,
M.


http://nsis.sourceforge.net/FCT_plug-in