[RISOLTO] Messaggio Di domanda prima del shutdown

di il
10 risposte

[RISOLTO] Messaggio Di domanda prima del shutdown

Buonasera, sto programmando un software timesheet.
Per far ricordare ai collaboratori di inserire il timesheet ho pensato che, prima dello spegnimento del computer, il programma (o un servizio) chiedesse se avesse inserito il timesheet e se l'utente clicca "Sì" il computer prosegue lo spegnimento altrimenti il pc rimane accesso.
Ho già cercato su google però non ho trovato una risposta, soltanto verificare se il pc si spegne quando il programma è aperto.
Ho provato con c# windows service ma niente da fare .

        [DllImport("wtsapi32.dll", SetLastError = true)]
        static extern bool WTSSendMessage(
        IntPtr hServer,
        [MarshalAs(UnmanagedType.I4)] int SessionId,
        String pTitle,
        [MarshalAs(UnmanagedType.U4)] int TitleLength,
        String pMessage,
        [MarshalAs(UnmanagedType.U4)] int MessageLength,
        [MarshalAs(UnmanagedType.U4)] int Style,
        [MarshalAs(UnmanagedType.U4)] int Timeout,
        [MarshalAs(UnmanagedType.U4)] out int pResponse,
        bool bWait);

        protected override void OnStart(string[] args)
        {
            bool result = false;
            String title = "Alert";
            int tlen = title.Length;
            String msg = "Hai inserito il timesheet?";
            int mlen = msg.Length;
            int resp = 7;
            result = WTSSendMessage(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, title, tlen, msg, mlen, 4, 3, out resp, true);
            int err = Marshal.GetLastWin32Error();
        }
My mostra errore su "WTS_CURRENT_SERVER_HANDLE" e "WTS_CURRENT_SESSION" e comunque non andrebbe bene poichè mostra un messaggio e non una domanda.

Non so più cosa fare

10 Risposte

  • Re: [RISOLTO] Messaggio Di domanda prima del shutdown

    Qui trovi un semplice service in C++

    https://www.codeproject.com/Articles/499465/Simple-Windows-Service-in-Cplusplus

    Immagino sia sufficiente modificarlo in modo che apra una dialogo nel metodo shutdown

    Rimane infine da installare il servizio sui diversi PC e inserirlo in avvio automatico.

    Tuttavia non so dirti se sia sufficiente ad arrestare il processo di shutdown del sistema operativo che potrebbe forzare la chiusura del tuo servizio. Immagino ci siano un po' di prove da fare.
  • Re: [RISOLTO] Messaggio Di domanda prima del shutdown

    Grazie! Ti farò sapere!
  • Re: [RISOLTO] Messaggio Di domanda prima del shutdown

    Leggi con attenzione la docentazionw di questa API per Windows

    https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-shutdownblockreasoncreate
  • Re: [RISOLTO] Messaggio Di domanda prima del shutdown

    Ma è corretto usare il metodo "MessageBox" in un servizio c++?
  • Re: [RISOLTO] Messaggio Di domanda prima del shutdown

    I servizi normalmente non interagiscono con il desktop quindi non sarebbe corretto. Tuttavia puoi indicare ad un servizio che deve interagire col desktop esplicitamente.

    In ogni caso puoi ritardare lo shutdown per un tempo molto limitato, la chiusura comunque può essere forzata
  • Re: [RISOLTO] Messaggio Di domanda prima del shutdown

    Che sappia io, non è possibile impedire il riavvio del PC.
    Lo si può ritardare, ma non impedire.

    Anni fa (ai tempi di XP) avevo un problema simile al tuo, però l'ho risolto con una banale domanda in fase di chiusura della mia applicazione. In pratica:
    - Nell'avvio automatico viene eseguita l'applicazione
    - Quando chiudi l'applicazione ti chiede "hai fatto tutto?"


    Quella semplice domanda è un po' una rottura di scatole quando chiudi il programma con la X (perchè di norma la si chiude dopo aver fatto le registrazioni), però se provavi a riavviare il sistema, questo diceva "non riesco a chiudere l'applicazione X. Procedere con l'arresto forzato?"

    In questo modo vedevi che c'era un problema con l'applicazione, andavi a rispondere alla domanda (e/o fare quello che dovevi) e poi riavviavi il PC.

    Ovvio, non garantisce che l'utente lo faccia, ma su quello non puoi farci nulla
  • Re: [RISOLTO] Messaggio Di domanda prima del shutdown

    PiGi, penso che la tua risposta sia quella più semplice. Ci sarebbe un modo per cambiare: "non riesco a chiudere l'applicazione X" a "Hai inserito il timesheet?"
  • Re: [RISOLTO] Messaggio Di domanda prima del shutdown

    Scusa, la domanda era stata messa con una frase buttata lì per capirci.

    In realtà stai in ascolto dell'evento "onClosing" della finestra principale.
    Quando si scatena puoi fare quello che vuoi:
    - Se hai già salvato (sei nella tua app, quindi sai se l'hai fatto o meno), allora non chiedi nulla e chiudi
    - Se non hai già salvato, allora fai la domanda col testo che vuoi (è una normale MessageBox.ShowDialog)
    - In base all'esito (risposta si/no) puoi decidere di annullare la chiusura o meno

    Se cerchi in internet trovi un sacco di post/esempi su come procedere. Non metto link per evitare il "cross-qualchecosa" che è vietato.


    Unica cosa: è da verificare se Windows 10 fa come XP e segnala che ha problemi a chiudere l'app X (la tua), oppure se la killa brutalmente.
  • Re: [RISOLTO] Messaggio Di domanda prima del shutdown

    PiGi78 ha scritto:


    ...Non metto link per evitare il "cross-qualchecosa" che è vietato...
    Il concetto di crossposting è inteso in un'altra maniera. Certo, nessuno è esentato dall'applicare il STFW, ma se si ha uno o più link di risorse utili alla discussione a portata di mano, postarli male non fa.
  • Re: [RISOLTO] Messaggio Di domanda prima del shutdown

    Ho risolto con un semplicissimo codice. Grazie mille a tutti! Condivido il codice in caso che qualcuno abbia lo stesso problema/dubbio:
    [CODE]using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace AdvTSReminder { public partial class Form1 : Form { [DllImport("user32.dll")] public extern static bool ShutdownBlockReasonCreate(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)] string pwszReason); private bool blocked = false; public Form1() { InitializeComponent(); } protected override void WndProc(ref Message aMessage) { const int WM_QUERYENDSESSION = 0x0011; const int WM_ENDSESSION = 0x0016; if (blocked && (aMessage.Msg == WM_QUERYENDSESSION || aMessage.Msg == WM_ENDSESSION)) return; base.WndProc(ref aMessage); } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { //Ora è if(true) però aggiungerò un controllo per vedere se è stato inserito il timesheet if(true) { if (ShutdownBlockReasonCreate(this.Handle, "Hai dimenticato di inserire il timesheet!")) { blocked = true; } } } } } Potete anche chiudere il thread
Devi accedere o registrarti per scrivere nel forum
10 risposte