IIS 7のサイトプロパティを取得します
-
16-10-2019 - |
質問
IIS 7サイトのプロパティを取得する必要があるC ++アプリケーション(IIS6のプロパティと同様のメタベースプロパティなどがあります - Path
, AppFriendlyName
等)。
IIS 7では、私のコードがこれを行います。
- 取得します
AppHostWritableAdminManager
そしてパスをコミットしますMACHINE/WEBROOT/APPHOST/Default Web Site/
. - 電話
GetAdminSection
セクション名付きappSettings
. - 次に、返されたコレクションを見て、プロパティを探します(
Path
例えば)。
これはIIS 6で機能しますが、IIS7/7.5では機能しません。
これを機能させるためには、どのような変更を加える必要がありますか?
解決
IIS7では、構成データは「メタベース」に保存されておらず、IIS6で慣れているメタベースプロパティも同じではありません。 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
. 。つまり:
<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管理互換性コンポーネントをインストールできます。これにより、ADSI、System.DirectoryServicesなどの従来のIIS6 Metabase APIを使用してIIS7サイトプロパティにアクセスできます。互換性レイヤーは、これらのプロパティを新しいIIS7スキーマにマッピングします。
この記事の最初の部分では、これをVista/Windows7/Windows 2008にインストールする方法について説明します。
VistaおよびWindows 2008にIIS7を使用してASP.NET 1.1をインストールする方法 - ステップ#1を参照してください
アップデート:
残念ながら、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/sites/default webサイト/バインディングを行うことによって
を使用する場合 AppHostWritableAdminManager
検査/変更するサイトまたはそれがプロパティに直接到達するためのショートカットはありません。上記の例では、私が興味を持っているサイトを見つけるために、サイトコレクションをループする必要があることがわかります。その理由は、 AppHostWritableAdminManager
すべてを要素と要素のコレクションと見なします。これはかなり基本的なAPIです。マネージドを使用する場合でも Microsoft.Web.Administration
APIあなたはあなたが見つけることがわかりますが、ようないくつかの素晴らしいプロパティがあります Site.Bindings
, 、これらは薄く変装したラッパーです AppHostWritableAdminManager
.
実際、サイトを見つけたい場合は、まだ検索する必要があります Sites
c#3.5以降を使用している場合は、ループの場合、または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;
}