How to use ServerManager to read IIS sites, not IIS express, from class library OR how do elevated processes handle class libraries?

孤街浪徒 提交于 2019-12-18 11:01:29

问题


I have some utility methods that uses Microsoft.Web.Administration.ServerManager that I've been having some issues with. Use the following dead simple code for illustration purposes.

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

If I put that code directly in a console application and run it, it will get and list the IIS express websites. If I run that app from an elevated command prompt, it will list the IIS7 websites. A little inconvenient, but so far so good.

If instead I put that code in a class library that is referenced and called by the console app, it will ALWAYS list the IIS Express sites, even if the console app is elevated.

Google has led me to try the following, with no luck.

//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");

Evidently I've misunderstood something in the way an "elevated" process runs. Shouldn't everything executing in an elevated process, even code from another dll, be run with elevated rights? Evidently not?

Thanks for the help!


回答1:


Make sure you are adding the reference to the correct Microsoft.Web.Administration, should be v7.0.0.0 that is located under c:\windows\system32\inetsrv\ It looks like you are adding a reference to IIS Express's Microsoft.Web.Administraiton which will give you that behavior




回答2:


Your question helped me find the answer for PowerShell, so if the Internet is searching for how to do that:

$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



回答3:


CAUTION! Using this approach we have seen seemingly random issues such as "unsupported operation" exceptions, failure to add/remove HTTPS bindings, failure to start/stop application pools when running in IIS Express, and other problems. It is unknown whether this is due to IIS being generally buggy or due to the unorthodox approach described here. In general, my impression is that all tools for automating IIS (appcmd, Microsoft.Web.Administration, PowerShell, ...) are wonky and unstable, especially across different OS versions. Good testing is (as always) advisable!

The regular Microsoft.Web.Administration package installed from NuGet works fine. No need to copy any system DLLs.

The obvious solution from the official documentation also works fine:

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

This works even if you execute the above from within the application pool of IIS Express. You will still see the configuration of the "real" IIS. You will even be able to add new sites, as long as your application runs as a user with permission to do so.

Note, however that the constructor above is documented as "Microsoft internal use only":

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




回答4:


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

This works perfectly. No need to change any references



来源:https://stackoverflow.com/questions/8467908/how-to-use-servermanager-to-read-iis-sites-not-iis-express-from-class-library

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!