web-dev-qa-db-fra.com

Comment utiliser ServerManager pour lire IIS sites, pas IIS express, à partir de la bibliothèque de classes OR comment les processus élevés gèrent-ils la classe bibliothèques?

J'ai quelques méthodes utilitaires qui utilisent Microsoft.Web.Administration.ServerManager avec lequel j'ai eu quelques problèmes. Utilisez le code simple mort suivant à des fins d'illustration.

using(var mgr = new ServerManager())
{
    foreach(var site in mgr.Sites)
    {
        Console.WriteLine(site.Name);
    }
}

Si je mets ce code directement dans une application console et l'exécute, il obtiendra et répertoriera les sites Web express IIS. Si j'exécute cette application à partir d'une invite de commande élevée, elle répertoriera les sites Web IIS7 Un peu gênant, mais jusqu'ici tout va bien.

Si, à la place, je mets ce code dans une bibliothèque de classes référencée et appelée par l'application console, il répertorie TOUJOURS les sites IIS Express, même si l'application console est élevée.

Google m'a amené à essayer ce qui suit, sans succès.

//This returns IIS express
var mgr = new ServerManager();
//This returns IIS express
var mgr = ServerManager.OpenRemote(Environment.MachineName);
//This throws an exception
var mgr = new  ServerManager(@"%windir%\system32\inetsrv\config\applicationhost.config");

Évidemment, j'ai mal compris quelque chose dans la façon dont un processus "élevé" s'exécute. Tout ce qui s'exécute dans un processus élevé, même le code d'une autre DLL, ne devrait-il pas être exécuté avec des droits élevés? Evidemment non?

Merci pour l'aide!

35
Josh

Assurez-vous que vous ajoutez la référence à la bonne Microsoft.Web.Administration, devrait être v7.0.0.0 qui se trouve sous c:\windows\system32\inetsrv\Il semble que vous ajoutiez une référence à IIS Express Microsoft.Web.Administraiton d'Express qui vous donnera ce comportement

58

Votre question m'a aidé à trouver la réponse pour PowerShell, donc si Internet cherche comment le faire:

$Assembly = [System.Reflection.Assembly]::LoadFrom("$env:systemroot\system32\inetsrv\Microsoft.Web.Administration.dll")

# load IIS express
$iis = new-object Microsoft.Web.Administration.ServerManager 
$iis.Sites

# load IIS proper
$iis = new-object Microsoft.Web.Administration.ServerManager "$env:systemroot\system32\inetsrv\config\applicationhost.config"  
$iis.Sites
9
Richard

ATTENTION! En utilisant cette approche, nous avons vu des problèmes apparemment aléatoires tels que les exceptions "opération non prise en charge", l'échec de l'ajout/suppression de liaisons HTTPS, l'échec du démarrage/arrêt des pools d'applications lors de l'exécution dans IIS Express et d'autres problèmes. On ne sait pas si cela est dû au fait que IIS est généralement bogué ou à l'approche peu orthodoxe décrite ici. En général, j'ai l'impression que tous les outils pour automatiser IIS (appcmd, Microsoft.Web.Administration, PowerShell, ...) sont bancals et instables, en particulier sur différentes versions de système d'exploitation. De bons tests sont (comme toujours) recommandés !

Le package Microsoft.Web.Administration Standard installé à partir de NuGet fonctionne très bien. Pas besoin de copier les DLL système.

La solution évidente de la documentation officielle fonctionne également très bien:

ServerManager iisManager = new ServerManager(@"C:\Windows\System32\inetsrv\config\applicationHost.config");

Cela fonctionne même si vous exécutez ce qui précède à partir du pool d'applications de IIS Express. Vous verrez toujours la configuration du "vrai" IIS. Vous pourrez même ajouter de nouveaux sites, tant que votre application s'exécute en tant qu'utilisateur autorisé à le faire.

Notez, cependant, que le constructeur ci-dessus est documenté comme "usage interne Microsoft uniquement":

https://msdn.Microsoft.com/en-us/library/ms617371 (v = vs.90) .aspx

4
Florian Winter
var iisManager = new ServerManager(Environment.SystemDirectory + "\\inetsrv\\config\\applicationhost.config");

Cela fonctionne parfaitement. Pas besoin de changer les références

0
arlak