Domanda

Ho un'applicazione c # che funziona come un servizio di Windows che controlla le connessioni socket e altre cose. Inoltre, esiste un'altra applicazione Windows Form per controllare e configurare questo servizio (systray con start, stop, show form con parametri di configurazione).

Sto usando .net remoting per fare l'IPC e questo andava bene, ma ora voglio mostrare un po 'di traffico reale e altri report e remoting non soddisfano i miei requisiti di prestazione. Quindi voglio combinare entrambe le applicazioni in una.

Ecco il problema:

Quando ho avviato il modulo dal servizio Windows, non è successo nulla. Cercando su Google ho scoperto che devo fare clic con il pulsante destro del mouse sul servizio, andare su Accedi e controllare " Consenti al servizio di interagire con il desktop " opzione. Dal momento che non voglio chiedere ai miei utenti di farlo, ho ottenuto di nuovo un po 'di codice su Google per impostare questa opzione nel regedit dell'utente durante l'installazione. Il problema è che anche impostando questa opzione, non funziona. Devo aprire le opzioni di accesso del servizio (è selezionata), deselezionare e ricontrollare.

Quindi, come risolverlo? Come è il modo migliore per avere un servizio Windows con un controllo systray nello stesso processo, disponibile per qualsiasi utente che accede?

AGGIORNAMENTO: Grazie per i commenti finora, ragazzi. Sono d'accordo che è meglio usare IPC e so che è male mescolare servizi di Windows e interfacce utente. Anche se, voglio sapere come farlo.

È stato utile?

Soluzione

Due processi separati che comunicano usando la tua tecnologia preferita. I servizi con l'interfaccia utente sono una cattiva idea . Non andare su questa strada - te ne pentirai.

Ho avuto ottimi risultati con la comunicazione di servizio attraverso una semplice connessione socket - documenta bene il tuo protocollo di servizio, mantienilo il più semplice possibile e sarà più facile di quanto pensi.

Altri suggerimenti

In pratica non dovresti associare il tuo servizio all'interfaccia utente di gestione.

Sono d'accordo con Greg. Forse potresti esaminare un diverso meccanismo IPC. Forse usa socket e il tuo protocollo. Oppure, se l'app di controllo del servizio può controllare solo il servizio sul computer locale, è possibile utilizzare le named pipe (anche più velocemente).

Ecco un modo per mescolare servizi e moduli

http://www.codeproject.com/KB/system/SystemTrayIconInSvc.aspx

Ho capito come farlo da questo articolo (fai clic sul link " Modifica " nella tabella Metodi).

string wmiPath = "Win32_Service.Name='" + SERVICE_NAME + "'";
using (ManagementObject service = new ManagementObject(wmiPath))
{
    object[] parameters = new object[11];
    parameters[5] = true;  // Enable desktop interaction
    service.InvokeMethod("Change", parameters);
}

Ho la soluzione in pochi passaggi, questo è il piano

  1. non creeremo un progetto di servizio con un modulo di Windows, ma creeremo una soluzione di Visual Studio che contiene un progetto di servizio di Windows, un progetto di Windows Form e un progetto di installazione.

  2. L'idea è quella di avere un database o un file o qualsiasi cosa tu abbia familiarità con l'archiviazione dei dati in cui archivieresti i parametri che il tuo servizio Windows utilizzerà sempre per essere eseguito. Pertanto, il servizio Windows e l'applicazione Windows Form dovrebbero essere in grado di modificare e recuperare i dati da esso.

  3. Nella forma principale dell'applicazione Windows trascina e rilascia un NotifyIcon sul modulo, nella scheda delle proprietà, sfoglia e seleziona un'immagine .ico (puoi srearne una in Visual Studio ma questo è un altro argomento che puoi vai su google o contattami) Che verrà visualizzato nella barra delle applicazioni quando esegui l'applicazione e il modulo principale è attivo o visualizzato, provalo, esegui l'applicazione.

  4. Aggiungili entrambi come output nel progetto di installazione della soluzione. Per aggiungere un progetto a un progetto di installazione, devono trovarsi nella stessa soluzione. Fai clic con il pulsante destro del mouse sul progetto di installazione in Esplora soluzioni, evidenzia aggiungi e quindi seleziona l'output del progetto, aggiungi il servizio Windows e gli output del modulo di Windows e li vedrai in Esplora soluzioni nel progetto di installazione.

  5. l'aggiunta di un servizio Windows va oltre, ma questo è anche un altro argomento su Google

  6. La creazione di un collegamento per l'applicazione Windows e l'aggiunta alla cartella di avvio è anche un altro argomento di google o contattami.

    NOTA Programmare il modulo in modo tale che il pulsante Chiudi non venga visualizzato e il modulo diventi Me.visible = false e facendo doppio clic sull'icona nella barra delle applicazioni è l'unico modo per impostare me.visible = true.that ogni volta che il computer si avvia, anche l'applicazione del modulo di Windows viene avviata e visibile viene immediatamente impostato su false ma poiché ha un oggetto di notifica con un'immagine icona, verrà visualizzato nella barra delle applicazioni e facendo doppio clic su di esso rende visibile il modulo per modificare il impostazioni che stai memorizzando per il servizio, il servizio si avvia anche automaticamente poiché lo avresti impostato nella configurazione del servizio nel progetto di installazione. la mia mail è iamjavademon@gmail.com per una migliore illustrazione usando schermate e spiegando in pieno

È molto semplice: è necessario creare un thread per eseguire eventi dell'applicazione. In questo modo (codice sorgente per C ++ con CLR, ma puoi farlo in C #):

ref class RunWindow{
public:
    static void MakeWindow(Object^ data)
    {
        Application::EnableVisualStyles();
        Application::SetCompatibleTextRenderingDefault(false); 

        Application::Run(gcnew TMainForm());
    };
};

E crea thread in main

int main(array<System::String ^> ^args)
{
    bool bService = RunAsService(L"SimpleServiceWithIconInTrayAndWindow");

    if (bService)
    {

        System::Threading::Thread ^thread = gcnew System::Threading::Thread(gcnew ParameterizedThreadStart(RunWindow::MakeWindow));
        thread->Start();

        ServiceBase::Run(gcnew simpleWinService());
        Application::Exit();
    }
    else
    {
        Application::EnableVisualStyles();
        Application::SetCompatibleTextRenderingDefault(false); 

        // Create the main window and run it
        Application::Run(gcnew TMainForm());
    }

    return 0;
}

I principali problemi con i servizi interattivi sono:

  • Sicurezza: un altro processo potrebbe inviargli messaggi attraverso il suo pump dei messaggi, ottenendo così l'accesso a un processo SYSTEM / LOCAL.

  • Incompletità: un servizio interattivo non vede mai i messaggi della shell, quindi non può interagire con le icone dell'area di notifica.

Usiamo regolarmente connessioni TCP e UDP per trasferire informazioni dai servizi ad altri ex e, in alcuni casi, MSMQ.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top