Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用ServerManager从类库中读取IIS站点,而不是IIS express,或者提升的进程如何处理类库?_C#_Iis 7_Uac_Iis Express_Elevated Privileges - Fatal编程技术网

C# 如何使用ServerManager从类库中读取IIS站点,而不是IIS express,或者提升的进程如何处理类库?

C# 如何使用ServerManager从类库中读取IIS站点,而不是IIS express,或者提升的进程如何处理类库?,c#,iis-7,uac,iis-express,elevated-privileges,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); } } 如果我将代码直接放在控制台应用程序中并运行它,它将获取并列出IIS express网站。如果

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

using(var mgr = new ServerManager())
{
    foreach(var site in mgr.Sites)
    {
        Console.WriteLine(site.Name);
    }
}
如果我将代码直接放在控制台应用程序中并运行它,它将获取并列出IIS express网站。如果我从提升的命令提示符运行该应用程序,它将列出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");
显然,我误解了“提升”流程运行的方式。提升进程中执行的所有内容,甚至来自另一个dll的代码,都不应该以提升的权限运行吗?显然不是


谢谢你的帮助

确保您正在添加对正确的Microsoft.Web.Administration的引用,该引用应为位于c:\windows\system32\inetsrv下的v7.0.0.0\
看起来您正在添加对IIS Express的Microsoft.Web.Administraton的引用,这将为您提供该行为

您的问题帮助我找到了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

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

编辑:请参阅此答案上的注释,了解此方法可能不稳定的原因。

从NuGet安装的常规
Microsoft.Web.Administration
软件包运行良好。无需复制任何系统DLL

官方文档中显而易见的解决方案也很有效:

ServerManager iisManager = new ServerManager(@"C:\Windows\System32\inetsrv\config\applicationHost.config");
即使您从IIS Express的应用程序池中执行上述操作,此操作也会起作用。您仍将看到“真实”IIS的配置。您甚至可以添加新站点,只要您的应用程序以具有权限的用户身份运行

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


这很好用。无需更改任何参考资料。谢谢你的回复!你是对的!我仔细检查了一遍,不知怎的,类库里的参考资料搞砸了。我发誓它的引用是正确的,但不知怎的,它指向了GAC中的7.9.0.0。谢谢我怀疑安装VS 2012导致我出现同样的问题,可能它只是安装了IIS express,而实际上不是直接原因。我还注意到,即使您在%windir%\system32\inetsrv\中运行对程序集的引用,但您在IIS express进程中执行代码,它也只返回IIS express站点,但是,当我在具有管理员权限的控制台应用程序中运行它时,我只会得到IIS 7.5站点(在Windows 7 x64上)。我爱你。这让我发疯了,谢谢你。我曾引用过7.0.0.0(来自inetmgr dir),但VisualStudio却悄悄地将其从GAC转换为7.9.0.0(IISExpress)。在my*.csproj中的程序集引用中设置
True
,修复了该问题。通过在调试器中启动应用程序并查看
ServerManager.ApplicationPoolsSection.Configuration.ConfigFile.FilePath
以查看它是否包含inetsrv或IISExpress,您可以判断ServerManager是否正在使用IIS或IISExpress。请注意,您使用的构造函数记录为“仅限Microsoft内部使用”当前位置我认为效果不是随机的。系统中存在该dll的两个版本,一个在GAC中,另一个在
System32\inetsrv\
中。由于某种奇怪的未知原因,两者都有相同的名字。GAC中的一个用于IISExpress,inetsrv中的一个用于IIS。两人都不能正确读取对方的数据。显然,GAC版本不应该存在于实际的Web服务器中,因为未安装visual studio。@AaA感谢您的解释。您不知道是否有官方/可靠的方法链接到正确的DLL?公认的答案是基于版本号的,版本号似乎不稳定,因为版本号会发生变化(对此的评论表明这种情况已经发生)。我不确定您想知道什么,IISExpress版本通常不存在于生产环境中。如果您不想复制应用程序文件夹中的dll(显然是从安装应用程序的同一台机器上),那么
var iisManager = new ServerManager(Environment.SystemDirectory + "\\inetsrv\\config\\applicationhost.config");