Con quale utente vengono eseguiti i servizi in Windows? Servizi Windows. Cosa sono i servizi

Modalità operative

Nella maggior parte dei casi, ai servizi è vietato interagire con la console o il desktop degli utenti (sia locali che remoti), ma per alcuni servizi è possibile un'eccezione: l'interazione con la console (sessione numero 0 in cui l'utente è registrato localmente o quando inizia il servizio mstsc con l'opzione /console).

Esistono diverse modalità per i servizi:

  • vietato il lancio;
  • avviamento manuale (a richiesta);
  • avvio automatico all'avvio del computer;
  • avvio automatico (ritardato) (introdotto in Windows Vista e Windows Server 2008);
  • servizio/autista obbligatorio (avvio automatico e impossibilità (per l'utente) di interrompere il servizio).

Modalità sfondo

Avvia, arresta e modifica i servizi Windows

I servizi e i loro attributi possono essere modificati nella MMC:

In diverse versioni sistemi operativi Alcuni servizi potrebbero essere presenti ed altri assenti. Anche alcune applicazioni e programmi installati separatamente possono creare i propri servizi.

Elenco dei servizi del sistema operativo Microsoft Windows

Nome da visualizzare Nome di Servizio Funzioni Descrizione
Cliente DHCP Dhcp Registra e aggiorna gli indirizzi IP e i record DNS per questo computer. Se questo servizio viene interrotto, il computer non sarà in grado di ottenere indirizzi IP dinamici ed eseguire aggiornamenti DNS.
Cliente DNS Dnscache Il servizio client DNS (dnscache) memorizza nella cache i nomi DNS (Domain Name System) e registra il nome completo di questo computer. Se il servizio viene interrotto, la risoluzione dei nomi DNS continuerà. Tuttavia, i risultati delle code dei nomi DNS non verranno memorizzati nella cache e il nome del computer non verrà registrato.
KtmRm per coordinatore delle transazioni distribuite KtmRm Coordina le transazioni tra MSDTC e Kernel Transaction Manager (KTM).
ReadyBoost EMDMgmt ReadyBoost Supporto per migliorare le prestazioni del sistema utilizzando la tecnologia ReadyBoost.
Superfetch SysMain Superfetch Mantiene e migliora le prestazioni del sistema.
Audio di Windows Audiosrv Gestione degli strumenti audio per Programmi Windows. Se questo servizio viene interrotto, i dispositivi audio e gli effetti non funzioneranno correttamente.
Spazio scheda di Windows idsvc Fornisce una capacità sicura di creare, gestire ed esporre identità digitali.
Aggiornamento automatico WUAUSER Include download e installazione Aggiornamenti di Windows. Se il servizio è disabilitato, non potrai utilizzare le funzionalità su questo computer. aggiornamento automatico o il sito Web di Windows Update.

Elenco dei servizi creati da applicazioni e programmi Microsoft

Elenco di servizi creati da applicazioni e programmi di altri produttori

Guarda anche

Elenco dei servizi Windows

Collegamenti

  • pcs.suite101.com/article.cfm/index_of_services: Indice dei servizi Windows XP: un indice dei servizi in esecuzione su Windows XP sistema operativo
  • Come rimuovere un servizio in Windows Vista o Windows XP
  • Servizi Windows XP (russo)

Fondazione Wikimedia. 2010.

Scopri cos'è "Servizi Windows" in altri dizionari:

    Servizi Windows SharePoint (WSS) componente aggiuntivo gratuito A Microsoft Windows Server 2003 e 2008, implementando una piattaforma web completa con supporto per le seguenti funzionalità: Sistema di gestione dei contenuti Strumenti di collaborazione... ... Wikipedia

    Sviluppatore Famiglia di sistemi operativi Microsoft Windows ... Wikipedia

    Componente Microsoft Windows... Wikipedia


Il servizio Windows NT è un processo speciale che dispone di un'interfaccia unificata per interagire con il sistema operativo Sistema Windows N.T. I servizi sono divisi in due tipi: servizi Win32, che interagiscono con il sistema operativo tramite Service Control Manager (SCM), e driver, che funzionano utilizzando il protocollo driver. Dispositivi Windows N.T. Discuteremo solo dei servizi Win32 più avanti in questo articolo.

Applicazione dei servizi

Una delle proprietà più importanti del servizio è la non interattività. Un tipico servizio viene eseguito in background senza che l'utente medio se ne accorga. Per questo motivo, i servizi sono più adatti per implementare i seguenti tipi di applicazioni:

  • Server in architettura client-server (ad esempio MS SQL, MS Exchange Server)
  • Rete Servizi Windows NT (server, postazione di lavoro);
  • Componenti server (in termini di funzionalità) di applicazioni distribuite (ad esempio, tutti i tipi di programmi di monitoraggio).

Proprietà fondamentali dei servizi

Il servizio si distingue da una normale applicazione Win32 per 3 proprietà principali. Diamo un'occhiata a ciascuno di essi.

Innanzitutto è possibile interrompere (sospendere) correttamente il servizio. Un utente o un'altra applicazione che utilizza meccanismi standard ha la capacità di modificare lo stato di un servizio, spostandolo da uno stato in esecuzione a uno stato in pausa o addirittura interrompendone l'esecuzione. In questo caso, prima di cambiare stato, il servizio riceve una notifica speciale, grazie alla quale può eseguire le azioni necessarie per passare a un nuovo stato, ad esempio rilasciare le risorse occupate.

In secondo luogo, la possibilità di avviare il servizio prima della registrazione dell'utente e, di conseguenza, la possibilità di lavorare senza un utente registrato. Qualsiasi servizio può essere avviato automaticamente all'avvio del sistema operativo e iniziare a funzionare anche prima che l'utente acceda al sistema.

E infine, la capacità di lavorare in un contesto di sicurezza arbitrario. Contesto Sicurezza di Windows NT definisce una serie di diritti di accesso del processo a vari oggetti e dati di sistema. A differenza di una tipica applicazione Win32, che viene sempre eseguita nel contesto di sicurezza dell'utente attualmente registrato nel sistema, per un servizio è possibile determinare in anticipo il contesto di sicurezza della sua esecuzione. Ciò significa che un servizio può avere la propria serie di diritti di accesso agli oggetti di sistema definiti in anticipo e quindi limitare la portata delle sue attività. Per i servizi esiste un tipo speciale di contesto di sicurezza predefinito denominato Sistema locale. Un servizio in esecuzione in questo contesto ha diritti solo sulle risorse del computer locale. Nessuna operazione di rete può essere eseguita con i diritti di sistema locale, poiché solo questo contesto ha senso computer locale e non viene riconosciuto da altri computer sulla rete.

Interazione del servizio con altre applicazioni

Qualsiasi applicazione dotata dei diritti appropriati può interagire con il servizio. L'interazione, innanzitutto, comporta la modifica dello stato del servizio, ovvero il suo trasferimento in uno dei tre stati: in esecuzione (Avvio), sospeso (Pausa), in arresto e viene eseguita inviando richieste SCM. Le richieste sono di tre tipi: messaggi dai servizi (che fissano i loro stati), richieste relative alla modifica della configurazione di un servizio o all'ottenimento di informazioni su di esso e richieste dell'applicazione per modificare lo stato di un servizio.

Per gestire un servizio è necessario prima ottenere il suo handle utilizzando la funzione API OpenService Win32. La funzione StartService avvia un servizio. Se necessario, lo stato del servizio viene modificato chiamando la funzione ControlService.

Banca dati dei servizi

Le informazioni su ciascun servizio sono archiviate nel registro, nella chiave HKLM\SYSTEM\CurrentControlSet\Services\ServiceName. Contiene le seguenti informazioni:

  • Tipo di servizio. Indica se questa applicazione implementa un solo servizio (esclusivo) o se ne sono presenti diversi nell'applicazione. Un servizio esclusivo in grado di operare in qualsiasi contesto di sicurezza. Più servizi all'interno della stessa applicazione possono essere eseguiti solo nel contesto LocalSystem.
  • Tipo di lancio. Automatico: il servizio si avvia all'avvio del sistema. Su richiesta: il servizio viene avviato manualmente dall'utente. Disattivato: il servizio non può essere avviato.
  • Il nome del modulo eseguibile (file EXE).
  • Ordine di avvio in relazione ad altri servizi. In alcuni casi, affinché un servizio funzioni correttamente, è necessario che uno o più altri servizi siano in esecuzione. In questo caso, il registro contiene informazioni sui servizi avviati prima di questo.
  • Contesto di sicurezza dell'esecuzione del servizio ( nome della rete e password). Per impostazione predefinita, il contesto di sicurezza è LocalSystem.

Le applicazioni che desiderano recuperare informazioni su un servizio o modificare l'impostazione di un servizio devono essenzialmente modificare le informazioni nel database del servizio nel registro. Questo può essere fatto utilizzando le corrispondenti funzioni API Win32:

  • OpenSCManager, CreateService, OpenService, CloseServiceHandle - per creare (aprire) un servizio;
  • QueryServiceConfig, QueryServiceObjectSecurity, EnumDependentServices, EnumServicesStatus - per ottenere informazioni sul servizio;
  • ChangeServiceConfig, SetServiceObjectSecurity, LockServiceDatabase, UnlockServiceDatabase, QueryServiceLockStatus: per modificare le informazioni sulla configurazione del servizio.

Struttura interna del servizio.

Affinché ciò accada, l'applicazione deve essere strutturata di conseguenza, ovvero includere un determinato insieme di funzioni (in termini C++) con una determinata funzionalità. Diamo un'occhiata brevemente a ciascuno di essi.

funzione principale

Come sai, la funzione principale è il punto di ingresso di qualsiasi applicazione console Win32. All'avvio del servizio, il codice per questa funzione inizia per primo ad essere eseguito. Entro 30 secondi dall'avvio, la funzione principale deve chiamare StartServiceCtrlDispatcher per stabilire una connessione tra l'applicazione e l'SCM. Tutte le comunicazioni tra qualsiasi servizio in una determinata applicazione e SCM vengono eseguite all'interno della funzione StartServiceCtrlDispatcher, che termina solo dopo l'arresto di tutti i servizi nell'applicazione.

Funzione ServiceMain

Oltre al punto di ingresso a livello di processo, esiste anche un punto di ingresso separato per ciascuno dei servizi implementati nell'applicazione. I nomi delle funzioni che sono punti di ingresso del servizio (per semplicità, chiamiamole tutte uguali - ServiceMain) vengono passati a SCM in uno dei parametri quando si chiama StartServiceCtrlDispatcher. All'avvio di ogni servizio, viene creato un thread separato per eseguire ServiceMain.

Dopo aver ricevuto il controllo, ServiceMain deve prima registrare un gestore della richiesta di servizio, la funzione Handler, per ogni servizio nell'applicazione. Questo è solitamente seguito in ServiceMain da alcune azioni per inizializzare il servizio: allocazione della memoria, lettura dei dati, ecc. Queste azioni devono essere accompagnate da notifiche SCM che indicano che il servizio è ancora in fase di avvio e che non si sono verificati errori. Le notifiche vengono inviate utilizzando le chiamate alla funzione SetServiceStatus. Tutte le chiamate tranne l'ultima devono essere con il parametro SERVICE_START_PENDING e la più recente deve essere con il parametro SERVICE_RUNNING. La frequenza delle chiamate viene determinata dallo sviluppatore del servizio in base alla seguente condizione: la durata dell'intervallo di tempo tra due chiamate SetServiceStatus adiacenti non deve superare il valore del parametro dwWaitHint passato all'SCM durante la prima delle due chiamate. In caso contrario SCM, non ricevendo in tempo la successiva notifica, interromperà forzatamente il servizio. Questo metodo consente di evitare la situazione del servizio all'avvio a causa del verificarsi di determinati guasti (ricordiamo che i servizi sono solitamente non interattivi e possono essere avviati in assenza dell'utente). La pratica abituale è che l'SCM venga avvisato dopo il completamento della fase di inizializzazione successiva.

Funzione del gestore

Come accennato in precedenza, Handler è un prototipo di funzione di callback, un gestore di richieste di servizio, unico per ciascun servizio nell'applicazione. Il gestore viene chiamato quando il servizio riceve una richiesta (avvio, pausa, ripresa, arresto, messaggio sullo stato corrente) ed esegue le azioni necessarie in conformità con la richiesta, dopodiché segnala il nuovo stato all'SCM.

Da notare in particolare una richiesta: la richiesta ricevuta all'arresto del sistema (Shutdown). Questa richiesta segnala la necessità di deinizializzare e terminare. Microsoft afferma che a ogni servizio vengono concessi 20 secondi per spegnersi prima di essere costretto a interrompersi. Tuttavia, i test hanno dimostrato che non sempre questa condizione è rispettata e il servizio è costretto ad interrompersi prima della scadenza di questo periodo di tempo.

Sistema di sicurezza del servizio

Qualsiasi azione sui servizi richiede che l'applicazione disponga dei diritti appropriati. Tutte le applicazioni dispongono dei diritti per connettersi a SCM, enumerare i servizi e verificare se il database dei servizi è bloccato. Solo le applicazioni con diritti amministrativi possono registrare un nuovo servizio nel sistema o bloccare il database del servizio.

Ogni servizio dispone di un descrittore di sicurezza che descrive quali utenti dispongono dei diritti su quale operazione. Predefinito:

  • Tutti gli utenti dispongono dei diritti SERVICE_QUERY_CONFIG, SERVICE_QUERY_STATUS, SERVICE_ENUMERATE_DEPENDENTS, SERVICE_INTERROGATE e SERVICE_USER_DEFINED_CONTROL;
  • Gli utenti appartenenti al gruppo Power Users e all'account LocalSystem dispongono inoltre dei diritti SERVICE_START, SERVICE_PAUSE_CONTINUE e SERVICE_STOP;
  • Gli utenti appartenenti ai gruppi Amministratori e Operatori di sistema dispongono del diritto SERVICE_ALL_ACCESS.

Servizi e interattività

Per impostazione predefinita, i servizi interattivi possono essere eseguiti solo nel contesto di sicurezza LocalSystem. Ciò è dovuto alle peculiarità della visualizzazione sullo schermo del monitor in Windows NT, dove è presente, ad esempio, un oggetto come "Desktop", per lavorare con il quale è necessario disporre dei diritti di accesso appropriati, cosa che un oggetto arbitrario potrebbe non avere. Avere. account, diverso da LocalSystem. Nonostante nella stragrande maggioranza dei casi questa limitazione non sia significativa, a volte c'è la necessità di creare un servizio che visualizzi le informazioni sullo schermo del monitor e allo stesso tempo venga eseguito in un contesto di sicurezza diverso da LocalSystem, ad esempio ad esempio, un componente del server delle applicazioni per eseguire applicazioni su un computer remoto.

Frammento di codice da . illustra questa possibilità.

In questo frammento, in risposta ad una richiesta inviata dal lato client dell'applicazione come conseguenza RPC, il servizio visualizza un messaggio di testo sullo schermo del monitor.

Servizio di esempio (snippet chiave)

Consideriamo l'esempio dei frammenti chiave di un'applicazione in C++ che implementa un servizio Windows NT. Per chiarezza, le parti non essenziali del codice sono state omesse.

funzione principale

Il codice della funzione principale è mostrato in B.

Funzione ServiceMain

Una caratteristica del codice contenuto in ServiceMain è che spesso è impossibile prevedere in anticipo il tempo di esecuzione di una determinata operazione, soprattutto considerando che la sua esecuzione avviene su un sistema operativo con multitasking preemptive. Se l'operazione richiede più tempo dell'intervallo di tempo specificato nel parametro di chiamata SetServiceStatus, il servizio non sarà in grado di inviare la notifica successiva in tempo, causando l'interruzione del funzionamento di SCM. Esempi di operazioni potenziali potrebbero essere chiamate a funzioni di rete con timeout prolungati o letture singole grande quantità informazioni provenienti da media lenti. Inoltre, questo approccio è del tutto inapplicabile durante il debug di un servizio, poiché l'esecuzione del programma nel debugger è accompagnata da lunghe pause necessarie allo sviluppatore.

Per superare questo problema, tutte le operazioni che interagiscono con l'SCM dovrebbero essere eseguite in un thread separato, indipendente dalle azioni che avvengono durante la fase di inizializzazione.

B mostra un algoritmo per avviare correttamente un servizio utilizzando un thread ausiliario.

Funzione del gestore

B mostra il codice per la funzione Handler e i thread ausiliari. Per le richieste di "Stop" e "Shutdown" viene utilizzato un algoritmo per arrestare correttamente il servizio, simile a quello utilizzato per l'avvio di un servizio, con l'unica differenza che al posto del parametro SERVICE_START_PENDING viene passato a SetserviceStatus il parametro SERVICE_STOP_PENDING e invece di SERVICE_RUNNING - SERVICE_STOPPED.

Idealmente, anche le richieste "Pausa" e "Continua" dovrebbero utilizzare questo approccio. Un lettore curioso può facilmente implementarlo sulla base di questi esempi.

Conclusione

In conclusione ricordiamo che con il passaggio a Windows NT 2000 lo sviluppo dei servizi non è cambiato. I servizi continuano a rappresentare una parte importante del software sulla piattaforma Windows, offrendo agli sviluppatori un'ampia gamma di opzioni.


// Funzione simile a MessageBox Win32 API int ServerMessageBox(RPC_BINDING_HANDLE h, LPSTR lpszText, LPSTR lpszTitle, UINT fuStyle) ( DWORD dwThreadId; HWINSTA hwinstaSave; HDESK hdeskSave; HWINSTA hwinstaUser; HDESK hdeskUser; int result; // Ricorda gli oggetti correnti "W indow station " e "Desktop". GetDesktopWindow(); hwinstaSave = GetProcessWindowStation(); dwThreadId = GetCurrentThreadId(); hdeskSave = GetThreadDesktop(dwThreadId); // Cambia il contesto di sicurezza in quello // del client RPC chiamante // e ottenere l'accesso agli oggetti // utente "Window station" e "Desktop". RpcImpersonateClient(h); hwinstaUser = OpenWindowStation("WinSta0", FALSE, MAXIMUM_ALLOWED); if (hwinstaUser == NULL) ( RpcRevertToSelf(); return 0; ) SetProcessWindowStation( hwinstaUser); hdeskUser = OpenDesktop("Default", 0, FALSE, MAXIMUM_ALLOWED); RpcRevertToSelf(); if (hdeskUser == NULL) ( SetProcessWindowStation(hwinstaSave); CloseWindowStation(hwinstaUser); return 0; ) SetThreadDesktop(utentehdesk); // Visualizza una normale finestra di testo. risultato = MessageBox(NULL, lpszText, lpszTitle, fuStyle); // Ripristina gli oggetti salvati // "Stazione Windows" e "Desktop". SetThreadDesktop(hdeskSave); SetProcessWindowStation(hwinstaSave); ChiudiDesktop(hdeskUtente); ChiudiWindowStation(hwinstaUser); risultato restituito; ) void main() ( SERVICE_TABLE_ENTRY steTable = ( (SERVICENAME, ServiceMain), (NULL, NULL) ); // Stabilisce una connessione con SCM. All'interno di questa funzione // le richieste vengono ricevute e inviate. StartServiceCtrlDispatcher(steTable); ) void WINAPI ServiceMain (DWORD dwArgc, LPSTR *psArgv) ( // Registra immediatamente il gestore della richiesta. hSS = RegisterServiceCtrlHandler(SERVICENAME, ServiceHandler); sStatus.dwCheckPoint = 0; sStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE; sStatus.dwServiceSpecificExitC ode = 0;sStatus. dwServiceType = SERVICE_WIN32_OWN_PROCESS ; sStatus.dwWaitHint = 0; sStatus.dwWin32ExitCode = NOERROR; // Per inizializzare il servizio, viene richiamata la funzione InitService(); // Per garantire che il sistema non // scarichi il servizio durante il processo di inizializzazione, viene avviato un thread che segnala una volta ogni // secondo che il servizio è in fase di inizializzazione. // Viene creato un evento per sincronizzare il thread. // Successivamente viene avviato un thread di lavoro, // per il quale viene generato un evento viene // creato anche per la sincronizzazione. hSendStartPending = CreateEvent(NULL, TRUE, FALSE, NULL); MANIGLIA hSendStartThread; DWORD dwThreadId; hSendStartThread = CreateThread(NULL, 0, SendStartPending, NULL, 0, &dwThreadId); //Tutta l'inizializzazione del servizio viene eseguita qui. InitService(); SetEvent(hSendStartPending); if(WaitForSingleObject(hSendStartThread, 2000) != WAIT_OBJECT_0) ( TerminateThread(hSendStartThread, 0); ) CloseHandle(hSendStartPending); CloseHandle(hSendStartThread); hWork = CreaEvento(NULL, VERO, FALSO, NULL); hServiceThread = CreateThread(NULL, 0, ServiceFunc, 0, 0, &dwThreadId); sStatus.dwCurrentState = SERVICE_RUNNING; SetServiceStatus(hSS, &sStatus); ) // Una funzione thread che invia notifiche all'SCM // ogni secondo in cui è in corso il processo di inizializzazione. La funzione // termina quando viene impostato l'evento hSendStartPending //. DWORD WINAPI SendStartPending(LPVOID) ( sStatus.dwCheckPoint = 0; sStatus.dwCurrentState = SERVICE_START_PENDING; sStatus.dwWaitHint = 2000; // “Sleep” per 1 secondo. Se dopo 1 secondo // l'evento hSendStartPending non ha // inserito il segnale state (l'inizializzazione del servizio non è // terminata), inviamo la notifica successiva, // impostando l'intervallo di tempo massimo // a 2 secondi, in modo che ci sia un margine di tempo fino // alla notifica successiva. while (true ) ( ​​SetServiceStatus(hSS, &sStatus); sStatus .dwCheckPoint++; if(WaitForSingleObject(hSendStartPending, 1000)!=WAIT_TIMEOUT) break; ) sStatus.dwCheckPoint = 0; return 0; ) // Funzione che inizializza il servizio. Lettura di dati, // allocazione di memoria, ecc. void InitService() ( ... ) // Funzione contenente il codice del servizio. DWORD WINAPI ServiceFunc(LPVOID) ( while (true) ( ​​​​if (!bPause) ( // Contiene codice che in genere // esegue alcuni tipi di operazioni cicliche... ) if (WaitForSingleObject(hWork, 1000)!=WAIT_TIMEOUT ) break; ) return 0; ) // Gestore delle richieste da SCM void WINAPI ServiceHandler(DWORD dwCode) ( switch (dwCode) ( case SERVICE_CONTROL_STOP: case SERVICE_CONTROL_SHUTDOWN: ReportStatusToSCMgr(SERVICE_STOP_PENDING, NO_ERROR, 0, 1000); hSendStopPending = CreateEvent(NULL, VERO, FALSO, NULL); hSendStopThread = CreateThread(NULL, 0, SendStopPending, NULL, 0, & dwThreadId); SetEvent(hWork); if (WaitForSingleObject(hServiceThread, 1000) != WAIT_OBJECT_0) ( TerminateThread(hServiceThread, 0); ) SetEvent(hSendStopPending); CloseHandle(hServiceThread); CloseHandle(hWork); if(WaitForSingleObject(hSendStopThread, 2000) != WAIT_OBJECT_0) ( TerminateThread(hSendStopThread, 0); ) CloseHandle(hSendStopPending); sStatus.dwCurrentState = SERVICE_STOPPED; SetServiceStatus ( hSS, &sStato); rottura; caso SERVICE_CONTROL_PAUSE: bPause = true; sStatus.dwCurrentState = SERVICE_PAUSED; SetServiceStatus(hSS, &sStatus); rottura; caso SERVICE_CONTROL_CONTINUE: bPause = true; sStatus.dwCurrentState = SERVICE_RUNNING; SetServiceStatus(hSS, &sStatus); rottura; caso SERVICE_CONTROL_INTERROGATE: SetServiceStatus(hSS, &sStatus); rottura; impostazione predefinita: SetServiceStatus(hSS, &sStatus); rottura; ) ) // Funzione thread simile a SendStartPending // per interrompere il servizio. DWORD WINAPI SendStopPending(LPVOID) ( sStatus.dwCheckPoint = 0; sStatus.dwCurrentState = SERVICE_STOP_PENDING; sStatus.dwWaitHint = 2000; while (true) ( ​​​​SetServiceStatus(hSS, &sStatus); sStatus.dwCheckPoint++; if(WaitForSingleObject( hSendStopPending, 10 00 )! =WAIT_TIMEOUT) break; ) sStatus.dwCheckPoint = 0; return 0; )

Come eseguire un'applicazione come servizio Windows

È possibile eseguire un'applicazione client come servizio? In uno di essi ho descritto come creare un servizio Windows utilizzando gli strumenti del sistema operativo standard. Tuttavia, non tutte le applicazioni console possono essere eseguite come servizi e i programmi con un'interfaccia grafica, in linea di principio, non possono funzionare in questo modo. Ma è ancora possibile eseguire l'applicazione come servizio e un programma con un nome originale ci aiuterà in questo Responsabile del servizio non succhiante.

NSSM è un servizio gratuito Software Con fonte aperta e supporta tutti i sistemi operativi Microsoft, da Windows 2000 a Windows 8. NSSM non necessita di installazione, basta scaricarlo e scompattarlo. La distribuzione include versioni per sistemi operativi a 32 e 64 bit. Puoi scaricare il programma dal sito nssm.cc, al momento l'ultima versione stabile è la 2.21.1, che userò.

Per dimostrare le capacità di NSSM, proviamo a correre Blocco note di Windows come servizio su Windows 8.1.

Creazione di un servizio

Per creare un servizio denominato bloc notes avviare la console dei comandi, accedere alla cartella con NSSM decompresso (per Windows a 64 bit) e immettere il comando nssm install notepad, che apre la finestra grafica dell'installazione di NSSM. Per creare un servizio, basta specificare il percorso del file eseguibile nel campo Percorso e fare clic sul pulsante "Installa servizio". Inoltre, nel campo Opzioni è possibile specificare le chiavi necessarie per avviare il servizio.

Puoi anche specificare alcuni parametri aggiuntivi durante la creazione di un nuovo servizio.

La scheda Spegnimento elenca i metodi di spegnimento e i timeout utilizzati quando l'applicazione si spegne normalmente o si blocca. Quando NSSM riceve un comando di arresto (ad esempio, quando un'applicazione viene arrestata), tenta di arrestare l'applicazione controllata in modo normale. Se l'applicazione non risponde, NSSM può terminare forzatamente tutti i processi e sottoprocessi di questa applicazione.

Esistono quattro passaggi per chiudere l'applicazione e per impostazione predefinita verranno utilizzati in questo ordine:

Nella prima fase, NSSM tenta di generare e inviare un evento CTRL+C. Questo metodo funziona bene per le applicazioni console o gli script, ma non è applicabile alle applicazioni grafiche;
NSSM rileva quindi tutte le finestre create dall'applicazione e invia loro un messaggio WM_CLOSE, provocando la chiusura dell'applicazione;
Il terzo passo è che NSSM calcola tutti i thread creati dall'applicazione e invia loro un messaggio WM_QUIT, che verrà ricevuto se l'applicazione ha una coda di messaggi di thread;
Come ultima risorsa, NSSM può chiamare il metodo TerminateProcess(), forzando la chiusura dell'applicazione.

È possibile disabilitare alcuni o addirittura tutti i metodi, ma a diverse applicazioni Funzionano diversi metodi e, per chiudere correttamente l'applicazione, si consiglia di lasciare tutto così com'è.

Per impostazione predefinita, quando un servizio si arresta in modo anomalo, NSSM tenta di riavviarlo. Nella scheda "Azioni di uscita", puoi modificare l'azione automatica quando l'applicazione si chiude in modo anomalo, nonché impostare un ritardo prima che l'applicazione si riavvii automaticamente.

Nella scheda "Input/Output (I/O)", è possibile impostare il reindirizzamento dell'input/output dell'applicazione su un file specificato.

Nella scheda "Ambiente", puoi impostare nuove variabili di ambiente per il servizio o sovrascrivere quelle esistenti.

Puoi anche non utilizzare la shell grafica e creare immediatamente un servizio nella console con il seguente comando:

nssm installa il blocco note ″C:\Windows\system32\notepad.exe″

Gestione del servizio

Dopo aver creato il servizio utilizzando NSSM, vai allo snap-in Servizi e trova il servizio Blocco note. Come puoi vedere, nell'aspetto non è diverso dagli altri servizi; possiamo anche avviarlo, fermarlo o cambiare la modalità di avvio. Tuttavia, tieni presente che nssm.exe è elencato come file eseguibile.

E se andiamo a Task Manager, vedremo la seguente immagine: NSSM è in esecuzione come processo principale (genitore), il servizio Blocco note è in esecuzione come processo figlio e l'applicazione Blocco note è già in esecuzione in questo processo figlio.

Rimozione di un servizio

Per rimuovere un servizio, inserisci il comando nssmremovenotepad e confermane la rimozione. E inserendo il comando nssm rimuovi notepad confirm , puoi fare a meno della conferma.

Avvia un servizio in modo interattivo

Differenza principale applicazione personalizzata da un servizio è che dopo l'avvio dell'applicazione potrebbero essere necessarie ulteriori azioni da parte dell'utente per continuare a lavorare, ad esempio la pressione di un pulsante o l'immissione di un comando. Per fare ciò, è necessario accedervi, il che, a quanto pare, non è così facile.

Per avviare un servizio in modalità interattiva, è necessario aprire le sue proprietà nello snap-in Servizi e nella scheda "Login" selezionare la casella di controllo "Consenti interazione con il desktop".

E poi iniziano i miracoli :) Un servizio avviato in modalità interattiva si apre in una sessione isolata (sessione 0). È possibile accedere a questa sessione solo utilizzando il servizio di rilevamento dei servizi interattivi (ui0detect), che monitora l'avvio dei servizi interattivi sul computer ed emette un avviso. In Windows 7\Server 2008 questo servizio è attivo per impostazione predefinita, ma in Windows 8\Server 2012 è disabilitato e non appare nello snap-in grafico Servizi (almeno non l'ho trovato lì). Inoltre, se trovi questo misterioso servizio e provi ad avviarlo, riceverai un messaggio di errore.

Ma il fatto è che per eseguirlo è necessario consentire l'esecuzione dei servizi interattivi sul tuo computer. Apri quindi l'editor del registro, trova nella sezione HKLM\System\CurrentControlSet\Control\Windows un parametro di tipo DWORD denominato Nessun servizio interattivo e impostarne il valore su 0 .

Apri quindi la console di PowerShell e avvia il servizio di discovery con il comando:

Start-Service -Nome ui0detect

Dopo esserci assicurati che il servizio di rilevamento sia in esecuzione, riavviamo il servizio Blocco note e otteniamo questa finestra. Seleziona "Visualizza messaggio"

e ci troviamo nella sessione nulla in cui viene eseguita la nostra applicazione. Quindi eseguiamo le azioni necessarie con esso e torniamo indietro.

Questa è una soluzione interessante per eseguire applicazioni come servizi Windows. Non il più bello, ma abbastanza coerente con il suo nome :)

Ultimo aggiornamento: 31/10/2015

Uno dei componenti più importanti del sistema operativo Windows sono i servizi. Si tratta infatti di applicazioni separate che non dispongono di un'interfaccia grafica e che svolgono diverse attività in background. I servizi possono essere avviati all'avvio del sistema operativo o in qualsiasi altro momento in cui l'utente sta lavorando. Un esempio comune di servizi sono vari server web che ascoltano in background su una porta specifica per le connessioni e, se ci sono connessioni, interagiscono con esse. Potrebbero anche trattarsi di vari servizi di aggiornamento ausiliari per altri programmi installati, che contattano il server per scoprire se esiste una nuova versione applicazioni. In generale, possiamo aprire il pannello dei servizi e vedere di persona tutti i servizi installati e in esecuzione:

Diamo un'occhiata a come creare i tuoi servizi in C#. Come attività da implementare, sceglieremo di monitorare le modifiche in una cartella specifica nel file system. Ora creiamo un servizio per eseguirlo.

Per prima cosa creiamo un nuovo progetto, che sarà di tipo Servizio Windows. Chiamiamo il progetto FileWatcherService:

Visual Studio genera quindi un progetto che contiene tutto ciò di cui hai bisogno. Anche se non dobbiamo necessariamente scegliere questo tipo di progetto, potremmo creare un progetto di libreria di classi e quindi definire al suo interno tutte le classi necessarie.

Quindi il nuovo progetto si presenta così:

C'è anche un file Program.cs e c'è il nodo del servizio vero e proprio Service1.cs.

Il servizio rappresenta una normale applicazione, ma non si avvia da sola. Tutte le chiamate e l'accesso ad esso passano attraverso il gestore del controllo del servizio (Service Control Manager o SCM). Quando un servizio viene avviato automaticamente all'avvio del sistema o manualmente, SCM chiama il metodo Main nella classe Program:

Classe statica Programma ( static void Main() ( ServiceBase ServicesToRun; ServicesToRun = new ServiceBase ( new Service1() ); ServiceBase.Run(ServicesToRun); ) )

Il metodo Main è definito per impostazione predefinita per eseguire più servizi contemporaneamente, definiti nella matrice ServicesToRun. Tuttavia, per impostazione predefinita, il progetto contiene un solo servizio, Servizio1. L'avvio stesso viene eseguito utilizzando il metodo Run: ServiceBase.Run(ServicesToRun) .

Il servizio avviato è rappresentato dal nodo Service1.cs. Tuttavia, questo non è in realtà un semplice file di codice. Se apriamo questo nodo, vedremo il file di progettazione del servizio Service1.Designer.cs e la classe Service1.

La classe Service1 rappresenta effettivamente il servizio. Di default ha il seguente codice:

Utilizzo del sistema; utilizzando System.Collections.Generic; utilizzando System.ComponentModel; utilizzando System.Data; utilizzando System.Diagnostics; utilizzando System.Linq; utilizzando System.ServiceProcess; utilizzando System.Text; utilizzando System.Threading.Tasks; spazio dei nomi FileWatcherService ( classe parziale pubblica Service1: ServiceBase ( public Service1() ( InizializzaComponent(); ) override protetto void OnStart(string args) ( ) override protetto void OnStop() ( ) ) )

La classe del servizio deve ereditare dalla classe base ServiceBase. Questa classe definisce una serie di metodi, i più importanti dei quali sono il metodo OnStart(), che avvia le azioni eseguite dal servizio, e il metodo OnStop(), che arresta il servizio.

Dopo che SCM chiama il metodo Main e registra il servizio, viene chiamato direttamente eseguendo il metodo OnStart.

Quando nella console dei servizi o tramite riga di comando inviamo un comando per interrompere il servizio, quindi SCM chiama il metodo OnStop per interromperlo.

Oltre a questi due metodi nella classe di servizio, puoi sovrascrivere molti altri metodi della classe base ServiceBase:

    OnPause: chiamato quando il servizio è in pausa

    OnContinue: chiamato quando un servizio riprende dopo essere stato sospeso

    OnShutdown: chiamato quando Windows si spegne

    OnPowerEvent: chiamato quando cambia la modalità di alimentazione

    OnCustomCommand: chiamato quando un servizio riceve un comando personalizzato da Service Control Manager (SCM)

Nel costruttore della classe Service1 viene chiamato il metodo InitializeComponent(), che è definito nel file di progettazione Service1.Designer.cs:

Spazio dei nomi FileWatcherService ( classe parziale Service1 ( private System.ComponentModel.IContainer componenti = null; override protetto void Dispose(bool disponendo) ( if (disponendo && (componenti != null)) ( componenti.Dispose(); ) base.Dispose(disponendo ); ) private void InitializeComponent() ( componenti = new System.ComponentModel.Container(); this.ServiceName = "Service1"; ) ) )

L'unica cosa che deve essere annotata è l'impostazione del nome del servizio (proprietà ServiceName):

This.ServiceName = "Servizio1";

Questo è il nome che verrà visualizzato nella console dei servizi dopo l'installazione di questo servizio. Possiamo cambiarlo o lasciarlo così com'è.

Ora modifichiamo il codice del servizio come segue:

Utilizzo del sistema; utilizzando System.ServiceProcess; utilizzando System.IO; utilizzando System.Threading; namespace FileWatcherService ( public partial class Service1: ServiceBase ( Logger logger; public Service1() ( InizializzaComponent(); this.CanStop = true; this.CanPauseAndContinue = true; this.AutoLog = true; ) override protetto void OnStart(string args) ( logger = new Logger(); Thread loggerThread = new Thread(new ThreadStart(logger.Start)); loggerThread.Start(); ) override protetto void OnStop() ( logger.Stop(); Thread.Sleep(1000); ) ) class Logger ( osservatore FileSystemWatcher; oggetto obj = nuovo oggetto(); bool abilitato = true; public Logger() ( osservatore = new FileSystemWatcher("D:\\Temp"); watcher.Deleted += Watcher_Deleted; watcher.Created + = Watcher_Created; watcher.Changed += Watcher_Changed; watcher.Renamed += Watcher_Renamed; ) public void Start() ( watcher.EnableRaisingEvents = true; while(abilitato) ( Thread.Sleep(1000); ) ) public void Stop() ( watcher.EnableRaisingEvents = false; abilitato = false; ) // rinominare i file private void Watcher_Renamed(mittente oggetto, RenamedEventArgs e) ( string fileEvent = "rinominato in " + e.FullPath; stringa filePath = e.OldFullPath; RecordEntry(fileEvent, filePath); ) // modifica dei file private void Watcher_Changed(oggetto mittente, FileSystemEventArgs e) ( string fileEvent = "changed"; string filePath = e.FullPath; RecordEntry(fileEvent, filePath); ) // creazione dei file private void Watcher_Created(oggetto mittente, FileSystemEventArgs e) ( string fileEvent = "creato"; string filePath = e.FullPath; RecordEntry(fileEvent, filePath); ) // eliminazione dei file private void Watcher_Deleted(oggetto mittente, FileSystemEventArgs e) ( string fileEvent = "deleted"; string filePath = e.FullPath; RecordEntry(fileEvent, filePath); ) private void RecordEntry(string fileEvent, string filePath) ( lock (obj) ( using (StreamWriter writer = new StreamWriter("D:\\templog.txt", true)) ( writer.WriteLine(String.Format("(0) file (1) era (2)", DateTime.Now.ToString("gg/MM/aaaa hh:mm:ss"), filePath, fileEvent)); writer. Sciacquone(); ) ) ) ) )

La classe chiave che incapsula tutte le funzionalità è la classe Logger. Utilizzando l'oggetto FileSystemWatcher, monitorerà le modifiche nella cartella D://Temp. Il metodo Start() specifica che controlleremo le modifiche tramite l'oggetto FileSystemWatcher. E tutto il lavoro continuerà finché la variabile booleana abilitata sarà vera. E il metodo Stop() consentirà alla classe di terminare.

Gli eventi FileSystemWatcher consentono di monitorare tutte le modifiche apportate a una cartella controllata. Ciò registrerà le modifiche al file templog.txt. Per evitare una corsa alle risorse per il file templog.txt, in cui vengono registrate le modifiche, la procedura di registrazione è bloccata dallo stub lock(obj).

Di conseguenza, dopo aver creato, modificato, rinominato ed eliminato, il file di registro conterrà qualcosa del tipo:

30/07/2015 12:15:40 il file D:\Temp\Nuovo documento di testo.txt è stato creato 30/07/2015 12:15:46 il file D:\Temp\Nuovo documento di testo.txt è stato rinominato in D:\ Temp\ciao.txt 30/07/2015 12:15:55 il file D:\Temp\ciao.txt è stato modificato 30/07/2015 12:15:55 il file D:\Temp\ciao.txt è stato modificato il 30/07 /2015 12:16:01 il file D:\Temp\ciao.txt è stato eliminato

Nella stessa classe di servizio Service1, nel costruttore sono impostate una serie di opzioni:

This.CanStop = vero; // il servizio può essere interrotto this.CanPauseAndContinue = true; // il servizio può essere messo in pausa e poi continuato. AutoLog = true; // il servizio può scrivere nel log

Nel metodo OnStart(), viene chiamato un nuovo thread per avviare l'oggetto Logger:

Override protetto void OnStart(string args) ( logger = new Logger(); Thread loggerThread = new Thread(new ThreadStart(logger.Start)); loggerThread.Start(); )

Il nuovo thread è necessario perché il thread corrente elabora solo i comandi SCM e deve restituire il metodo OnStart il più rapidamente possibile.

Quando viene ricevuto un comando dall'SCM per interrompere il servizio, viene attivato il metodo OnStop, che chiama il metodo logger.Stop(). Il ritardo aggiuntivo consentirà l'interruzione del thread del logger:

Override protetto void OnStop() ( logger.Stop(); Thread.Sleep(1000); )

Tuttavia, la classe di servizio in sé non è sufficiente. Dobbiamo anche creare un programma di installazione del servizio.

Oppure il desktop degli utenti (sia locali che remoti), tuttavia, per alcuni servizi è possibile un'eccezione: l'interazione con la console (sessione numero 0, in cui l'utente è registrato localmente o all'avvio del servizio mstsc con l'opzione /console).

Esistono diverse modalità per i servizi:

  • vietato il lancio;
  • avviamento manuale (a richiesta);
  • avvio automatico all'avvio del computer;
  • avvio automatico (ritardato) (introdotto in Windows Vista e Windows Server 2008);
  • servizio/autista obbligatorio (avvio automatico e impossibilità (per l'utente) di interrompere il servizio).

Modalità sfondo

Avvia, arresta e modifica i servizi Windows

I servizi e i loro attributi possono essere modificati nella MMC:

Versioni diverse di sistemi operativi possono avere alcuni servizi e non altri. Anche alcune applicazioni e programmi installati separatamente possono creare i propri servizi.

Elenco dei servizi del sistema operativo Microsoft Windows

Nome da visualizzare Nome di Servizio Funzioni Descrizione
Cliente DHCP Dhcp Registra e aggiorna gli indirizzi IP e i record DNS per questo computer. Se questo servizio viene interrotto, il computer non sarà in grado di ottenere indirizzi IP dinamici ed eseguire aggiornamenti DNS.
Cliente DNS Dnscache Il servizio client DNS (dnscache) memorizza nella cache i nomi DNS (Domain Name System) e registra il nome completo di un determinato computer. Se il servizio viene interrotto, la risoluzione dei nomi DNS continuerà. Tuttavia, i risultati delle code dei nomi DNS non verranno memorizzati nella cache e il nome del computer non verrà registrato.
KtmRm per coordinatore delle transazioni distribuite KtmRm Coordina le transazioni tra MSDTC e Kernel Transaction Manager (KTM).
ReadyBoost EMDMgmt ReadyBoost Supporto per migliorare le prestazioni del sistema utilizzando la tecnologia ReadyBoost.
Superfetch SysMain Superfetch Mantiene e migliora le prestazioni del sistema.
Audio di Windows Audiosrv Gestione degli strumenti audio per i programmi Windows. Se questo servizio viene interrotto, i dispositivi audio e gli effetti non funzioneranno correttamente.
Spazio scheda di Windows idsvc Fornisce una capacità sicura di creare, gestire ed esporre identità digitali.
Aggiornamento automatico WUAUSER Include il download e l'installazione degli aggiornamenti di Windows. Se il servizio è disabilitato, il computer non sarà in grado di utilizzare Aggiornamenti automatici o il sito Web Windows Update.
Chiamata di procedura remota (RPC) RpcSs Fornisce la mappatura tra endpoint e altri servizi RPC.

Elenco dei servizi creati da applicazioni e programmi Microsoft

Esempi di servizi creati da applicazioni e programmi di terze parti

Nome da visualizzare Nome di Servizio Funzioni Descrizione
Server HTTP ESET EhttpSrv protezione antivirus Componente ESET HTTP Server