Italian community of Lazarus and Free Pascal

Programmazione => Generale => Topic aperto da: xinyiman - Settembre 19, 2012, 02:02:28 pm

Titolo: Spegnimento PC
Inserito da: xinyiman - Settembre 19, 2012, 02:02:28 pm
Ciao ragazzi, qualcuno conosce un comando crossplatform per effettuare lo spegnimento del pc?! Grazie
Titolo: Re:Spegnimento PC
Inserito da: Stilgar - Settembre 19, 2012, 02:11:55 pm
Un martello?
Ogni OS ha le sue ...
Se potessi accedere direttamente all'hw (come con il MS-DOS, per capirci) il reboot lo fai saltando alla posizione 0 con il program counter.
In Java ho trovato questo frammento ...
Codice: [Seleziona]
public static void shutdown() throws RuntimeException, IOException {
 
String osName = System.getProperty("os.name");       
if (osName.startsWith("Win")) {
  shutdownCommand = "shutdown.exe -s -t 0";
} else if (osName.startsWith("Linux") || osName.startsWith("Mac")) {
  shutdownCommand = "shutdown -h now";
} else {
  System.err.println("Shutdown unsupported operating system ...");
    //closeApp();
}

Per l'esecuzione di processi esterni : http://wiki.freepascal.org/Executing_External_Programs/it

Per il riconoscimento della piattaforma ... o te la giochi con la solita pappardella degli IFDEF o trovi una stada migliore ;)
Titolo: Re:Spegnimento PC
Inserito da: xinyiman - Settembre 19, 2012, 02:13:21 pm
Pensavo anche io di fare qualcosa del genere, ero solo curioso di sapere se c'era una strada migliore. Tutto li
Titolo: Re:Spegnimento PC
Inserito da: Stilgar - Settembre 19, 2012, 02:18:56 pm
Potresti fare una cosa del genere :
Dichiari una unit (OSSystemUtils .. o simile)
Nella interface dichiari la firma del metodo.

Codice: [Seleziona]
interface
procedure OSShutdown;

implementation

{IFDEF Win}
{$INCLUDE OSShotDownWin.inc}
{$ELSE}{IFDEF MAC}
{$INCLUDE OSShotDownMac.inc}
{$ELSE}{IFDEF LINUX}
{$INCLUDE OSShotDownLin.inc}
Così hai la possibilità di avere le tre versioni tramite include...

L'alternativa è vedere (ma ho cercato rapidamente senza trovarlo) se hai la possibilità di avere il nome direttamente da qualche funzione / costante da testare.
Con questa strada ti riporti alla versione più simile a quella java...

Titolo: Re:Spegnimento PC
Inserito da: bonmario - Settembre 19, 2012, 06:23:29 pm
Scusa, ma sono di fretta ... io uso questo che va su windows e Linux
Codice: [Seleziona]
      {$IFDEF MSWINDOWS}
        Comando:='ShutDown';
        Parametri:='-s -f -t 0';
        EseguiProcesso(Comando, Parametri, False);
      {$ELSE}
        MinutiStr:=IntToStr(Ritardo div 60);

        //Comando:='/sbin/shutdown';
        //Parametri:='-h now';
        //EseguiProcesso(Comando, Parametri, False);


        Comando:='/usr/bin/dbus-send';
        Parametri:='--system --print-reply --dest=org.freedesktop.Hal /org/freedesktop/Hal/devices/computer org.freedesktop.Hal.Device.SystemPowerManagement.Shutdown';
        EseguiProcesso(Comando, Parametri, False);

        //Aspetto 30 secondi. Se il PC è ancora acceso, provo con lo shutdown
        Sleep(30 * CstSecondi);
        Comando:='/sbin/shutdown';
        Parametri:='-h now';
        EseguiProcesso(Comando, Parametri, False);

        //Aspetto 30 secondi. Se il PC è ancora acceso, provo con lo shutdown che mi sono
        //salvato nella directory uty
        Sleep(30 * CstSecondi);
        Comando:='/home/bonmario/uty/shutdown';
        Parametri:='-h now';
        EseguiProcesso(Comando, Parametri, False);

        //Aspetto 30 secondi. Se il PC è ancora acceso, alzo bandiera bianca
        //ed emetto un messaggio di errore !!!!
        Sleep(30 * CstSecondi);
        EmettiErrore(0, 'Impossibile spegnere il PC :-(((');
      {$ENDIF}

Purtroppo richiama altre mie procedure mie, ma credo che in ogni caso sia capibile. Se ci sono problemi chiedi pure, appena torno a casa ti rispondo.

Ciao, Mario
Titolo: Re:Spegnimento PC
Inserito da: xinyiman - Settembre 20, 2012, 03:55:00 pm
Mi passi anche la procedura EseguiProcesso...grazie
Titolo: Re:Spegnimento PC
Inserito da: bonmario - Settembre 20, 2012, 08:21:51 pm
Subito !!!

Codice: [Seleziona]
{Eseguo un comando ed attendo fino a quando non termina}
  function  EseguiProcesso(const Comando, Parametri:string;Visualizza:Boolean;
                           ForzaDirCorrente:String = ''):String;
  var MyProcess:TProcess;
      OraInizio, OraAttuale:DWord;
      Appo:String;
  begin
    //Imposto un valore che faccia capire al chiamante se il comando non è stato eseguito
    Result:=CstProcNonExec;

    MyProcess:=TProcess.Create(nil);
    MyProcess.CommandLine:=Comando + ' ' + Parametri;
    if (ForzaDirCorrente = '') then begin
      MyProcess.CurrentDirectory:=ExtractFileDir(Comando);
    end else begin
      MyProcess.CurrentDirectory:=AppendPathDelim(ForzaDirCorrente);
    end;

    //Faccio in modo che nel titolo della finestra venga scritto il comando lanciato.
    //Questo dovrebbe funzionare solo quando viene eseguito un comando DOS
    MyProcess.ConsoleTitle:=Comando + ' ' + Parametri;

    if Visualizza then MyProcess.ShowWindow:=swoShow
                  else MyProcess.ShowWindow:=swoHIDE;

//    Priorità dalla più bassa alla più alta:
//    ppIdle
//    ppNormal
//    ppHigh
//    ppRealTime

    MyProcess.Priority:=ppIdle;  // priorità bassa
    try
      try
        MyProcess.Execute;

        OraInizio:=GetTickCount;
        while MyProcess.Running do begin
          Sleep(100);
          OraAttuale:=GetTickCount;
          // Ogni 5 secondi aggiorno il video
          if ((OraAttuale - OraInizio) >= (5 * CstSecondi)) then begin
            OraInizio:=OraAttuale;
            AggiornaVideo
          end;
        end;

        //Comunico al chiamante il risultato dell/esecuzione
        Result:=IntToStr(MyProcess.ExitStatus);
      finally
        // Libero la memoria
        FreeAndNil(MyProcess);
      end;
    except
      on E:Exception do begin
        //Comunico al chiamante che qualcosa è andato storto
        Result:=E.Message;
      end;
    end;

    // Aggiorno il video
    AggiornaVideo
  end;

P.S. "AggiornaVideo" è un semplice "Application.ProcessMessages".

Ciao, Mario
Titolo: Re:Spegnimento PC
Inserito da: xinyiman - Settembre 21, 2012, 03:45:03 pm
Non ricordo una cosa, la procedura che lancia l'eseguibile esterno, aspetta la chiusura dell'eseguibile esterno o va avanti subito dopo averlo lanciato?
Titolo: Re:Spegnimento PC
Inserito da: bonmario - Settembre 21, 2012, 04:11:59 pm
Se ti riferisci ad "EseguiProcesso" cicla fino a quando "while MyProcess.Running do begin", quindi esce solo quando l'eseguibile lanciato ha finito il suo lavoro ed ogni 5 secondi aggiorna il video per evitare che il programma chiamante sembri in loop.

Ciao, Mario