2010-02-03 3 views
3

J'ai créé une bibliothèque de classe .NET en C# qui initialise la journalisation, envoyée à un outil externe. La bibliothèque est complètement séparée de toute application, mais pour l'initialiser, j'ai besoin de faire au moins un appel de méthode.Est-il possible d '"injecter" une DLL .NET dans une autre application .NET, via app.config peut-être?

Y a-t-il un moyen pour moi de mettre quelque chose dans app.config qui va charger automatiquement cette DLL, et y appeler quelque chose? Je peux changer le contenu pour convenir à n'importe quoi, je n'ai pas besoin de supporter un nom de classe ou un nom de méthode ou quoi que ce soit d'autre.

Notez que j'ai besoin que cela soit fait sans aucune modification de l'application en question, sauf pour changer le fichier app.config.

Est-ce possible? Si oui, que devrais-je regarder?

+0

Appelez-moi fou, mais pourquoi votre outil de connexion ne s'initialise-t-il pas quelque part dans un bloc d'initialisation statique? –

+0

Le but est d'injecter ce code dans une application qui n'a pas été construite pour l'appeler. Un constructeur statique est seulement appelé parfois * avant * le code de la classe est utilisé, il n'y a aucune garantie qu'il sera jamais appelé si vous n'utilisez pas vraiment la classe. Comme l'application n'utilise pas du tout injection-dll, le constructeur statique ne sera pas appelé. –

Répondre

1

Cela m'a étonné pendant un moment sur la façon de le faire. Au départ, je pensais que cela pouvait être réalisé en créant un WebProxy personnalisé qui configurerait la journalisation, et en le chargeant dans l'application principale en utilisant l'élément de configuration . Cependant, le problème est le même que celui des autres suggestions de configuration, à savoir que le code n'est exécuté que lorsque cela est nécessaire (dans ce cas, lorsqu'une requête HTTP est utilisée), ce qui nécessite une modification de l'application d'origine.

Je l'ai atteint cependant en inversant l'approche. Au lieu d'essayer d'obtenir l'application d'origine pour configurer la journalisation, vous pouvez écrire un talon d'une application qui configure la journalisation, puis lance l'application d'origine.

À titre d'exemple:

J'ai une application WinForms appelé Forms.exe dont le point d'entrée est défini comme:

[STAThread] 
internal static void Main() 
{ 
    Application.Run(new MainForm()); 
} 

Dans mon application stub (que j'ai comme une application de la console), je configurer l'enregistrement puis charger et exécuter Forms.exe:

internal static void Main() 
{ 
    ConfigureLogging() 
    Assembly app = Assembly.LoadFrom(@".\Forms.exe"); 
    app.EntryPoint.Invoke(null, null); 
} 

T il utilise la réflexion pour charger l'autre application dans celle qui configure la journalisation.

Avertissements:

  • l'autre application doit être une application .Net pour le charger de cette façon
  • vous pourriez avoir besoin d'utiliser réflecteur pour inspecter l'autre application pour travailler le bon arguments à passer au point d'entrée (ie.si elle prend string[] args, vous devrez peut-être passer dans un vide string[] au lieu d'un null que les arguments)
  • la fenêtre de la console de l'application originale se bloque autour tandis que les autres pistes d'application (ce qui est probablement pas un problème, mais si Vous pouvez essayer de le cacher en utilisant FreeConsole)
+0

Ah, cette approche n'avait pas ' Je me suis rendu compte que oui, cela semble beaucoup plus prometteur. –

+0

Ceci est apparemment la seule option viable à gauche. Je ne connais pas les règles exactes utilisées pour déterminer quand les classes liées à ConfigurationSection sont chargées, mais il semble qu'elles ne soient chargées que si je touche à cette configuration. Dans mon cas, et dans le cas général, l'application ne lit pas cette configuration, cela ne fonctionnera donc pas. Cependant, le projet d'application stub fonctionne comme un charme. –

0

Oui, vous pouvez utiliser la réflexion pour charger le contenu de l'ensemble

+0

Le but était d'éviter de changer le code de l'application cible. Je peux facilement ajouter une réflexion ou autre si je veux suivre cette route. –

+0

@Lasse: Hmmmm ... Si l'application cible n'a pas été créée pour gérer cela, et que vous ne voulez pas la mettre à jour, vous êtes bloqué. Ce serait un problème de sécurité si c'était magique. –

+0

Oui, c'est aussi mon hypothèse, et comme je n'arrive pas à faire fonctionner la section de configuration, j'imagine que j'ai besoin de code dans l'application après tout. Peut-être que le hook de débogage que @Brian a commenté peut fonctionner à la place. –

2

Il serait probablement considéré comme un hack, mais si vous mettez quelque chose qui hérite ConfigurationSection dans votre dll, et d'ajouter que la section de configuration à votre app.config , cela vous permettra d'exécuter le code dans le constructeur de la section de configuration et ainsi faire à peu près ce que vous voulez. Il ne sera évidemment invoqué qu'une seule fois, au démarrage de l'application, mais si j'ai bien compris, cela suffirait. Est-ce que cela utilise du Cood Voodoo?

+0

Je vais essayer cela, semble prometteur. –

+0

Un hack est bien. Cette DLL se connecte au système d'écoute de Debug and Trace, pour capturer tous les messages du journal, et démarre les threads d'arrière-plan pour surveiller l'utilisation de la mémoire et du processeur, tout est envoyé à une application de journalisation externe. C'est un outil de débogage judiciaire que je dois utiliser pour une application que je ne peux malheureusement pas changer. –

+0

Eh bien, je ne vois pas pourquoi cela ne fonctionnerait pas alors. Bonne chance avec ça et laissez-moi savoir comment ça se passe. –

1

Snoop Heureusement, la source est disponible - regardez dans le projet nommé "ManagedInjector"

Questions connexes