Newsgroup: it.comp.programmare.win32
Titolo: spegnimento automatico

non riesco a trovare l'istruzione per arrestare il sistema. Ho bisogno di
una routine (in Visual basic o
Visual C o assembler) che abbia lo stesso effetto dei tasti:
avvio - chiudi sessione - arresta il sistema
C'e' qualcuno che sa come fare?
grazie
Ino Lodato

...


Ino Lodato
Ciao, attenzione a una cosa : le funzioni variano a seconda del S.O.
che usi, se usi 9X basta un ExitWindows o ExitWindowsEx mentre se
usi NT (oltre ad avere anche altre API) il solo uso delle API precedenti
non riavvia la macchina bisogna effettuare delle chiamate che modifichino
i privilegi del programma.......
se il tuo S.O. e' NT  e hai bisogno di una mano riposta
Ciao
--
Roberto


Grazie, (anche a Dome).
ho provato sotto w98 ed e' perfetta. Sotto NT in effetti
non succede niente. Gia' cosi' mi sta bene, pero' se puoi
darmi una dritta per Nt e' meglio.
grazie ancora.
Ciao
Ino

Ciao
Ciao, per Nt il problema é che le applicazioni lanciate non sempre hanno i
medesimi privilegi del proprietario.
Se hai il MSDN devi cercare le funzioni della famiglia GetTokenPrivileges,
AdjustTokenPrivileges eccetera...... il loro uso é abbastanza facile.
Se non hai il MSDN e usi il C++ ti posso mandare un esempio...... fammelo
sapere
Ciao
--
Roberto
tat...@hotmail.com

...

Piuttosto che farlo ammattire penso sia meglio scrivergli subito un piccolo
esempio :-)
// -------------------------------------------------------------------
#include <windows.h>
// # -> Forza uscita
// ! -> uscita normale
// @ -> riavvia sistema
// & -> spegne l'ATX (se presente, altrimenti riavvia)
// * -> riavvia come altro utente
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR cmd,int)
{
    HANDLE HProc = GetCurrentProcess();
    HANDLE token;
    if(OpenProcessToken( HProc,  TOKEN_WRITE, &token))
        LUID luid;
        LookupPrivilegeValue( 0, SE_SHUTDOWN_NAME, &luid);
        TOKEN_PRIVILEGES newPriv;
        newPriv.PrivilegeCount = 1;
        newPriv.Privileges[0].Luid = luid;
        newPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
        DWORD retLen;
        AdjustTokenPrivileges( token, false, &newPriv, 0, 0, &retLen);
        }
    unsigned flag = EWX_LOGOFF;
    switch(*cmd) {
        case '#':
            flag |= EWX_FORCE;
            // fall-through
        case '!':
            flag |= EWX_SHUTDOWN;
            break;
        case '&':
            flag |= EWX_FORCE;
            flag |= EWX_POWEROFF;
            break;
        case '@':
            flag |= EWX_REBOOT;
        case '*':
            break;
        default:
            return 0;
        }
    ExitWindowsEx(flag,0);
    return 0;
}
// -------------------------------------------------------------------------
-------------
Lo spegnimento del pc su NT non posso dire se funzioni o meno, non ho ancora
avuto modo (tempo e occasione) di verificarlo (di caricarci ed eseguirci
l'esempio di cui sopra).
Sullo stesso pc, win98 e NT si comportano in maniera diversa all'uscita dal
sistema.
Win98 lo spegne mentre NT presenta la classica richiesta di terminare o
riavviare.
Ciao
Nazzareno

esempio :-)
Ciao, hai ragione, io lo facevo solo per il fatto che é meglio
ricevere un consiglio che una soluzione........  ;-)
Comunque gli invio anche la mia soluzione, lo so che é piu lunga ma
avevo il file include contenente anche una piccola routine per controllare
se il S.O. é NT e se necessario chiama la routine per la modifica dei
privilegi passandogli il valore (non ho messo il valore fisso perche uso il
file
anche per altre cose).......
P.S. un po di clemenza con il mio codice non sono uno sviliuppatore
ma un amministratore di rete.
//--------------------------------------------------------------------------
-
//
//     Mie routine C++ Builder 3.00 Professional
//
//--------------------------------------------------------------------------
-
// void    Rebooter( long flag);
//            Chiama ExitWindowsEx con il parametro flag, se il S.O.
//            é windows NT chiama prima la funzione ModificaToken
// int     VersioneDiWindows( void);
//            Ritorna il valore della piattaforma di Windows e mette
//            nella variabile globale WinVer (int) il numero della
//            Versione di Windows moltiplicato 100 (es. 400 )
// bool    ModificaToken(  LPCTSTR, bool);
//            Modifica i privilegi per l'utente corrente
// int     Errori( const char*, int, int);
//            Chiama MessageBox con i parametri corretti e ritorna
//            l'eventuale scelta fatta
// -------------------------------------------------------------------------
-----------
// ---------------------FUNZIONI----------------------
void     Rebooter( long );
int      VersioneDiWindows( void);
bool        ModificaToken(  LPCTSTR, bool);
int      Errori( char*, int, int);
//--------------------------------VARIABILI---------------------------------
-
int         WinVer;
char        *ErrMsg = "E R R O R E  !";
char        *WarnMsg = "A T T E N Z I O N E  !";
char        *AdvMsg = "M E S S A G G I O !";
//--------------------------------DEFINIZIONI-------------------------------
-
#define     ERR 1
#define  WARN 2
#define     ADV 3
//--------------------------------------------------------------------------
-
void Rebooter( long flag)
{
    if( VersioneDiWindows() == VER_PLATFORM_WIN32_NT )
    {
        if(ModificaToken(SE_SHUTDOWN_NAME,true) != true)
        {
            Errori("Errore nella modifica dei privilegi",IDOK,1);
            return;
        }
    }
    ExitWindowsEx(flag, 0);
}
//--------------------------------------------------------------------------
-
int  VersioneDiWindows( void)
{
   OSVERSIONINFO VI;
 VI.dwOSVersionInfoSize = sizeof(TOSVersionInfo);
 GetVersionEx(&VI);
    WinVer = (100 * VI.dwMajorVersion) + VI.dwMinorVersion;
    return VI.dwPlatformId;
    // possibili codici di uscita
    //  VER_PLATFORM_WIN32s
   //  VER_PLATFORM_WIN32_WINDOWS
    //  VER_PLATFORM_WIN32_NT
}
//--------------------------------------------------------------------------
-
bool ModificaToken(  LPCTSTR Privilege,bool bEnablePrivilege)
{
    HANDLE hToken;
    TOKEN_PRIVILEGES tp;
    LUID luid;
    TOKEN_PRIVILEGES tpPrevious;
    DWORD cbPrevious=sizeof(TOKEN_PRIVILEGES);
    if(!OpenProcessToken( GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES |
TOKEN_QUERY,&hToken))
        return false;
    if(!LookupPrivilegeValue( NULL, Privilege, &luid ))
        return false;
    tp.PrivilegeCount           = 1;
    tp.Privileges[0].Luid       = luid;
    tp.Privileges[0].Attributes = 0;
    AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof
TOKEN_PRIVILEGES),&tpPrevious,&cbPrevious);
    if (GetLastError() != ERROR_SUCCESS)
        return false;
    tpPrevious.PrivilegeCount       = 1;
    tpPrevious.Privileges[0].Luid   = luid;
    if(bEnablePrivilege)
        tpPrevious.Privileges[0].Attributes |= (SE_PRIVILEGE_ENABLED);
    else
        tpPrevious.Privileges[0].Attributes ^= (SE_PRIVILEGE_ENABLED &
tpPrevious.Privileges[0].Attributes);
    AdjustTokenPrivileges(hToken,FALSE,&tpPrevious,cbPrevious,NULL,NULL);
    if (GetLastError() != ERROR_SUCCESS)
        return false;
    return true;
}
//--------------------------------------------------------------------------
-
int Errori( char* TipoMsg, int flag, int tipo)
{
    switch( tipo)
    {
        case ERR:
            return(  MessageBox( Application->Handle, TipoMsg, ErrMsg,
flag));
        case WARN:
            return(  MessageBox( Application->Handle, TipoMsg, WarnMsg,
flag));
        case ADV:
            return(  MessageBox( Application->Handle, TipoMsg, AdvMsg,
flag));
    }
    return 0;
}
Ciao
Roberto
tat...@hotmail.com

Io uso MSDN, quindi penso che il programma di Nazzareno sia
quello che fa al caso mio. Lo provero' al piu' presto.
grazie a tutti per l'aiuto
ciao
Ino

ho provato il tuo codice inserendolo nel pulsante ok di un form:
void CSpegniDlg::OnOK()
{
 // TODO: Add extra validation here
    HANDLE HProc = GetCurrentProcess();
    HANDLE token;
    if(OpenProcessToken( HProc,  TOKEN_WRITE, &token))
 {
        LUID luid;
  LookupPrivilegeValue( 0, SE_SHUTDOWN_NAME, &luid);
  TOKEN_PRIVILEGES newPriv;
  newPriv.PrivilegeCount = 1;
  newPriv.Privileges[0].Luid = luid;
  newPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  DWORD retLen;
  AdjustTokenPrivileges( token, false, &newPriv, 0, 0, &retLen);
 }
 ExitWindowsEx(EWX_SHUTDOWN, 0);
 CDialog::OnOK();
}
e, come prevedevi, esce dal sistema e presenta il messaggio "puoi
spegnere.." o
riavviare. Con POWEROFF esegue il reboot e con FORCE e LOGOFF chiude la
sessione.
Di spegnere il pc non se ne parla. Eppure leggendo l'help sembra possibile
con
questo procedimento. Ho controllato anche i valori di ritorno di
LookupPrivilegeValue e AdjustTokenPrivileges e sono 1. Non capisco.
Grazie e ciao.
Ino

parli del service pack 4?
Si, nel SP4 ita c'e' il file che fa al caso tuo.....
Ciao
--
Roberto
tat...@hotmail.com
(Se é Microsoft non é un errore, é una caratteristica)

>(Se é Microsoft non é un errore, é una caratteristica)
questa e' bella!
grazie e ciao
Ino