2009-07-17 19 views
12

Qual è il modo migliore per programmare a livello di codice che una macchina Windows XP (o successiva) si attivi in ​​un momento specifico. (Idealmente molto simile a come Media Center può avviarsi automaticamente per registrare un particolare programma TV)Pianifica la macchina per svegliarsi

Ho un servizio di Windows (scritto in C#) e mi piacerebbe che questo servizio fosse in grado di causare la macchina è ospitato per l'avvio in tempi prestabiliti.

Esistono impostazioni BIOS o prerequisiti (ad esempio ACPI) che devono essere configurati affinché funzioni correttamente?

Questa macchina utilizza dialup o modem wireless 3G, quindi purtroppo non può fare affidamento su Wake on LAN.

+0

Forse le persone su http://serverfault.com lo saprebbero. – jmservera

risposta

10

È possibile utilizzare waitable timers di svegliarsi da uno stato di sospensione o ibernazione. Da quello che posso trovare, non è possibile riattivare a livello di programmazione dalla normale modalità di spegnimento (soft off/S5), in tal caso, è necessario specificare un allarme WakeOnRTC nel BIOS. Per utilizzare i timer attendibili da C#, è necessario pInvoke. Le dichiarazioni di importazione sono:

public delegate void TimerCompleteDelegate(); 

[DllImport("kernel32.dll", SetLastError = true)] 
static extern IntPtr CreateWaitableTimer(IntPtr lpTimerAttributes, bool bManualReset, string lpTimerName); 

[DllImport("kernel32.dll", SetLastError = true)] 
static extern bool SetWaitableTimer(IntPtr hTimer, [In] ref long pDueTime, int lPeriod, TimerCompleteDelegate pfnCompletionRoutine, IntPtr pArgToCompletionRoutine, bool fResume); 

[DllImport("kernel32.dll", SetLastError = true)] 
public static extern bool CancelWaitableTimer(IntPtr hTimer); 

È possibile utilizzare queste funzioni nel modo seguente:

public static IntPtr SetWakeAt(DateTime dt) 
{ 
    TimerCompleteDelegate timerComplete = null; 

    // read the manual for SetWaitableTimer to understand how this number is interpreted. 
    long interval = dt.ToFileTimeUtc(); 
    IntPtr handle = CreateWaitableTimer(IntPtr.Zero, true, "WaitableTimer"); 
    SetWaitableTimer(handle, ref interval, 0, timerComplete, IntPtr.Zero, true); 
    return handle; 
} 

si può quindi annullare il timer waitable con CancelWaitableTimer, utilizzando l'handle restituito come argomento.

Il programma può hibernate e dormire con PInvoke:

[DllImport("powrprof.dll", SetLastError = true)] 
[return: MarshalAs(UnmanagedType.Bool)] 
private static extern bool SetSuspendState(bool hibernate, bool forceCritical, bool disableWakeEvent); 

public static bool Hibernate() 
{ 
    return SetSuspendState(true, false, false); 
} 

public static bool Sleep() 
{ 
    return SetSuspendState(false, false, false); 
} 

Il vostro sistema potrebbe non consentire ai programmi per lasciare che il computer può entrare in modalità di sospensione. È possibile chiamare il seguente metodo per consentire la sospensione:

public static bool EnableHibernate() 
{ 
    Process p = new Process(); 
    p.StartInfo.FileName = "powercfg.exe"; 
    p.StartInfo.CreateNoWindow = true; 
    p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; 
    p.StartInfo.Arguments = "/hibernate on"; // this might be different in other locales 
    return p.Start(); 
} 
+0

Sembra che potrebbe essere. Ho trovato un altro esempio di questo qui - http://www.codeproject.com/Articles/49798/Wake-the-PC-from-standby-or-hibernation –

+0

Ho seguito il tuo codice, Il sistema può essere avviato con successo in modalità ibernazione , ma, non è stato riattivato dalla modalità di ibernazione al momento specificato. – Viswa

+0

Non ho seguito questo codice effettivo, ma posso garantire che su hardware decennale (con le opzioni del BIOS impostate (vedi sotto)), questa API Win32 funzioni. Ho scritto uno strumento di sincronizzazione C# che ha funzionato bene. –

0

Alcune macchine dispongono di una sveglia BIOS che può essere impostata per riattivare il computer a una determinata ora. Dovrebbe essere possibile programmare questo orologio, ma non conosco i dettagli specifici.

Modifica: ho trovato questo program che dovrebbe consentire di impostare l'ora. È in C, sotto Linux, ma forse può darti qualche suggerimento.

Un avvertimento però: prima di provare tutto ciò che cambia le impostazioni del BIOS siano direttamente sicuro annotare ogni impostazione dagli schermi del BIOS, perché in caso di errore del BIOS potrebbe tornare alle impostazioni di fabbrica e potrebbe essere necessario sistemalo di nuovo com'era.

1

La soluzione migliore è utilizzare la capacità Wake on LAN. Ciò richiederà ad un'altra macchina di inviare un pacchetto di un tipo speciale per riattivare la macchina.

Questo non sarà utile se la vostra macchina non è collegata alla rete o per qualche motivo non dovreste spostare questa logica su un'altra macchina. Ma è utile per alcune configurazioni in cui si hanno più macchine e si desidera risvegliarle a livello di programmazione.

4

Il programma di pianificazione attività in Win7, taskschd.msc (e anche Windows XP) può essere impostato per riattivare il sistema su trigger diversi. Questi trigger possono essere orari, eventi, ecc.

In almeno Win7, è necessario impostare "Consenti timer di sveglia" su "Abilitato" affinché funzioni. Questa impostazione si trova sotto ...

-> Pannello di controllo \ Hardware e Opzioni risparmio energia \ audio
click - "Modifica impostazioni combinazione"
click - "Cambiare impostazione di potenza avanzate"
espandere - "Sleep"
Expand - "Consenti timer di riattivazione"

+0

Penso che questo si stia avvicinando alla vera risposta. Poiché desidero eseguire questa operazione a livello di codice, desidero sapere quale API utilizzare per impostare un timer di sveglia –

+0

Bene, lo schedulatore di attività in Win7 è diverso da quello in XP. Per XP è possibile utilizzare il comando at (http://support.microsoft.com/kb/313565) o l'API Task Scheduler 1.0 (http://msdn.microsoft.com/en-us/library/aa383579(VS. 85) aspx). Hai un wrapper in http://www.codeproject.com/KB/cs/tsnewlib.aspx. Mentre in Windows 7 hai la nuova API 2.0 (http://msdn.microsoft.com/en-us/library/aa384138(VS.85).aspx) – jmservera

Problemi correlati