获取IIS 7网站属性
-
16-10-2019 - |
题
我有一个C ++应用程序需要检索IIS 7站点的属性(例如类似于IIS6中的属性属性 - Path
, AppFriendlyName
ETC)。
使用IIS 7,我的代码可以做到这一点:
- 得到
AppHostWritableAdminManager
并提出道路MACHINE/WEBROOT/APPHOST/Default Web Site/
. - 称呼
GetAdminSection
带有部分名称appSettings
. - 然后查看返回的集合并查找属性(
Path
例如)。
这在IIS 6中起作用,但在IIS7/7.5上不起作用。
为了完成这项工作,我需要做出什么更改?
解决方案
在IIS7中,配置数据不存储在“ metabase”中,也不存储我们在IIS6中习惯的metabase属性并不相同。 IIS7将其大部分配置数据存储在以下文件中:
%systemroot%\System32\InetSrv\Config\applicationHost.config
还有其他文件,但是为了回答这个问题,这是我们感兴趣的文件。
文档 applicationHost.config
可以在这里找到:
<system.applicationHost>
-iis.net
配置元素[IIS 7设置模式
System.ApplicationHost部分组[IIS 7设置模式
您可以在此处找到IIS6 metabase-> IIS7 XML配置映射的列表:
例如,在IIS6中 /root
存储在 Path
属性 IIsWebVirtualDir
. 。 IE:
<IIsWebServer Location="/LM/W3SVC/67793744" AuthFlags="0" ServerAutoStart="TRUE"
ServerBindings="217.69.47.170:80:app2.dev" ServerComment="app2" />
<IIsWebVirtualDir Location="/LM/W3SVC/67793744/root"
AccessFlags="AccessRead | AccessScript"
AppFriendlyName="Default Application"
AppIsolated="2"
AppRoot="/LM/W3SVC/67793744/Root"
AuthFlags="AuthAnonymous | AuthNTLM"
DirBrowseFlags="DirBrowseShowDate | DirBrowseShowTime | DirBrowseShowSize |
DirBrowseShowExtension | DirBrowseShowLongDate | EnableDefaultDoc"
Path="D:\websites\ssl-test\www\kerboom"
ScriptMaps="...">
但是在IIS7中,它的存储方式不同:
<sites>
<site name="Default Web Site" id="1" serverAutoStart="true">
<!-- this is the functional equivalent of the /root app in IIS6 -->
<application path="/">
<virtualDirectory path="/"
physicalPath="%SystemDrive%\inetpub\wwwroot" />
</application>
</site>
<sites>
但是,如果您的代码必须与IIS6和IIS7一起使用,则可以安装IIS6管理兼容性组件。这将使您能够使用传统的IIS6 Metabase API(例如ADSI,System.DirectoryServices等)访问IIS7站点属性。兼容性层将这些属性映射到您的新IIS7架构中。
本文的第一部分说明了如何在Vista/Windows7/Windows 2008上安装此信息:
更新:
不幸的是,C ++不是我的强项。但是,我使用com Interop在C#中汇总了一个示例 AppHostWritableAdminManager
:
IAppHostWritableAdminManager wam = new AppHostWritableAdminManager();
IAppHostElement sites =
wam.GetAdminSection("system.applicationHost/sites", "MACHINE/WEBROOT/APPHOST");
IAppHostElementCollection sitesCollection = sites.Collection;
long index = FindSiteIndex(sitesCollection, "MySite");
if(index == -1) throw new Exception("Site not found");
IAppHostElement site = sitesCollection[index];
IAppHostElementCollection bindings = site.ChildElements["bindings"].Collection;
for (int i = 0; i < bindings.Count; i++)
{
IAppHostElement binding = bindings[i];
IAppHostProperty protocolProp = binding.GetPropertyByName("protocol");
IAppHostProperty bindingInformationProp =
binding.GetPropertyByName("bindingInformation");
string protocol = protocolProp.Value;
string bindingInformation = bindingInformationProp.Value;
Debug.WriteLine("{0} - {1}", protocol, bindingInformation);
}
static long FindSiteIndex(IAppHostElementCollection sites, string siteName)
{
for (int i = 0; i < sites.Count; i++)
{
IAppHostElement site = sites[i];
Debug.WriteLine(site.Name);
IAppHostProperty prop = site.GetPropertyByName("name");
if(prop.Value == siteName)
{
return i;
}
}
return -1;
}
上面的代码在 <sites>
收藏。然后检索网站的 <bindings>
收集和打印的每个绑定 protocol
和 bindingInformation
属性。
您应该能够轻松地将其转换为C ++。
在您的评论中回答问题 -
例如,PATH System.ApplicationHost/站点将使我进入站点列表。是否有一种绝对的方法可以像这样到达我的服务器绑定(例如,使用System.ApplicationHost/stites/default网站/绑定
使用时 AppHostWritableAdminManager
直接进入您要检查/修改或其属性的网站没有快捷方式。在上面的示例中,您会发现我需要循环浏览网站集合以查找我感兴趣的网站。原因是 AppHostWritableAdminManager
将所有内容视为元素的元素和集合。这是一个相当基本的API。即使使用托管 Microsoft.Web.Administration
API您发现,尽管有一些不错的属性,例如 Site.Bindings
, ,这些都是伪装的包装器 AppHostWritableAdminManager
.
实际上,如果我想找到一个网站,我仍然必须搜索 Sites
如果我使用C#3.5或以后,则在for循环中收集或通过添加一些LINQ糖:
using(ServerManager serverManager = new ServerManager())
{
Site x = serverManager.Sites.FirstOrDefault(s => s.Name == "MySite");
}
Site
的基础是 ConfigurationElement
在引擎盖包装下的访问 IAppHostElement
.
一旦您经过一些基本的快捷方式包装属性,我们在托管代码中所做的很多事情(例如IIS FTP)是元素的元素,属性和集合。
更新2:
请记住,我一生中从未写过C ++系列。没有清理字符串或物体:
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <ahadmin.h>
#include <crtdbg.h>
static IAppHostElement*
FindSite(IAppHostElementCollection *pCollection, BSTR bstrSiteName);
int _tmain(int argc, _TCHAR* argv[])
{
CoInitialize(NULL);
IAppHostWritableAdminManager *pMgr = NULL;
IAppHostElement *pElem = NULL;
IAppHostElementCollection *pSitesCollection = NULL;
IAppHostElement *pSite = NULL;
IAppHostElement *pBindings = NULL;
IAppHostElement *pBinding = NULL;
IAppHostElementCollection *pBindingsCollection = NULL;
IAppHostChildElementCollection *pChildElements = NULL;
IAppHostProperty *pProtocol = NULL;
IAppHostProperty *pBindingInformation = NULL;
BSTR bstrSectionName = SysAllocString( L"system.applicationHost/sites" );
BSTR bstrConfigCommitPath = SysAllocString( L"MACHINE/WEBROOT/APPHOST" );
BSTR bstrSiteName = SysAllocString( L"MySite" );
BSTR bstrBindingsConst = SysAllocString( L"bindings" );
BSTR bstrBindingProtocol = SysAllocString( L"protocol" );
BSTR bstrBindingInformation = SysAllocString( L"bindingInformation" );
VARIANT vtPropertyName;
VARIANT vtIndex;
HRESULT hr = S_OK;
hr = CoCreateInstance( __uuidof(AppHostWritableAdminManager), NULL,
CLSCTX_INPROC_SERVER, __uuidof(IAppHostWritableAdminManager), (void**) &pMgr);
hr = pMgr->GetAdminSection(bstrSectionName, bstrConfigCommitPath, &pElem);
hr = pElem->get_Collection(&pSitesCollection);
pSite = FindSite(pSitesCollection, bstrSiteName);
hr = pSite->get_ChildElements(&pChildElements);
vtPropertyName.vt = VT_BSTR;
vtPropertyName.bstrVal = bstrBindingsConst;
hr = pChildElements->get_Item(vtPropertyName, &pBindings);
hr = pBindings->get_Collection(&pBindingsCollection);
DWORD bindingsCount;
hr = pBindingsCollection->get_Count(&bindingsCount);
for(int i = 0; i < bindingsCount; i++)
{
vtIndex.lVal = i;
vtIndex.vt = VT_I4;
hr = pBindingsCollection->get_Item(vtIndex, &pBinding);
hr = pBinding->GetPropertyByName(bstrBindingProtocol, &pProtocol);
hr = pBinding->GetPropertyByName(bstrBindingInformation, &pBindingInformation);
BSTR bstrProtocol;
BSTR bstrBindingInformation;
hr = pProtocol->get_StringValue(&bstrProtocol);
hr = pBindingInformation->get_StringValue(&bstrBindingInformation);
_tprintf(_T("Protocol: %s, BindingInfo: %s\n"), bstrProtocol, bstrBindingInformation);
}
CoUninitialize();
return 0;
}
IAppHostElement* FindSite(IAppHostElementCollection *pCollection, BSTR bstrSiteName)
{
DWORD count = -1;
pCollection->get_Count(&count);
BSTR bstrPropName = SysAllocString( L"name");
for(DWORD i = 0; i < count; i++)
{
IAppHostElement *site = NULL;
IAppHostProperty *prop = NULL;
BSTR bstrPropValue;
HRESULT hr = S_OK;
VARIANT vtCount;
VariantInit(&vtCount);
vtCount.lVal = i;
vtCount.vt = VT_I4;
hr = pCollection->get_Item(vtCount, &site);
hr = site->GetPropertyByName(bstrPropName, &prop);
hr = prop->get_StringValue(&bstrPropValue);
if(wcscmp(bstrPropValue, bstrSiteName) == 0)
{
return site;
}
}
return NULL;
}