Domanda

Esiste un modo più semplice per scorrere il codice che avviare il servizio tramite Gestione controllo servizi di Windows e quindi collegare il debugger al thread? È un po 'ingombrante e mi chiedo se esiste un approccio più diretto.

È stato utile?

Soluzione

Se voglio eseguire il debug rapido del servizio, inserisco semplicemente un Debugger.Break () . Quando viene raggiunta quella linea, mi riporterà su VS. Non dimenticare di rimuovere quella riga quando hai finito.

AGGIORNAMENTO: In alternativa ai pragmi #if DEBUG , puoi anche utilizzare l'attributo Condizionale (" DEBUG_SERVICE ") .

[Conditional("DEBUG_SERVICE")]
private static void DebugMode()
{
    Debugger.Break();
}

Sul tuo OnStart , chiama questo metodo:

public override void OnStart()
{
     DebugMode();
     /* ... do the rest */
}

Lì, il codice sarà abilitato solo durante le build di debug. Mentre ci sei, potrebbe essere utile creare una Configurazione build separata per il debug del servizio.

Altri suggerimenti

Penso anche di avere una versione " separata " per l'esecuzione normale e come servizio è la strada da percorrere, ma è davvero necessario dedicare un interruttore di riga di comando separato a tale scopo?

Non potresti semplicemente:

public static int Main(string[] args)
{
  if (!Environment.UserInteractive)
  {
    // Startup as service.
  }
  else
  {
    // Startup as application
  }
}

Ciò avrebbe il "vantaggio", che puoi semplicemente avviare l'app tramite doppio clic (OK, se ne hai davvero bisogno) e che puoi semplicemente premere F5 in Visual Studio (senza il è necessario modificare le impostazioni del progetto per includere l'opzione / console ).

Tecnicamente, Environment.UserInteractive verifica se il flag WSF_VISIBLE è impostato per la stazione corrente della finestra, ma c'è qualche altro motivo per cui restituire false , oltre ad essere gestito come un servizio (non interattivo)?

Quando ho impostato un nuovo progetto di servizio qualche settimana fa, ho trovato questo post. Sebbene ci siano molti ottimi suggerimenti, non ho ancora trovato la soluzione che volevo: la possibilità di chiamare i metodi OnStart e OnStop delle classi di servizio senza alcuna modifica al servizio classi.

La soluzione che ho trovato utilizza Environment.Interactive la modalità di esecuzione select, come suggerito da altre risposte a questo post.

static void Main()
{
    ServiceBase[] servicesToRun;
    servicesToRun = new ServiceBase[] 
    {
        new MyService()
    };
    if (Environment.UserInteractive)
    {
        RunInteractive(servicesToRun);
    }
    else
    {
        ServiceBase.Run(servicesToRun);
    }
}

L'helper RunInteractive utilizza la reflection per chiamare i metodi protetti OnStart e OnStop :

static void RunInteractive(ServiceBase[] servicesToRun)
{
    Console.WriteLine("Services running in interactive mode.");
    Console.WriteLine();

    MethodInfo onStartMethod = typeof(ServiceBase).GetMethod("OnStart", 
        BindingFlags.Instance | BindingFlags.NonPublic);
    foreach (ServiceBase service in servicesToRun)
    {
        Console.Write("Starting {0}...", service.ServiceName);
        onStartMethod.Invoke(service, new object[] { new string[] { } });
        Console.Write("Started");
    }

    Console.WriteLine();
    Console.WriteLine();
    Console.WriteLine(
        "Press any key to stop the services and end the process...");
    Console.ReadKey();
    Console.WriteLine();

    MethodInfo onStopMethod = typeof(ServiceBase).GetMethod("OnStop", 
        BindingFlags.Instance | BindingFlags.NonPublic);
    foreach (ServiceBase service in servicesToRun)
    {
        Console.Write("Stopping {0}...", service.ServiceName);
        onStopMethod.Invoke(service, null);
        Console.WriteLine("Stopped");
    }

    Console.WriteLine("All services stopped.");
    // Keep the console alive for a second to allow the user to see the message.
    Thread.Sleep(1000);
}

Questo è tutto il codice richiesto, ma ho anche scritto procedura dettagliata con spiegazioni.

A volte è importante analizzare cosa sta succedendo durante l'avvio del servizio. Il collegamento al processo non aiuta qui, perché non si è abbastanza veloci da collegare il debugger mentre il servizio è avvio.

La risposta breve è che sto usando le seguenti 4 righe di codice per fare questo:

#if DEBUG
    base.RequestAdditionalTime(600000); // 600*1000ms = 10 minutes timeout
    Debugger.Launch(); // launch and attach debugger
#endif

Questi sono inseriti nel metodo OnStart del servizio come segue:

protected override void OnStart(string[] args)
{
    #if DEBUG
       base.RequestAdditionalTime(600000); // 10 minutes timeout for startup
       Debugger.Launch(); // launch and attach debugger
    #endif
    MyInitOnstart(); // my individual initialization code for the service
    // allow the base class to perform any work it needs to do
    base.OnStart(args);
}

Per coloro che non l'hanno mai fatto prima, ho incluso suggerimenti dettagliati di seguito , perché puoi rimanere facilmente bloccato. I seguenti suggerimenti si riferiscono a Windows 7x64 e Visual Studio 2010 Team Edition , ma dovrebbero essere validi anche per altri ambienti.


Importante: distribuisci il servizio in " manuale " mode (utilizzando l'utilità InstallUtil dal prompt dei comandi VS o eseguendo un progetto di installazione del servizio che è stato preparato). Apri Visual Studio prima di avviare il servizio e carica la soluzione contenente il codice sorgente del servizio - imposta punti di interruzione aggiuntivi come richiesto in Visual Studio - quindi avvia il servizio tramite il Pannello di controllo del servizio.

A causa del codice Debugger.Launch , ciò causerà una finestra di dialogo " Si è verificata un'eccezione non gestita di Microsoft .NET Framework in Servicename.exe . " apparire. Fai clic su  Elevate Sì, debug Servicename.exe come mostrato nello screenshot:
FrameworkException

Successivamente, in particolare UAC di Windows 7, potrebbe essere necessario inserire le credenziali di amministratore. Inseriscili e procedi con :

UACPrompt

Successivamente, viene visualizzata la ben nota finestra Debugger just-in-time di Visual Studio . Ti chiede se desideri eseguire il debug utilizzando il debugger eliminato. Prima di fare clic su , selezionare che non si desidera aprire una nuova istanza (seconda opzione) - una nuova istanza non sarebbe utile qui, perché il codice sorgente non verrebbe visualizzato. Quindi selezioni invece l'istanza di Visual Studio che hai aperto in precedenza: VSDebuggerPrompt

Dopo aver fatto clic su , dopo un po 'Visual Studio mostrerà la freccia gialla proprio nella riga in cui l'istruzione Debugger.Launch è e sei in grado di eseguire il debug del tuo codice (metodo MyInitOnStart , che contiene la tua inizializzazione). VSDebuggerBreakpoint

La pressione di F5 continua immediatamente l'esecuzione, fino al raggiungimento del punto di interruzione successivo che hai preparato.

Suggerimento: per mantenere attivo il servizio, seleziona Debug - > Stacca tutto . Ciò consente di eseguire un client che comunica con il servizio dopo che è stato avviato correttamente e al termine del debug del codice di avvio. Se si preme Sposta+F5 (interrompe il debug), il servizio verrà interrotto. Invece di farlo, dovresti usare il Pannello di controllo del servizio per fermarlo.

Nota che

  • Se crei una versione , il codice di debug viene automaticamente rimosso e il servizio funziona normalmente.

  • Sto usando Debugger.Launch() , che avvia e allega un debugger . Ho testato anche Debugger.Break() , che non ha funzionato , poiché non è ancora collegato alcun debugger all'avvio del servizio (causando il " Errore 1067: il processo è terminato in modo imprevisto. " ).

  • RequestAdditionalTime imposta un timeout più lungo per l'avvio del servizio (non è non in ritardo il codice stesso, ma continuerà immediatamente con l'istruzione Debugger.Launch ). In caso contrario, il timeout predefinito per l'avvio del servizio è troppo breve e l'avvio del servizio non riesce se non si chiama base.Onstart (args) abbastanza rapidamente dal debugger. In pratica, un timeout di 10 minuti evita la visualizzazione del messaggio " il servizio non ha risposto ... " immediatamente dopo l'avvio del debugger.

  • Una volta che ti ci abitui, questo metodo è molto semplice perché richiede solo aggiungere 4 righe a un codice di servizio esistente, permettendoti di ottenere rapidamente controllo e debug.

Quello che faccio di solito è incapsulare la logica del servizio in una classe separata e avviarla da una classe "runner". Questa classe di corridori può essere il servizio effettivo o solo un'applicazione console. Quindi la tua soluzione ha (almeno) 3 progetti:

/ConsoleRunner
   /....
/ServiceRunner
   /....
/ApplicationLogic
   /....

Questo video YouTube di Fabio Scopel spiega come eseguire correttamente il debug di un servizio Windows ... il vero metodo per farlo inizia alle 4:45 nel video ...

Ecco il codice spiegato nel video ... nel tuo file Program.cs, aggiungi gli elementi per la sezione Debug ...

namespace YourNamespace
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        static void Main()
        {
#if DEBUG
            Service1 myService = new Service1();
            myService.OnDebug();
            System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
#else
            ServiceBase[] ServicesToRun;
            ServicesToRun = new ServiceBase[]
            {
                new Service1()
            };
            ServiceBase.Run(ServicesToRun);
#endif

        }
    }
}

Nel tuo file Service1.cs, aggiungi il metodo OnDebug () ...

    public Service1()
    {
        InitializeComponent();
    }

    public void OnDebug()
    {
        OnStart(null);
    }

    protected override void OnStart(string[] args)
    {
        // your code to do something
    }

    protected override void OnStop()
    {
    }
  

Come funziona

Fondamentalmente devi creare un vuoto pubblico OnDebug () che chiama OnStart (string [] args) poiché è protetto e non accessibile all'esterno. Il programma void Main () viene aggiunto con il preprocessore #if con #DEBUG .

Visual Studio definisce DEBUG se il progetto è compilato in modalità Debug. Ciò consentirà l'esecuzione della sezione di debug (sotto) quando la condizione è vera

Service1 myService = new Service1();
myService.OnDebug();
System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);

E funzionerà proprio come un'applicazione console, una volta che le cose vanno bene puoi cambiare la modalità Rilascio e la normale sezione else attiverà la logica

Aggiorna

Questo approccio è di gran lunga il più semplice:

http://www.codeproject.com/KB/dotnet/DebugWinServices.aspx

Lascio la mia risposta originale qui sotto per i posteri.


I miei servizi tendono ad avere una classe che incapsula un Timer poiché voglio che il servizio controlli a intervalli regolari se c'è qualche lavoro da fare.

Rinnoviamo la classe e chiamiamo StartEventLoop () durante l'avvio del servizio. (Questa classe potrebbe essere facilmente utilizzata anche da un'app console.)

Il piacevole effetto collaterale di questo design è che gli argomenti con cui si imposta il Timer possono essere utilizzati per avere un ritardo prima che il servizio inizi effettivamente a funzionare, in modo da avere il tempo di collegare manualmente un debugger.

  

P.S. Come collegare manualmente il debugger a un processo in esecuzione ...?

using System;
using System.Threading;
using System.Configuration;    

public class ServiceEventHandler
{
    Timer _timer;
    public ServiceEventHandler()
    {
        // get configuration etc.
        _timer = new Timer(
            new TimerCallback(EventTimerCallback)
            , null
            , Timeout.Infinite
            , Timeout.Infinite);
    }

    private void EventTimerCallback(object state)
    {
        // do something
    }

    public void StartEventLoop()
    {
        // wait a minute, then run every 30 minutes
        _timer.Change(TimeSpan.Parse("00:01:00"), TimeSpan.Parse("00:30:00");
    }
}

Inoltre, ero solito fare quanto segue (già menzionato nelle risposte precedenti ma con i flag del compilatore condizionale [#if] per evitare che sparasse in una build di Release).

Ho smesso di farlo in questo modo perché a volte ci saremmo dimenticati di compilare in Release e di avere una pausa del debugger in un'app in esecuzione su una demo client (imbarazzante!).

#if DEBUG
if (!System.Diagnostics.Debugger.IsAttached)
{
    System.Diagnostics.Debugger.Break();
}
#endif

static void Main()
{
#if DEBUG
                // Run as interactive exe in debug mode to allow easy
                // debugging.

                var service = new MyService();
                service.OnStart(null);

                // Sleep the main thread indefinitely while the service code
                // runs in .OnStart

                Thread.Sleep(Timeout.Infinite);
#else
                // Run normally as service in release mode.

                ServiceBase[] ServicesToRun;
                ServicesToRun = new ServiceBase[]{ new MyService() };
                ServiceBase.Run(ServicesToRun);
#endif
}

È inoltre possibile avviare il servizio tramite il prompt dei comandi (sc.exe).

Personalmente, eseguivo il codice come programma autonomo in fase di debug e, quando la maggior parte dei bug viene risolta, passa all'esecuzione come servizio.

Quello che ero solito fare era avere un'opzione da riga di comando che avviasse il programma come servizio o come normale applicazione. Quindi, nel mio IDE imposterei l'interruttore in modo da poter scorrere il mio codice.

Con alcune lingue puoi effettivamente rilevare se è in esecuzione in un IDE ed eseguire questa opzione automaticamente.

Che lingua stai usando?

Utilizza la TopShelf .

Crea un'applicazione console quindi configura la configurazione nel tuo Principale

class Program
    {
        static void Main(string[] args)
        {
            HostFactory.Run(x =>
            {

                // setup service start and stop.
                x.Service<Controller>(s =>
                {
                    s.ConstructUsing(name => new Controller());
                    s.WhenStarted(controller => controller.Start());
                    s.WhenStopped(controller => controller.Stop());
                });

                // setup recovery here
                x.EnableServiceRecovery(rc =>
                {
                    rc.RestartService(delayInMinutes: 0);
                    rc.SetResetPeriod(days: 0);
                });

                x.RunAsLocalSystem();
            });
        }
}

public class Controller
    {
        public void Start()
        {

        }

        public void Stop()
        {

        }
    }

Per eseguire il debug del tuo servizio, premi F5 in Visual Studio.

Per installare il servizio, digitare cmd " console.exe install "

È quindi possibile avviare e interrompere il servizio nel gestore servizi di Windows.

Penso che dipenda dal sistema operativo in uso, Vista è molto più difficile da collegare ai Servizi, a causa della separazione tra le sessioni.

Le due opzioni che ho usato in passato sono:

  • Usa GFlags (negli Strumenti di debug per Windows) per impostare un debugger permanente per un processo. Ciò esiste nelle "Opzioni di esecuzione dei file di immagine" chiave di registro ed è incredibilmente utile. Penso che dovrai modificare le impostazioni del servizio per abilitare " Interagisci con il desktop " ;. Lo uso per tutti i tipi di debug, non solo per i servizi.
  • L'altra opzione è quella di separare un po 'il codice, in modo che la parte di servizio sia intercambiabile con un normale avvio dell'app. In questo modo, puoi utilizzare un semplice flag della riga di comando e lanciarlo come processo (anziché come servizio), il che semplifica notevolmente il debug.

Spero che questo aiuti.

Quando scrivo un servizio inserisco tutta la logica di servizio in un progetto dll e creo due "host" quella chiamata in questa dll, una è un servizio Windows e l'altra è un'applicazione da riga di comando.

Uso l'applicazione da riga di comando per il debug e allego il debugger al servizio reale solo per i bug che non riesco a riprodurre nell'applicazione da riga di comando.

Se usi questo approccio, ricorda solo che devi testare tutto il codice durante l'esecuzione in un servizio reale, mentre lo strumento da riga di comando è un valido aiuto per il debug, è un ambiente diverso e non si comporta esattamente come un vero servizio .

Mi piace essere in grado di eseguire il debug di ogni aspetto del mio servizio, inclusa qualsiasi inizializzazione in OnStart (), mentre lo sto ancora eseguendo con un comportamento di servizio completo nel quadro di SCM ... no " console " o " app " modalità.

Lo faccio creando un secondo servizio, nello stesso progetto, da utilizzare per il debug. Il servizio di debug, quando avviato come di consueto (ovvero nel plug-in MMC dei servizi), crea il processo host del servizio. Questo ti dà una procedura per collegare il debugger anche se non hai ancora iniziato il tuo vero servizio. Dopo aver collegato il debugger al processo, avvia il tuo vero servizio e puoi interromperlo ovunque nel ciclo di vita del servizio, incluso OnStart ().

Poiché richiede un'intrusione di codice molto minima, il servizio di debug può essere facilmente incluso nel progetto di installazione del servizio e può essere facilmente rimosso dalla versione di produzione commentando una singola riga di codice ed eliminando un singolo programma di installazione del progetto.

Dettagli:

1) Supponendo che tu stia implementando MyService , crea anche MyServiceDebug . Aggiungi entrambi all'array ServiceBase in Program.cs in questo modo:

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    static void Main()
    {
        ServiceBase[] ServicesToRun;
        ServicesToRun = new ServiceBase[] 
        { 
            new MyService(),
            new MyServiceDebug()
        };
        ServiceBase.Run(ServicesToRun);
    }

2) Aggiungi il servizio reale E il servizio di debug al programma di installazione del progetto per il progetto di servizio:

inserisci qui la descrizione dell'immagine

Entrambi i servizi (reali e di debug) vengono inclusi quando si aggiunge l'output del progetto di servizio al progetto di installazione per il servizio. Dopo l'installazione, entrambi i servizi verranno visualizzati nel plug-in MMC service.msc.

3) Avvia il servizio di debug in MMC.

4) In Visual Studio, collega il debugger al processo avviato dal servizio di debug.

5) Avvia il servizio reale e goditi il ??debug.

Durante lo sviluppo e il debug di un servizio Windows in genere lo eseguo come un'applicazione console aggiungendo un parametro di avvio / console e verificandolo. Semplifica la vita.

static void Main(string[] args) {
    if (Console.In != StreamReader.Null) {
        if (args.Length > 0 && args[0] == "/console") {
            // Start your service work.
        }
    }
}

Che ne dici di Debugger.Break () nella prima riga?

Per eseguire il debug dei servizi Windows, combino GFlags e un file .reg creato da regedit.

  1. Esegui GFlags, specificando il nome exe e vsjitdebugger
  2. Esegui regedit e vai alla posizione in cui GFlags imposta le sue opzioni
  3. Scegli " Esporta chiave " dal menu file
  4. Salva quel file da qualche parte con l'estensione .reg
  5. Ogni volta che si desidera eseguire il debug del servizio: fare doppio clic sul file .reg
  6. Se si desidera interrompere il debug, fare doppio clic sul secondo file .reg

Oppure salva i seguenti frammenti e sostituisci servicename.exe con il nome eseguibile desiderato.


debugon.reg:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\servicename.exe]
"GlobalFlag"="0x00000000"
"Debugger"="vsjitdebugger.exe"

debugoff.reg:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\servicename.exe]
"GlobalFlag"="0x00000000"

Per la programmazione di piccole cose di routine ho fatto un trucco molto semplice per eseguire facilmente il debug del mio servizio:

All'avvio del servizio, cerco un parametro della riga di comando " / debug " ;. Se il servizio viene chiamato con questo parametro, non eseguo il consueto avvio del servizio, ma invece avvio tutti i listener e visualizzo solo una finestra di messaggio "Debug in corso, premi ok per terminare".

Quindi, se il mio servizio viene avviato come di consueto, verrà avviato come servizio, se viene avviato con il parametro della riga di comando / debug funzionerà come un normale programma.

In VS aggiungerò / debug come parametro di debug e avvierò direttamente il programma di servizio.

In questo modo posso facilmente eseguire il debug per la maggior parte dei piccoli problemi. Certo, alcune cose dovranno ancora essere sottoposte a debug come servizio, ma per il 99% è abbastanza buono.

#if DEBUG
    System.Diagnostics.Debugger.Break();
#endif

Uso una variazione sulla risposta di JOP. Utilizzando i parametri della riga di comando è possibile impostare la modalità di debug nell'IDE con le proprietà del progetto o tramite il gestore servizi di Windows.

protected override void OnStart(string[] args)
{
  if (args.Contains<string>("DEBUG_SERVICE"))
  {
    Debugger.Break();
  }
  ...
}

Per la risoluzione dei problemi sul programma di servizio Windows esistente, usa "Debugger.Break ()" come altri ragazzi hanno suggerito.

Per il nuovo programma di servizio Windows, suggerirei di utilizzare il metodo di James Michael Hare http://geekswithblogs.net/BlackRabbitCoder/archive/2011/03/01/c-toolbox-debug-able-self-installable-windows- service-template-redux.aspx

Porta semplicemente il tuo debugger lunch ovunque e collega Visualstudio all'avvio

#if DEBUG
    Debugger.Launch();
#endif

Inoltre devi avviare VS come Administatrator e devi consentire che un processo possa essere automaticamente sottoposto a debug da un utente diverso (come spiegato qui ):

reg add "HKCR\AppID{E62A7A31-6025-408E-87F6-81AEB0DC9347}" /v AppIDFlags /t REG_DWORD /d 8 /f

Usa il progetto C # del modello di servizio di Windows per creare una nuova app di servizio https://github.com/ HarpyWar / windows-service-template

Sono state rilevate automaticamente le modalità console / servizio, l'installazione automatica / deinstaller del servizio e sono incluse diverse funzionalità più utilizzate.

Ecco il semplice metodo che ho usato per testare il servizio, senza alcun ulteriore "Debug" metodi e con prove unitarie VS integrate.

[TestMethod]
public void TestMyService()
{
    MyService fs = new MyService();

    var OnStart = fs.GetType().BaseType.GetMethod("OnStart", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);

    OnStart.Invoke(fs, new object[] { null });
}

// As an extension method
public static void Start(this ServiceBase service, List<string> parameters)
{
     string[] par = parameters == null ? null : parameters.ToArray();

     var OnStart = service.GetType().GetMethod("OnStart", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);

     OnStart.Invoke(service, new object[] { par });
}
static class Program
{
    static void Main()
    {
        #if DEBUG

        // TODO: Add code to start application here

        //    //If the mode is in debugging
        //    //create a new service instance
        Service1 myService = new Service1();

        //    //call the start method - this will start the Timer.
        myService.Start();

        //    //Set the Thread to sleep
        Thread.Sleep(300000);

        //    //Call the Stop method-this will stop the Timer.
        myService.Stop();

         #else
        ServiceBase[] ServicesToRun;
        ServicesToRun = new ServiceBase[] 
        { 
            new Service1() 
        };

        ServiceBase.Run(ServicesToRun);
         #endif
    }
}

Hai due opzioni per eseguire il debug.

  1. crea un file di registro: personalmente preferisco un file di registro separato come il file di testo piuttosto che utilizzare il registro dell'applicazione o il registro degli eventi, ma questo ti costerà molto per conto del tempo, perché è ancora difficile capire dove si trova l'errore esatto la posizione è
  2. Converti l'applicazione in console: questo ti consentirà tutti gli strumenti di debug che possiamo usare in VS.

Si prega di fare riferimento al QUESTO post sul blog che ho creato per l'argomento.

Basta incollare

Debugger.Break();

qualsiasi punto nel tuo codice.

Ad esempio,

internal static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        private static void Main()
        {
            Debugger.Break();
            ServiceBase[] ServicesToRun;
            ServicesToRun = new ServiceBase[]
            {
                new Service1()
            };
            ServiceBase.Run(ServicesToRun);
        }
    }

Colpirà Debugger.Break (); quando avvierai il tuo programma.

L'opzione migliore è utilizzare lo spazio dei nomi " System.Diagnostics ".

Racchiudi il tuo codice nel blocco if else per la modalità debug e la modalità di rilascio come mostrato di seguito per passare dalla modalità debug a quella di rilascio in Visual Studio,

#if DEBUG  // for debug mode
       **Debugger.Launch();**  //debugger will hit here
       foreach (var job in JobFactory.GetJobs())
            {
                //do something 
            }

#else    // for release mode
      **Debugger.Launch();**  //debugger will hit here
     // write code here to do something in Release mode.

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