2010-06-02 5 views
6

Existe-t-il un moyen de déterminer si l'application exécutée est WinForms ou Web lors de l'exécution?Déterminer si l'application est WinForms ou WebForms

[Modifier]

Est-il vraiment un problème si je fais référence à la fois System.Web et System.Windows.Forms dans ma bibliothèque de classe?

[Résumé] (jusqu'à présent)

Ce que j'ai appris jusqu'à présent:

  • HttpContext.Current est null si elle est cochée dans un fil de async, donc il ne peut pas être utilisé de manière fiable dans une aide méthode. HttpRuntime.Cache n'aide pas vraiment puisque je ne cherche pas du tout le contexte en cache (ou est-ce que je manque quelque chose ici?). D'autre part, System.Reflection.Assembly.GetEntryAssembly() semble retourner null dans les applications web, et non null dans WinForms. Cela devrait-il être considéré comme acquis? Il devrait y avoir plus de "hacks" comme ça, alors lequel utiliser?
  • référençant à la fois System.Web et System.Windows.Forms dans une bibliothèque auxiliaire devrait être bien, selon this thread.

Répondre

4

Vérifiez si HttpContext.Current est null. Si c'est le cas, ce n'est pas une webapp.

+0

Merci! Pourriez-vous également vérifier ma question mise à jour pour un détail supplémentaire? – dummy

+0

Comme l'écrit M. Smith ci-dessous, HttpContext.Current est null lorsque vous effectuez des tâches asynchrones, donc cela ne fonctionne pas toujours. – dummy

2

HttpContext.Current peut être nulle dans une application Web si elle effectue un traitement asynchrone. De this threadHttpRuntime.Cache pourrait être une meilleure chose à tester.

1

Pour que cette question soit logique, vous devez avoir inclus des références à System.Windows et à System.Windows dans votre projet. C'est en soi (à mon avis) un peu d'odeur de code.

Il est probablement préférable de collecter les informations nécessaires dans la méthode d'appel (qui doit être résolument dans le domaine Web ou WinForms) et de transmettre cette information aux métodes qui ont besoin de cette information comme argument.

[modifier]

Une façon de le faire ci-dessous. Toujours moche, mais cela signifie seulement avoir à définir le fait que vous êtes dans une application Web une fois.

public class Helper 
{ 
    public static bool IsCurrentAppWeb; //defaults to false 
    public bool TheActualHelpFullFunction() 
    { 
     if(Helper.IsCurrentAppWeb) 
     { 
      //do web specific things 
     } 
     else 
     { 
      //do things the non-web way. 
      //note that this does not tell you 
      //if you are currently running a WinForm or service or... 
     } 
    } 
} 
+0

Eh bien, le but est d'avoir une logique commune dans un assembly partagé (qui référencerait tout ce dont il a besoin pour référencer), donc les assemblys appelant n'auront besoin que de référencer cet assembly partagé. – dummy

+0

Sans vouloir vous offenser, le code que vous avez publié est un exemple d'odeur de code, et c'est bien pire que d'ajouter deux références. Les classes ne doivent jamais exposer les champs publics pour que d'autres clients puissent les modifier. Si vous avez besoin de transmettre des informations à la méthode, passez-la en paramètre (comme 'bool TheActualHelpFunction (bool isCurrentAppWeb)'), n'attendez pas de vos appelants qu'ils changent une série de drapeaux avant d'appeler une méthode. – dummy

+0

Je suis d'accord, mon exemple n'est pas meilleur. Ce que je voudrais éviter, c'est de faire en sorte qu'un assembly change son comportement en fonction de l'environnement dans lequel il s'exécute. Cela ne poserait pas de problème pour vous, mais la prochaine personne pourrait hériter du code. Il peut ne pas savoir que le comportement change en fonction du contexte d'exécution. La lecture de votre autre question (http://stackoverflow.com/questions/2957042/get-the-file-path-of-the-current-app) rend l'intention beaucoup plus claire pour moi. Je ne peux qu'applaudir l'intention. – LaustN

1

Une autre façon de procéder consiste à regarder le nom du processus en cours.

using System.Diagnostics; 

public class Helper 
{ 
    public static bool IsCurrentAppWeb() 
    { 
    return Process.GetCurrentProcess().ProcessName == "aspnet_wp"; 
    } 
} 

Cette solution fonctionne pour XP, la chaîne à comparer varie en fonction de l'environnement. Lorsque vous exécutez VS en mode de débogage par défaut, vous devez comparer le nom du serveur de test intégré.

Pas la plus jolie solution, mais elle vous permet d'omettre des références à des assemblages web ou winforms. Pour plus de détails sur la classe de processus, consultez http://msdn.microsoft.com/en-us/library/system.diagnostics.process_members(v=VS.100).aspx.

5

Dans votre édition, vous spécifiez que votre classe d'assistance est dans un ensemble séparé. Si vous voulez éviter les références et que vous avez le contrôle sur votre application.les fichiers de configuration que vous pourriez mettre un

<add key="typeOfSystem" value="Forms|Web"/> 

dans vos projets et accéder avec

ConfigurationManager.AppSettings["typeOfSystem"] 

en utilisant ConfigurationManager avec sa propriété AppSettings. N'oubliez pas d'ajouter une référence à System.Configuration dans votre projet. Notez que vous obtenez les AppSettings de l'application d'hébergement. En faisant cela, besoin pour ajouter une clé dans app.config de votre application parente, ou de produire une erreur ou un avertissement si ce n'est pas spécifié peut-être.

1

L'AppDomain contient des informations sur le fichier de configuration associé. Comme les applications Web ont leur fichier de configuration nommé "web.config" et tous les autres ont "{app} .exe.config", cela détermine le type d'application.

/// <summary> 
/// Extensions for the AppDomain class 
/// </summary> 
public static partial class AppDomainExtensions 
{ 
    /// <summary> 
    /// Determines whether the specified app domain is a web app. 
    /// </summary> 
    /// <param name="appDomain">The app domain.</param> 
    /// <returns> 
    ///  <c>true</c> if the specified app domain is a web app; otherwise, 
    /// <c>false</c>. 
    /// </returns> 
    public static bool IsWebApp(this AppDomain appDomain) 
    { 
     var configFile = (string)appDomain.GetData("APP_CONFIG_FILE"); 
     if (string.IsNullOrEmpty(configFile)) return false; 
     return (
      Path.GetFileNameWithoutExtension(configFile) ?? string.Empty 
     ).Equals(
      "WEB", 
      StringComparison.OrdinalIgnoreCase); 
    } 
} 
0

Vous anéantissez convinient de le faire avec des biens-cadre:

HostingEnvironment.IsHosted 

Référence System.Web et ajoutez espace de noms System.Web.Hosting.

Lorsque IsHosted est défini sur true, cela signifie que l'hôte est un site Web.

Questions connexes