2009-05-20 2 views
32

Existe-t-il un moyen d'arrêter automatiquement le serveur de développement ASP.NET (Cassini) chaque fois que je compile/reconstruit dans VS2008 (et que, de toute évidence, il redémarre au besoin) ? Peut-être qu'il y a un paramètre de configuration caché quelque part? Ou au moins un moyen de le faire comme un événement de post-construction peut-être? Pour certaines raisons, le problème est que j'utilise Spring.NET pour l'injection de dépendances, etc., mais il charge ses singletons sur Application Start, ce qui signifie que si je change un code ou une configuration liée au ressort, je dois arrêter le Serveur de développement, de sorte qu'il recommence à nouveau le débogage/exécution en s'assurant que l'événement Application Start est à nouveau déclenché. En d'autres termes, même si vous changez un tas de code/config & puis recommencez le débogage, il ne commence pas à nouveau, car il est déjà en cours d'exécution, donc votre nouveau code n'est pas utilisé.Arrêter/redémarrer automatiquement le serveur de développement ASP.NET lors de la construction

+0

Je serais curieux de savoir pourquoi vous en avez besoin sans l'arrière-plan que vous avez fourni. :) Je ne peux pas aider de toute façon. –

+1

J'ai le même désir mais un problème très différent. Mon application Web possède des dépendances natives (pilotes de base de données) et notre build les copie dans le répertoire de sortie. (Les wrappers .NET autour des pilotes ont des liens statiques avec les DLL natives, ce qui nous permet de les placer dans le répertoire 'bin' Croyez-moi, c'est une bien meilleure solution que d'essayer d'installer le client Oracle.) Malheureusement, le serveur de développement verrouille les DLL natives, donc les copier échoue pendant la construction. C'est très frustrant d'avoir à arrêter manuellement le serveur web chaque fois que j'ai besoin de reconstruire. – jpmc26

Répondre

9

donc j'ai fini avec une solution à base de réponse Magnus, mais en utilisant la macro suivante relativement simple (pourquoi ils vous obligent à utiliser VB pour les macros je me sens tout sale?):

Imports System 
Imports System.Diagnostics 

Public Module KillCassini 

    Sub RestartDebug() 
     If (DTE.Debugger.DebuggedProcesses.Count > 0) Then 
      DTE.Debugger.Stop(True) 
     End If 
     KillCassini() 
     DTE.Debugger.Go(False) 
    End Sub 

    Sub KillCassini() 
     Dim name As String = "WebDev.WebServer" 
     Dim proc As Process 
     For Each proc In Process.GetProcesses 
      If (proc.ProcessName.StartsWith(name)) Then 
       proc.Kill() 
      End If 
     Next 
    End Sub 

End Module 

Fondamentalement si le débogueur est en cours d'exécution, il l'arrêtera & puis supprimera tous les processus nommés "WebDev.WebServer" qui devraient être toutes les instances de Cassini, puis redémarrera le débogueur (ce qui impliquera de nouveau implicitement Cassini). J'utilise proc.Kill() parce que ni proc.CloseMainWindow() ou proc.WaitForExit(1000) semblait travailler ...

Quoi qu'il en soit, une fois que vous avez votre macro, vous pouvez l'assigner à des raccourcis clavier, ou créer des boutons personnalisés barre d'outils pour l'exécuter.

+0

Note: modifié par un éditeur anonyme pour changer 'proc.ProcessName = name' en' proc.ProcessName.StartsWith (name) 'afin qu'il continue à fonctionner avec VS2010. – Alconja

7

Le seul moyen que je connaisse est de faire un démarrage personnalisé de Cassini sur l'événement post.build. Ce processus fait sur mesure tue toutes les instances de Cassini et en lance un nouveau. Pour que cela fonctionne, vous devez créer un petit utilitaire de ligne de commande personnalisé. Je l'ai appelé SpawnProcess ici.

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Text; 
using System.Diagnostics; 

namespace SpawnProc 
{ 
    class Program 
    { 
    public static void Main(string[] args) 
    { 
     if (args.Length > 0) 
     { 
     // Kill all current instances 
     FileInfo fi = new FileInfo(args[0]); 
     string name = Path.GetFileNameWithoutExtension(fi.FullName); 
     foreach (Process proc in Process.GetProcessesByName(name)) 
     { 
      proc.Kill(); 
     } 

     ProcessStartInfo startInfo = new ProcessStartInfo(args[0]); 
     if (args.Length > 1) 
     { 
      startInfo.Arguments += "/port:" + args[1]; 
     } 

     if (args.Length > 2) 
     { 
      startInfo.Arguments += " /path:\"" + args[2].Trim(new char[]{'"'}) + "\""; 
     } 
     if (args.Length > 3) 
     { 
      startInfo.Arguments += " /vpath:\"" + args[3].Trim(new char[]{'"'}) + "\""; 
     } 

     try 
     { 
      Process.Start(startInfo); 
     } 
     catch (Exception ex) 
     { 
      Debug.WriteLine("Error: " + ex.Message); 
      for (int i = 0; i < args.Length; i++) 
      { 
      Debug.WriteLine("args[" + i + "]: " + args[i].ToString()); 
      } 
     } 
     } 
    } 
    } 
} 

Ensuite, vous devrez demander à Visual Studio de ne pas utiliser Cassini. Accédez aux propriétés de votre application Web -> Web et sélectionnez "Utiliser un serveur Web personnalisé", entrez quelque chose comme: http://localhost:1685/ (ou quel que soit le numéro de port que vous souhaitez utiliser). Ensuite, entrez cette commande en cas de post-construction:

"$(ProjectDir)..\SpawnProc\bin\debug\SpawnProc" "C:\Program Files (x86)\Common Files\microsoft shared\DevServer\9.0\WebDev.WebServer.exe" 1685 "$(ProjectDir)"/

Assurez-vous que vos chemins est correct, par exemple, depuis que je suis en cours d'exécution d'un système d'exploitation 64 bits, mes fichiers de programme chemin est différent d'un OS 32 bits. En outre, mon SpawnProc.exe est dans un sous-projet.

+0

Merci Magnus, même si je n'ai pas utilisé votre solution exacte, j'ai utilisé l'idée de créer une macro, ce qui est un peu plus simple pour moi. – Alconja

+0

@Kiquenet, pouvez-vous s'il vous plaît élaborer sur votre édition? Pourquoi pensez-vous qu'il existe un besoin pour un nom de domaine complet pour un environnement de développement local avec Cassini qui ne fonctionne que pour localhost de toute façon? –

+0

@Sorry, vous m'avez complètement perdu. Je le change à Localhost. –

22

Workaround: Debugging Global.aspx.cs Application_Start() with ASP.Net Web Server within Visual Studio

Activation "Modifier & Continuer" sur le projet de serveur Web a fonctionné pour moi. Il n'arrête pas Cassini lorsque vous arrêtez le débogage, mais il redémarre Cassini lorsque vous démarrez le débogage.

+0

Belle (et simple) solution. Je vais continuer à utiliser ma macro maintenant il est déjà écrit et me donne un contrôle plus fin, mais c'est toujours bon à savoir. Merci. – Alconja

+0

sur Visual Studio 2008, il ferme également le serveur Web à l'arrêt de débogage – Jaguar

+0

Sur Visual Studio 2010, il fait aussi bien. (Il n'efface pas l'icône de la zone de notification tant que vous n'avez pas survolé l'icône.) –

5

Inspiré par ce message et un autre about code clean up J'ai ajouté la macro comme PostDebug-event. Ainsi, chaque fois que le débogueur revient, il supprimera tous WebDev.WebServer-s. (Et je me suis détendu la ProcessName-contrainte.)

Note: cela va probablement tuer tous les serveurs Web, donc aussi d'autres serveurs Web debug-sessions (ce qui est bien avec moi, à ce moment-là, je le fais habituellement pas en avoir).Donc, vous voudrez peut-être seulement rechercher des processus enfants ou quelque chose comme ça (et publiez ce code ici ;-)).

donc mon code ressemble à ceci:

Private Sub DebuggerEvents_OnEnterDesignMode(ByVal Reason As EnvDTE.dbgEventReason) _ 
      Handles DebuggerEvents.OnEnterDesignMode 
    If (Reason = dbgEventReason.dbgEventReasonStopDebugging) Then 
     Dim name As String = "WebDev.WebServer" 
     Dim proc As System.Diagnostics.Process 
     For Each proc In System.Diagnostics.Process.GetProcesses() 
      If (proc.ProcessName.StartsWith(name)) Then 
       proc.Kill() 
      End If 
     Next 
    End If 
End Sub 
+0

La meilleure solution pour cela, à mon avis. – Tim

8

Je viens d'ouvrir une ligne de commande (runas admin)

exécutez la commande suivante. Il faut tous les tuer

Taskkill /IM WebDev.WebServer40.EXE /F 
0

Une autre façon utilise Powershell:

PS: Je ne sais pas si tout le monde est toujours dans le besoin, mais j'ai couru accidentellement dans cette solution, tout en cherchant quelque chose de complètement différent.

Questions connexes