在IIS7中,配置數據未存儲在「元數據庫」中,而且我們在IIS6中習慣使用的元數據庫屬性也不相同。 IIS7存儲在以下文件批量其配置數據:
%systemroot%\System32\InetSrv\Config\applicationHost.config
還有其他的文件,但對回答這個問題的目的,這是我們感興趣的文件。
爲applicationHost.config
的文檔可以在這裏找到:
<system.applicationHost>
- IIS.NET
configuration Element [IIS 7 Settings Schema]
system.applicationHost Section Group [IIS 7 Settings Schema]
你可以找到IIS6元數據庫的清單 - 在這裏> IIS7 XML配置映射:
Converting Metabase Properties to Configuration Settings [IIS 7]
例如在IIS6的路徑網站的/root
存儲在IIsWebVirtualDir
的Path
屬性中。即:
<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元數據庫API(如ADSI,System.DirectoryServices等)訪問IIS7站點屬性。兼容性層將爲您映射這些屬性到新的IIS7模式。
這篇文章的第一部分介紹瞭如何在Vista/Windows7的/ Windows 2008的安裝此:
How to install ASP.NET 1.1 with IIS7 on Vista and Windows 2008 - see step #1
更新:
不幸的是C++是不是我的優點。不過,我使用COM互操作使用AppHostWritableAdminManager
證明放在一起的例子在C#:
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>
集合在一個名爲「mysite的」網站。然後它檢索該網站的<bindings>
集合和打印的每個綁定和bindingInformation
屬性。
你應該能夠很容易地將其轉換爲C++。
要回答這個問題在您的評論 -
例如,路徑 system.applicationHost /網站將得到 我的站點列表。是否有 絕對的方式通過 要到我的服務器 綁定像這樣(例如做 system.applicationHost /網站/默認 網站/綁定
當使用AppHostWritableAdminManager
沒有快捷方式直接訪問您想要檢查/修改的網站或它的屬性在上面的例子中,您會看到我需要循環訪問網站集以查找我感興趣的網站。原因是AppHostWritableAdminManager
將一切看作元素和元素集合,它是一個相當基礎的API,即使使用受管理的API,您也會發現雖然有一些不錯的屬性例如Site.Bindings
,這些都是圍繞AppHostWritableAdminManager
的簡單僞裝包裝。
事實上,如果我想,如果我使用C#3.5或更高版本找到一個網站,我還是要搜索Sites
收集無論是在for循環或通過添加一些LINQ糖:
using(ServerManager serverManager = new ServerManager())
{
Site x = serverManager.Sites.FirstOrDefault(s => s.Name == "MySite");
}
Site
的基類是ConfigurationElement
,它在發動機罩下包裝訪問IAppHostElement
。
一旦你過去了一些基本的快捷包裝屬性,我們在託管代碼中配置IIS(例如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;
}
Kev,非常感謝您的回覆。你可以請我參考「管理部分」的解釋和提交路徑?例如,路徑system.applicationHost/Sites將讓我訪問站點列表。有沒有一種絕對的方式來到我的服務器綁定這樣(例如通過做system.applicationHost /站點/默認網站/綁定? – Ron
@龍 - 請參閱我的更新的答案。希望這將清除事情。 – Kev
再次感謝 - 我想我已經開始想到了這一點,基本上,爲了訪問我的服務器綁定,我需要在system.applicationHost/Sites部分找到我的網站,然後遍歷集合並找到我的網站,然後,我需要迭代我的網站的子元素,並尋找綁定。這很好,但有沒有辦法直接到綁定(可能是像system.applicationHost /默認網站/綁定?請讓我知道你的想法 - 並感謝如此多的 – Ron