Windows Vista? *NEVER* Het waarom - Opera forever!!!
I've seen chickens that were more menacing. Chickens in a coma. On ice. In my fridge
"The shell stopped unexpectedly and Explorer.exe was restarted."
Dat is juist wat ik niet kan vinden hoe..Op dinsdag 02 april 2002 20:24 schreef jelmervos het volgende:
Als je de handle hebt kun je er volgens mij wel een bericht heen sturen dat het programma zich moet sluiten.
Ik heb dus deze gegevens:
1
2
3
4
5
6
| typedef struct _PROCESS_INFORMATION { // pi
HANDLE hProcess;
HANDLE hThread;
DWORD dwProcessId;
DWORD dwThreadId;
} PROCESS_INFORMATION; |
Dus de handle net niet. Hoe krijg ik deze?
Windows Vista? *NEVER* Het waarom - Opera forever!!!
I've seen chickens that were more menacing. Chickens in a coma. On ice. In my fridge
Verwijderd
Om een process id om te zetten naar een window handle, zou je mbv EnumWindows kunnen kijken welke windows er zijn; en dan mbv GetWindowThreadProcessId kijken of het de juiste window is.
hoewel, ik niet zeker weet of het program 'netjes' afsluit
var
hBrowser : THandle;
begin
hBrowser := FindWindow(ClassType,PChar(Caption));
if hBrowser <> 0 Then
Begin
SendMessage(hBrowser, WM_SYSCOMMAND,SC_CLOSE,0);
RESULT := true;
end
else
RESULT := false;
end;
"The shell stopped unexpectedly and Explorer.exe was restarted."
Dat wil ik eigenlijk niet. Nou staat er in de help:
1
2
3
4
5
6
| The preferred way to shut down a process is by using the ExitProcess function, because this function notifies all dynamic-link libraries (DLLs) attached to the process of the approaching termination. Other means of shutting down a process do not notify the attached DLLs. Note that when a thread calls ExitProcess, other threads of the process are terminated without an opportunity to execute any additional code (including the thread termination code of attached DLLs). |
Nou, hoe doet ie dat nou? ExitProcess werkt voor geen meter. Ik heb ook nog geprobeerd met OpenProcess een handle te krijgen naar het process, dat werkt wel, maar ik kan hem alleen sluiten met TerminateProcess, Sendmessage enzo werkt niet (werkt alleen met de handle van FindWindow).
Wat ik eigenlijk dus wil vragen is dat er in de help staat dat je het proces kan/moet afsluiten met ExitProcess. Weet iemand hoe?
Windows Vista? *NEVER* Het waarom - Opera forever!!!
I've seen chickens that were more menacing. Chickens in a coma. On ice. In my fridge
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
| void CALLBACK MyShutDownProc(ULONG_PTR p_Dummy)
{
PostQuitMessage(0);
}
void ShutdownRemoteProcess(PROCESS_INFORMATION* p_Information)
{
// Keep trying
while(true)
{
// Request shutdown
QueueUserAPC(MyShutDownProc, p_Information->hTread, NULL);
// Wait for 10 seconds for the process to stop
if(WaitForSingleObject(p_p_Information->hProcess, 10 * 1000) == WAIT_OBJECT_0)
{
// Process has shut down succesfully
return;
}
// Process not responding
if(MessageBoxA(NULL, "The process is not responding to the shutdown request,\n"
"do you want to kill it?", "Question", MB_YESNO | MB_ICONQUESTION) == IDYES)
{
// Terminate it violently
TerminateProcess(p_Information->hProcess, -1);
return;
}
}
} |
ExitProcess is om het huidige process af te sluiten. Voor een nette shutdown moet je dus even in de huid van het andere process kruipen (via QueueUserAPC) en dan daar een vriendelijke shutdown verzoeken. Ik gebruik in bovenstaand voorbeeld PostQuitMessage omdat dit (geloof ik) de app nog toestaat vriendelijk dingen weg te schrijven en zo, ExitProcess is volgens mij iets botter.Op woensdag 03 april 2002 10:43 schreef Darkvater het volgende:
Wat ik eigenlijk dus wil vragen is dat er in de help staat dat je het proces kan/moet afsluiten met ExitProcess. Weet iemand hoe?
Let wel dat je QueueUserAPC overigens alleen mag doen op een thread waarop je voldoende access rights hebt: dit is wel het geval op de handle die je uit CreateProcess krijgt maar niet als je bijv. EnumProcesses gaat gebruiken.
* curry684 heeft overigens al een tijd niet meer dit soort gehack gedaan
Ah, dank je wel. Ik denk dat het wel lukt. Het stomme is dat het niet goed uitgelegd staat in de help. Alleen van met ExitProcess sluit je het met CreateProcess gestarte Process af. Maar nergens staat er een link voor QueueUserAPC/PostQuitMessageOp woensdag 03 april 2002 12:14 schreef curry684 het volgende:
[..]
ExitProcess is om het huidige process af te sluiten. Voor een nette shutdown moet je dus even in de huid van het andere process kruipen (via QueueUserAPC) en dan daar een vriendelijke shutdown verzoeken. Ik gebruik in bovenstaand voorbeeld PostQuitMessage omdat dit (geloof ik) de app nog toestaat vriendelijk dingen weg te schrijven en zo, ExitProcess is volgens mij iets botter.
Let wel dat je QueueUserAPC overigens alleen mag doen op een thread waarop je voldoende access rights hebt: dit is wel het geval op de handle die je uit CreateProcess krijgt maar niet als je bijv. EnumProcesses gaat gebruiken.
* curry684 heeft overigens al een tijd niet meer dit soort gehack gedaan
Windows Vista? *NEVER* Het waarom - Opera forever!!!
I've seen chickens that were more menacing. Chickens in a coma. On ice. In my fridge
Humm, QueueUserAPC wil niet lukken. Als ik dit doe:Op woensdag 03 april 2002 12:14 schreef curry684 het volgende:
[..]
Met wel dat je QueueUserAPC overigens alleen mag doen op een thread waarop je voldoende access rights hebt: dit is wel het geval op de handle die je uit CreateProcess krijgt maar niet als je bijv. EnumProcesses gaat gebruiken.
* curry684 heeft overigens al een tijd niet meer dit soort gehack gedaan
1
| QueueUserAPC(MyShutDownProc, hProcess.hProcess, 0); |
of dit:
1
| QueueUserAPC(PostQuitMessage(0), hProcess.hProcess, 0); |
en MyShutDownProc is:
1
2
3
4
| procedure TForm1.MyShutDownProc(p_Dummy: ULONG); begin PostQuitMessage(0); end; |
dan zegt ie:
1
| [Error] Unit1.pas(92): Incompatible types: 'procedure, untyped pointer or untyped parameter' and 'Pointer' |
Het ligt volgens mij aan ULONG dat ie ULONG_PTR moet zijn, maar die kent Delphi niet. Wat kan ik in plaats daarvan gebruiken?
EDIT::
Ik heb het opgelost denk ik, want hij compileert wel, met @ voor de functie. Die geeft dan het adres van die functie door. Zo dus.
1
| QueueUserAPC(@TForm1.MyShutDownProc,hProcess.hProcess, 0); |
EDIT2:: ik zie net, dat iemand dat ook al gezegd heeft.
Maar ik zit nog met een probleem: hij komt nooit in de MyShutDownProc functie om PostQuitMessage te doen. Dus hij sluit het ook niet af (wel met Terminate natuurlijk
Weet iemand de oplossing daarvoor?
Als niemand het weet, dan ga ik maar windowtjes zoeken
Windows Vista? *NEVER* Het waarom - Opera forever!!!
I've seen chickens that were more menacing. Chickens in a coma. On ice. In my fridge
Maar ik zit nog met een probleem: hij komt nooit in de MyShutDownProc functie om PostQuitMessage te doen. Dus hij sluit het ook niet af (wel met Terminate natuurlijk )
Weet iemand de oplossing daarvoor?
Als niemand het weet, dan ga ik maar windowtjes zoeken
Windows Vista? *NEVER* Het waarom - Opera forever!!!
I've seen chickens that were more menacing. Chickens in a coma. On ice. In my fridge
Verwijderd
1
2
3
4
| procedure MyShutDownProc(var Dummy: ULONG); stdcall; begin PostQuitMessage(0); end; |
Dus niet een method van TForm1, de var en de stdcall.
TForm1 was een foutje van mijOp woensdag 03 april 2002 21:03 schreef DiFool het volgende:
Wat robh zegt, en dit:
code:
1 2 3 4 procedure MyShutDownProc(var Dummy: ULONG); stdcall; begin PostQuitMessage(0); end;
Dus niet een method van TForm1, de var en de stdcall.
1
| QueueUserAPC(@MyShutDownProc,hProcess.hThread, 0) |
Dus hThread, anders krijg ik een invalid handle. Maar hij doet het nog steeds niet
Nog een laatste poging. Hier is hoe ik de programma heb opgestart:
1
2
3
4
5
6
7
8
9
10
| CreateProcess(nil,
PChar(Form2.Edit1.Text),
nil,
nil,
false,
NORMAL_PRIORITY_CLASS,
nil,
nil,
hStartup,
hProcess); |
Misschien doe ik hier iets fout.
Windows Vista? *NEVER* Het waarom - Opera forever!!!
I've seen chickens that were more menacing. Chickens in a coma. On ice. In my fridge
Verwijderd
Dus ik gok, dat het process wat jij start niet in een alertable state komt.When a user-mode APC is queued, the thread is not directed to call the APC function unless it is in an alertable state.
[..]
A thread enters an alertable state by using SleepEx, SignalObjectAndWait, WaitForSingleObjectEx, WaitForMultipleObjectsEx, or MsgWaitForMultipleObjectsEx to perform an alertable wait operation
Wat voor een process start je eigenlijk?
Probeer overigens eens ipv PostQuitMessage ExitProcess() aan te roepen. Dat de debugger zegt dat ie nooit in die APC komt is logisch natuurlijk: je zit hier in een extern process waar de debugger niet aan geattached zit... dat kun je alleen bruikbaar debuggen door logging in de APC te plaatsen.
Heb je trouwens de returnvalue van QueueUserAPC gechecked?
Ik zal kijken wat ExitProcess doet. De returnvalue van QueueUserAPC heb ik gechecked, daardoor weet ik dat het hThread moet zijn, anders vindt ie dat een invalid handle. Het proces is Cheating-death voor CS, maar ik heb ook Calculator opgestart, en die wou ook niet. Vanavond ga ik weer kijken (dan ben ik weer thuis), hopelijk lukt het wel.Op donderdag 04 april 2002 09:15 schreef curry684 het volgende:
Dit werkt logischerwijs alleen met programma's met een message queue EN alertable states idd. Ieder normaal Windows programma (pak gewoon Word) voldoet hieraan.
Probeer overigens eens ipv PostQuitMessage ExitProcess() aan te roepen. Dat de debugger zegt dat ie nooit in die APC komt is logisch natuurlijk: je zit hier in een extern process waar de debugger niet aan geattached zit... dat kun je alleen bruikbaar debuggen door logging in de APC te plaatsen.
Heb je trouwens de returnvalue van QueueUserAPC gechecked?
Windows Vista? *NEVER* Het waarom - Opera forever!!!
I've seen chickens that were more menacing. Chickens in a coma. On ice. In my fridge
Verwijderd
Weet je dit zeker, dwz ik twijfel hieraan.curry684:
Dit werkt logischerwijs alleen met programma's met een message queue EN alertable states idd. Ieder normaal Windows programma (pak gewoon Word) voldoet hieraan.
Ik dacht eigenlijk dat alertable states ed typerend zijn voor threads. En dat de main-thread ve programma normaal gesproken niet in een alertable state komt, tenzij je expliciet SleepEx oid aanroept.
Als een programma nooit yield oftewel in een alertable waitstate gaat zuipt ie constant 100% cpu-usage. Je vergeet dat GetMessage intern in een alertable wait state duikt zodra er geen messages meer in de queue staan.Op donderdag 04 april 2002 12:08 schreef DiFool het volgende:
Weet je dit zeker, dwz ik twijfel hieraan.
Ik dacht eigenlijk dat alertable states ed typerend zijn voor threads. En dat de main-thread ve programma normaal gesproken niet in een alertable state komt, tenzij je expliciet SleepEx oid aanroept.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
| // -------------------------------------------------------------------------- // Window enumerator callback // -------------------------------------------------------------------------- BOOL CALLBACK EnumWindowsProc(HWND p_Window, LPARAM p_Parameter) { DWORD l_ProcessId; // Request whose window this is GetWindowThreadProcessId(p_Window, &l_ProcessId); // On precise match post a WM_CLOSE if(l_ProcessId == p_Parameter) PostMessage(p_Window, WM_CLOSE, NULL, NULL); // Continue enumerating return TRUE; } // -------------------------------------------------------------------------- // Main function // -------------------------------------------------------------------------- int main() { STARTUPINFO l_StartupInfo = {0}; PROCESS_INFORMATION l_ProcessInfo = {0}; l_StartupInfo.cb = sizeof(l_StartupInfo); if(CreateProcess(NULL, "notepad.exe", NULL, NULL, FALSE, 0, NULL, NULL, &l_StartupInfo, &l_ProcessInfo)) { // Process succesfully started... wait 3 seconds Sleep(3 * 1000); // Request shutdown while(true) { // Request shutdown by posting WM_CLOSE to all app windows EnumWindows(EnumWindowsProc, (LPARAM)l_ProcessInfo.dwProcessId); // Wait for 10 seconds for the process to be stopped if(WaitForSingleObject(l_ProcessInfo.hProcess, 10 * 1000) == WAIT_OBJECT_0) break; // Process not responding if(MessageBoxA(NULL, "The process is not responding to the shutdown request,\n" "do you want to kill it?", "Question", MB_YESNO | MB_ICONQUESTION) == IDYES) { // Terminate it violently TerminateProcess(l_ProcessInfo.hProcess, -1); break; } } } // Wait before quitting printf("\n\nPress enter to quit..."); while(!getch()); return 0; |
Vooral even in die 3 seconden iets intypen in Notepad, en geniet ervan dat er netjes gevraagd wordt of je de veranderingen wil saven...
Enjoy and don't forget the credit
[ Voor 9% gewijzigd door curry684 op 19-12-2002 02:37 ]
Verwijderd
Eigenlijk alleen omdat GetMessage niet genoemd wordt bij de functies die een thread in een alertable wait state brengen, in de MSDN beschrijving van QueueUserAPC.
Maar ik zal 's wat gaan testen, als ik tijd heb
In ieder geval bedankt, ik ga het vanavond gelijk proberen
Windows Vista? *NEVER* Het waarom - Opera forever!!!
I've seen chickens that were more menacing. Chickens in a coma. On ice. In my fridge
Dank je wel curry684!! Met EnumWindows werkt het eindelijk!!! Alleen heb ik iets extra's aan toegevoegd: als ie de window gevonden heeft, returnt ie false, dus hij stopt met windowtjes zoeken.Op vrijdag 05 april 2002 00:22 schreef curry684 het volgende:
Okee ik ben ook maar eens gaan proberen, en na zeker 1 minuut zoeken in MSDN op 'kill process handle' vond ik Knowledge Base artikel Q178893, op basis waarvan ik het volgende werkende programmaatje schreef:
code:
1 werkt
Enjoy and don't forget the credit
Dank je zeer, credit wordt erbijgezet!
Windows Vista? *NEVER* Het waarom - Opera forever!!!
I've seen chickens that were more menacing. Chickens in a coma. On ice. In my fridge
waarom moeilijk doen als het makkelijk kan met findwindow.
je krijgt een handle terug op basis van de 'naam' en 'type' (class) van een app.
Uhm......... en da's dus niet de bedoelingOp vrijdag 05 april 2002 22:44 schreef Darkvater het volgende:
Alleen heb ik iets extra's aan toegevoegd: als ie de window gevonden heeft, returnt ie false, dus hij stopt met windowtjes zoeken.
Een Outlook heeft al snel z'n main window open en 2 new-mail windows om maar een voorbeeld te noemen, en als je dus als eerste een new-mail window vindt wordt de app niet afgesloten
Gewoon dooritereren, hij loopt alleen over de top-level windows dus weinig overhead.
En hoe exact ga je voorspellen wat voor titel er op dat moment in (bijvoorbeeld) Internet Explorer staat en/of wat voor window-classname IE7.0 gaat gebruiken?Op vrijdag 05 april 2002 23:05 schreef MisterE het volgende:
eeeuhmm, maareh enumwindows is toch hetzelfde als FindWindow.
waarom moeilijk doen als het makkelijk kan met findwindow.
je krijgt een handle terug op basis van de 'naam' en 'type' (class) van een app.
Je wil gewoon het process vriendelijk mollen by process id.
Het is niet hetzelfde. Met Findwindow zoek je op de title van het process. Bijvoorbeeld 'notepad'. Maar als je dat niet wil, en je wil gewoon aan de hand van de processid de handle naar de window vinden, kan dat niet.Op vrijdag 05 april 2002 23:05 schreef MisterE het volgende:
eeeuhmm, maareh enumwindows is toch hetzelfde als FindWindow.
waarom moeilijk doen als het makkelijk kan met findwindow.
je krijgt een handle terug op basis van de 'naam' en 'type' (class) van een app.
Stel je voor dat je 5 notepad's hebt openstaan. Je start er zelf eentje op, en die wil je straks afsluiten. Met FindWindow, geeft ie de handle naar de eerste de beste notepad-process, en is die heel vaak niet diegene die je wilt hebben. Enumwindows gaat alle windows langs, en alleen als het processid van die gelijk is aan die je zoekt, sluit je af
Windows Vista? *NEVER* Het waarom - Opera forever!!!
I've seen chickens that were more menacing. Chickens in a coma. On ice. In my fridge
Je hebt in principe gelijk, maar mijn opgestarte applicatie heeft maar 1 windowOp zaterdag 06 april 2002 02:05 schreef curry684 het volgende:
[..]
Uhm......... en da's dus niet de bedoeling
Een Outlook heeft al snel z'n main window open en 2 new-mail windows om maar een voorbeeld te noemen, en als je dus als eerste een new-mail window vindt wordt de app niet afgesloten
Gewoon dooritereren, hij loopt alleen over de top-level windows dus weinig overhead.
Windows Vista? *NEVER* Het waarom - Opera forever!!!
I've seen chickens that were more menacing. Chickens in a coma. On ice. In my fridge
DEFENSIEF PROGRAMMEREN!!!Op zaterdag 06 april 2002 14:54 schreef Darkvater het volgende:
Je hebt in principe gelijk, maar mijn opgestarte applicatie heeft maar 1 window
Je hebt geen garantie dat de volgende versie van dat programma ook maar 1 window gebruikt, en dan ben je dus 'incompatible'!!!!