Jump to content
Sign in to follow this  
knuto

Batch-fil må køyrast ved avslutning av Windows

Recommended Posts

God kveld!

 

Eg jobbar med eit prosjekt som skal vera absolutt installasjonsfritt. I den samanheng treng eg å få køyrt ei batch- eller programfil for å rydda opp når Windows avslutter. Aller helst burde det vore såpass kraftig at om Windows blir kritisk avslutta, så blir det køyrd ved neste oppstart.

 

Dette er i tilfelle brukaren ikkje avslutter prosessen sjølv.

 

Lagt til:

 

Etter litt utforsking har eg kome fram til at dette antageleg ikkje går an. Derimot har eg laga meg ein teori:

 

Prosjektet mitt blir nemleg starta av start.bat, og avslutta av shutdown.bat. Eg tenkjer at eg kunne laga eit enkelt program i C++ som køyrer som ein prosess, kun synleg i oppgåvebehandlaren.

 

Me kallar dette programmet for atshutdown.exe. Dette bør nok skiftast til eit meir unikt namn, men den tid, den sorg. I alle fall. Til slutt i start.bat har me linja start atshutdown.exe shutdown.bat.

 

I atshutdown.exe må eg nok bruka Win32-API-et. Programmet skal ikkje gjera anna enn å venta til det får kill-signal frå Windows. Då skal programmet køyra kommandoen / programmet det fekk som argument. Altså shutdown.bat.

 

Om brukaren køyrer shutdown.bat før Windows avslutter vil derimot shutdown.bat avslutta prosessen atshutdown.exe.

 

Er denne teorien mogleg i praksis, og utan å stela for mykje prosessorkraft?

Edited by knuto

Share this post


Link to post

Ja det er fullt mulig WM_CLOSE blir sendt når programmet blir avsluttet (dvs nå må programmet avslutte seg selv).

Men hva hvis strømmen går eller noe slikt, meget kritiske! system feil og slikt.

Det finnes jo steder der man kan legge filer som blir automatisk kjørt ved oppstart (startup direktivet på startmenyen osv).

Share this post


Link to post

Kan nokon då hjelpa meg med eit C/C++ program som køyrer skjult, men har ein message loop? Er ikkje heilt inne i det der, lenger ...

Share this post


Link to post

Jeg bare tenker litt.. Hva er det som skal fjernes? win32 har en variabel som man kan sette på en delete funksjonen (lenge siden jeg var borti den)

 

Men den mener jeg gjør at filene slettes først ved oppstart.

Hvis du forklarte litt nærmere opplegget ditt så tror jeg det finnes en enklere løsning.

Share this post


Link to post

Her er en liten kodebit jeg rasket sammen som kan hjelpe deg. Det er en liten app som lager et skjult vindu som tar i mot WM_QUERYENDSESSION og WM_ENDSESSION. Du må selv skrive koden du ønsker skal kjøre ved shutdown under WM_ENDSESSION. Se på MSDN for nærmere beskrivelse av meldingene.

 

Koden:

 

#include <windows.h>
#include <tchar.h>


// prototypes
LRESULT CALLBACK WindowProc (HWND hwndd, UINT message, WPARAM wParam, LPARAM lParam);


// constants
const TCHAR* WNDCLASSNAME = _T("MyHiddenWindow");


// entry point
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd)
{
 // register window class
 WNDCLASS wc;
 memset(&wc, 0, sizeof(wc));
 wc.lpszClassName = WNDCLASSNAME;
 wc.lpfnWndProc = WindowProc;
 RegisterClass(&wc);

 // create hidden window
 HANDLE hiddenWindow = CreateWindow( WNDCLASSNAME, 
                   WNDCLASSNAME, 
                   WS_OVERLAPPEDWINDOW, 
                   CW_USEDEFAULT, 
                   CW_USEDEFAULT, 
                   CW_USEDEFAULT, 
                   CW_USEDEFAULT, 
                   0, 
                   0, 
                   hInstance, 
                   0);

 // message loop
 MSG msg;
 while(GetMessage(&msg, NULL, 0, 0 ))
 {
   TranslateMessage(&msg);
   DispatchMessage(&msg);
 }

 return static_cast<int>( msg.wParam );
}


// event handlers
LRESULT CALLBACK WindowProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
 switch(message)
 {
 case WM_QUERYENDSESSION:
   // you may cancel shutdown here...

   return TRUE;


 case WM_ENDSESSION:
   if(wParam == FALSE)
     return 0;

   // do your cleanup here...

   DestroyWindow(hwnd);
   PostQuitMessage(0);

   return 0;


 default:
   return DefWindowProc(hwnd, message, wParam, lParam); 

 }

 return 0;
}

Share this post


Link to post

Hmm. Virker av ein eller annan grunn til at det der ikkje fungerer heilt ... Om eg avslutter prosessen som heiter AtShutdown.exe, så vil allikevel ikkje noko bli gjennomført. Verken om eg legg inn ein message box, eller ein system-kommando ...

 

Kode som blei brukt:

#include <cstdlib>
#include <windows.h>
#include <tchar.h>

// prototypes
LRESULT CALLBACK WindowProc (HWND hwndd, UINT message, WPARAM wParam, LPARAM lParam);

// constants
const TCHAR* WNDCLASSNAME = _T("AtShutdown");

// entry point
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd) {
// register window class
WNDCLASS wc;
memset(&wc, 0, sizeof(wc));
wc.lpszClassName = WNDCLASSNAME;
wc.lpfnWndProc = WindowProc;
RegisterClass(&wc);

// create hidden window
HANDLE hiddenWindow = CreateWindow( WNDCLASSNAME,
         WNDCLASSNAME,
         WS_OVERLAPPEDWINDOW,
         CW_USEDEFAULT,
         CW_USEDEFAULT,
         CW_USEDEFAULT,
         CW_USEDEFAULT,
         0,
         0,
         hInstance,
         0);

// message loop
MSG msg;
while(GetMessage(&msg, NULL, 0, 0 )) {
 TranslateMessage(&msg);
 DispatchMessage(&msg);
}//end while

return static_cast<int>( msg.wParam );
}//end entry point


// event handlers
LRESULT CALLBACK WindowProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch(message) {
 case WM_QUERYENDSESSION:
 	return TRUE;
 
 case WM_ENDSESSION:
 	if(wParam == FALSE)
   return 0;
 
 	/* {...} */
 	system("shutdown.bat");
 	MessageBox(NULL, "xxx does not run any more ...", "Finish..", MB_OK);
 
 	DestroyWindow(hwnd);
 	PostQuitMessage(0);
 	
 	return 0;
 	
 default:
 	return DefWindowProc(hwnd, message, wParam, lParam);
}//end switch
return 0;
}//end callback

Edited by knuto

Share this post


Link to post

WM_ENDSESSION blir sendt når Windows avslutter sesjonen (dvs. log off, restart eller shutdown), og ikke om du terminerer applikasjonen i task manager. Da har jeg misforstått hvis det var det du ønsket. Trodde du ville ha et program som lå i bakgrunnen og detekterte når brukeren avsluttet Windows.

Share this post


Link to post

Hvorfor er det bedre å bruke WM_CLOSE?

 

WM_ENDSESSION blir sendt når sesjonen eller Windows avsluttes. Synes det er bedre enn å bruke WM_CLOSE selv om du sikkert kan oppnå det samme med den siden vinduet er skjult.

 

Du trenger strengt tatt ikke bry deg om WM_QUERYENDSESSION, men jeg tok den med for å illustrere.

Share this post


Link to post

Kunne godt ha reagert uansett om Win blir avslutta, eller prosessen blir terminert, men er kanskje greitt nok med kun førstnemnte ...

Share this post


Link to post

Hvis du dreper prosessen tror jeg det blir vanskelig å detektere hvis du ikke ønsker enda et program som overvåker AtShutdown.exe. Er ganske sikker på at task manager ikke sender noen meldinger til prosesser den terminerer (nei, ikke noe WM_CLOSE heller).

 

Du kan jo alltids lage AtShutdown.exe slik at den alltid sørger for at det er minst to AtShutdown.exe prosesser.

 

Edit: kan bekrefte at task manager ikke sendte meldinger til applikasjonen den terminerer (sjekket i spy++).

Edited by kjetil7

Share this post


Link to post

hmm.. det stemmer (da lærte jeg noe i dag også :))

Vel da er det nok det beste med WM_ENDSESSION som kjetil7 sa, da har du jo også muligheten til å utsette og stoppe avskruingen av pcen.

Share this post


Link to post

Kan tydeleg vis ikkje bruka funksjonen system frå cstdlib til å gje Apache kommandoar. Det resulterar i cmd.exe feil. Må gjera dette på eit anna vis, men eg legg prosjektet midlertidig på hulla, for eg skal nok ein gong prøva å venna meg til Linux :)

 

Forresten positivt overraska sidan eg har fått til eksternt skrivebord, slik at eg kan bruka min win-laptop i stova for å styra linuxen på loftet :)

Share this post


Link to post

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

×
×
  • Create New...