如何使用ServerManager从类库中读取IIS站点,而不是IIS表达式或升级进程如何处理类库?

Jos*_*osh 35 c# iis-7 uac iis-express elevated-privileges

我有一些使用的方法,Microsoft.Web.Administration.ServerManager我一直有一些问题.使用以下死简单代码进行说明.

using(var mgr = new ServerManager())
{
    foreach(var site in mgr.Sites)
    {
        Console.WriteLine(site.Name);
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我将该代码直接放在控制台应用程序中并运行它,它将获取并列出IIS快速网站.如果我从提升的命令提示符运行该应用程序,它将列出IIS7网站.有点不方便,但到目前为止还不错.

如果我将该代码放在由控制台应用程序引用和调用的类库中,它将始终列出IIS Express站点,即使控制台应用程序已升级.

谷歌让我尝试以下,没有运气.

//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");
Run Code Online (Sandbox Code Playgroud)

显然我误解了"升级"过程的运行方式.不应该在升级过程中执行的所有操作,甚至是来自另一个dll的代码,都应该以提升的权限运行吗?显然不是吗?

谢谢您的帮助!

Car*_*res 57

请确保您添加的引用到正确的Microsoft.Web.Administration,应该是v7.0.0.0是位于C:\ WINDOWS\SYSTEM32\INETSRV \看起来要添加到IIS快递的Microsoft.Web参考.Administraiton会给你这种行为

  • 谢谢.我有一个对7.0.0.0的引用(来自inetmgr目录),但Visual Studio默默地从GAC切换到7.9.0.0(IISExpress).在我的*.csproj中的程序集引用中设置``<SpecificVersion> True </ SpecificVersion>``修复了问题.您可以通过在调试器中启动应用程序并查看"ServerManager.ApplicationPoolsSection.Configuration.ConfigFile.FilePath`"来判断ServerManager是使用IIS还是IISExpress,以查看它是否包含inetsrv或IISExpress. (9认同)
  • 我还注意到,即使您在%windir%\ system32\inetsrv \中运行对程序集的引用,但是您正在IIS Express进程中执行代码,它只会返回IIS Express站点,但是当我在运行它时具有管理员权限的控制台应用程序,我只获得IIS 7.5站点(在Windows 7 x64上). (4认同)
  • 我爱你.这让我发疯了. (3认同)
  • 卡洛斯.谢谢回复!你是对的!我仔细检查了,不知何故,类库中的引用搞砸了.我会发誓它有正确的参考,但不知何故,它指向GAC中的7.9.0.0.谢谢! (2认同)
  • 我怀疑安装VS 2012会导致我遇到同样的问题,也许它只安装了IIS express并且实际上并不是直接原因. (2认同)

Ric*_*ard 9

您的问题帮助我找到了PowerShell的答案,因此如果Internet正在搜索如何执行此操作:

$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
Run Code Online (Sandbox Code Playgroud)


Flo*_*ter 5

警告!使用这种方法,我们看到了一些看似随机的问题,例如“不受支持的操作”异常、无法添加/删除 HTTPS 绑定、在 IIS Express 中运行时无法启动/停止应用程序池以及其他问题。不知道这是由于 IIS 普遍存在缺陷还是由于此处描述的非正统方法。总的来说,我的印象是所有用于自动化 IIS 的工具(appcmd、Microsoft.Web.Administration、PowerShell 等)都不稳定且不稳定,尤其是在不同的操作系统版本中。良好的测试(一如既往)是可取的!

编辑:另请参阅对此答案的评论,了解为什么这种方法可能不稳定。

Microsoft.Web.Administration从 NuGet 安装的常规包工作正常。无需复制任何系统 DLL。

官方文档中的明显解决方案也可以正常工作:

ServerManager iisManager = new ServerManager(@"C:\Windows\System32\inetsrv\config\applicationHost.config");
Run Code Online (Sandbox Code Playgroud)

即使您从 IIS Express 的应用程序池中执行上述操作,这也有效。您仍将看到“真实”IIS 的配置。您甚至可以添加新站点,只要您的应用程序以具有权限的用户身份运行即可。

但是请注意,上面的构造函数被记录为“仅供 Microsoft 内部使用”:

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

  • 我不认为效果是随机的。系统中存在该 dll 的两个版本,一种在 GAC 中,一种在“System32\inetsrv\``”中。由于某种奇怪的未知原因,两者具有相同的名字。GAC 中的一个用于 IISExpress,而 inetsrv 中的一个用于 IIS。两者都无法正确读取对方的数据。显然 GAC 版本不应该存在于实际的网络服务器中,因为未安装 Visual Studio。 (2认同)