- NSIS Discussion
- alternative for FindWindow
Archive: alternative for FindWindow
Comm@nder21
7th March 2004 15:19 UTC
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.
Joost Verburg
7th March 2004 16:29 UTC
It might set a mutex or you can write a plug-in that gets the list of processes.
Comm@nder21
7th March 2004 16:31 UTC
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. :)
Comm@nder21
7th March 2004 19:05 UTC
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?
Joost Verburg
7th March 2004 19:08 UTC
You can search for a class name using FindWindow.
Anders
8th March 2004 18:18 UTC
You can use Process Explorer (sysinternals) to c if the program creates a mutex...
Comm@nder21
8th March 2004 19:16 UTC
@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 :)
MindlessOath
8th March 2004 20:49 UTC
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.
Comm@nder21
8th March 2004 21:03 UTC
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?
Comm@nder21
11th March 2004 17:27 UTC
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?
Takhir
26th March 2004 11:54 UTC
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
Comm@nder21
27th March 2004 17:09 UTC
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.
Takhir
27th March 2004 17:41 UTC
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.
Takhir
27th March 2004 17:44 UTC
And you can get game window class (string instead of GAME_WINDOW_CLASS I used above) using MS VS tool Spy++ for example.
Comm@nder21
27th March 2004 17:52 UTC
erm, that's the problem:
the GAME_WINDOW_CLASS is variable.
Comm@nder21
27th March 2004 18:12 UTC
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?
Comm@nder21
27th March 2004 18:20 UTC
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)
Takhir
27th March 2004 19:41 UTC
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.
Comm@nder21
27th March 2004 20:27 UTC
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?
atsuk
27th March 2004 20:57 UTC
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
Comm@nder21
27th March 2004 21:03 UTC
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.
atsuk
27th March 2004 21:04 UTC
no problem:)
Comm@nder21
27th March 2004 21:09 UTC
can you help me with the syntax of these commands?
atsuk
27th March 2004 21:14 UTC
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
Comm@nder21
27th March 2004 21:17 UTC
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.
Comm@nder21
28th March 2004 10:51 UTC
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?
Comm@nder21
28th March 2004 10:54 UTC
forgot the attachment ...
Comm@nder21
28th March 2004 11:04 UTC
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.
Comm@nder21
30th March 2004 18:17 UTC
ok, i postet the interesting part of my final solution at the nsis-archive. check it out here.
Comm@nder21
27th February 2006 20:10 UTC
Updated Wiki Page
Mæster
23rd June 2006 03:34 UTC
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.