3

PathIIS 7サイトのプロパティ(IIS6と同様のメタベースプロパティAppFriendlyNameなど)を取得する必要があるC++アプリケーションがあります。

IIS 7では、私のコードはこれを行います。

  1. を取得しAppHostWritableAdminManager、パスをコミットしますMACHINE/WEBROOT/APPHOST/Default Web Site/
  2. GetAdminSectionセクション名で呼び出しappSettingsます。
  3. 次に、返されたコレクションを見て、プロパティを探します(Pathたとえば)。

これはIIS6では機能しますが、IIS7/7.5では機能しません。

これを機能させるには、どのような変更を加える必要がありますか?

4

1 に答える 1

8

IIS7では、構成データは「メタベース」に格納されません。また、IIS6で慣れているメタベースのプロパティも同じではありません。IIS7は、構成データの大部分を次のファイルに保存します。

%systemroot%\System32\InetSrv\Config\applicationHost.config

他のファイルもありますが、この質問に答えるために、これは私たちが興味を持っているファイルです。

のドキュメントはapplicationHost.configここにあります:

<system.applicationHost>-IIS.NET
構成要素[IIS7設定スキーマ]
system.applicationHostセクショングループ[IIS7設定スキーマ]

IIS6メタベース->IIS7XML構成マッピングのリストは次の場所にあります。

メタベースプロパティの構成設定への変換[IIS7]

たとえば、IIS6では、サイトへのパスはの属性に/root格納されます。すなわち:PathIIsWebVirtualDir

<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メタベースAPIを使用してIIS7サイトのプロパティにアクセスできるようになります。互換性レイヤーは、これらのプロパティを新しいIIS7スキーマにマップします。

この記事の最初の部分では、これをVista / Windows7 /Windows2008にインストールする方法について説明します。

VistaおよびWindows2008でIIS7を使用してASP.NET1.1をインストールする方法-手順1を参照してください

アップデート:

残念ながら、C++は私の強みではありません。ただし、COM相互運用機能を使用した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;
}

上記のコードは、コレクション内の「MySite」という名前のサイトを検索します<sites>。次に、サイトのコレクションを取得し、<bindings>各バインディングprotocolbindingInformation属性を印刷します。

これをC++にかなり簡単に変換できるはずです。

コメントの質問に答えるには-

たとえば、パスsystem.applicationHost / Sitesを使用すると、サイトのリストが表示されます。このようなサーバーバインディングに到達する絶対的な方法はありますか(たとえば、system.applicationHost / Sites / Default Web Site / Bindingsを実行することによって)

を使用する場合AppHostWritableAdminManager、検査/変更するサイトまたはそのプロパティに直接アクセスするためのショートカットはありません。上記の例では、興味のあるサイトを見つけるためにサイトコレクションをループする必要があることがわかります。これは、AppHostWritableAdminManagerすべてを要素および要素のコレクションと見なすためです。これはかなり基本的なAPIです。マネージMicrosoft.Web.AdministrationAPIを使用している場合でも、などの優れたプロパティがいくつかありますがSite.Bindings、これらはの周りの薄く偽装されたラッパーであることがわかりますAppHostWritableAdminManager

実際、サイトを検索したい場合でもSites、forループでコレクションを検索するか、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;
}
于 2011-01-23T02:06:50.537 に答える