Frage

Ich habe eine C ++ - Anwendung, die die Eigenschaften einer IIS 7 -Site abrufen muss (z. B. Metabase -Eigenschaften ähnlich denen in IIS6 - Path, AppFriendlyName etc).

Mit IIS 7 macht mein Code dies:

  1. Bekommen das AppHostWritableAdminManager und den Weg begehen MACHINE/WEBROOT/APPHOST/Default Web Site/.
  2. Anruf GetAdminSection mit dem Abschnittsnamen appSettings.
  3. Schauen Sie sich dann die zurückgegebene Sammlung an und suchen Sie nach der Eigenschaft (Path zum Beispiel).

Dies funktioniert in IIS 6, aber nicht auf IIS7/7.5.

Welche Änderungen muss ich vornehmen, um diese Funktion zu machen?

War es hilfreich?

Lösung

In IIS7 werden die Konfigurationsdaten nicht in einer "Metabase" gespeichert und auch die Stoffwechseleigenschaften, an die wir in IIS6 gewöhnt sind, sind nicht gleich. IIS7 speichert den Großteil seiner Konfigurationsdaten in der folgenden Datei:

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

Es gibt andere Dateien, aber zur Beantwortung dieser Frage ist dies die Datei, an der wir interessiert sind.

Die Dokumentation für applicationHost.config kann hier gefunden werden:

<system.applicationHost> - iis.net
Konfigurationselement [IIS 7 Einstellungsschema
System.ApplicationHost Abschnitt Gruppe [IIS 7 Einstellungsschema

Hier finden Sie eine Liste der IIS6 -Metabase -> IIS7 XML -Konfigurationszuordnungen hier:

Konvertieren von Metabase -Eigenschaften in Konfigurationseinstellungen [IIS 7

Zum Beispiel in IIS6 der Weg zu einer Website einer Seite /root ist in der gespeichert Path Attribut von IIsWebVirtualDir. dh:

<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="...">

Aber in IIS7 ist es anders gespeichert:

<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>

Wenn Ihr Code jedoch sowohl mit IIS6 als auch mit IIS7 funktionieren muss, können Sie die Kompatibilitätskomponenten des IIS6 -Verwaltungskompatibilität installieren. Auf diese Weise können Sie mit herkömmlichen IIS6 -Metabase -APIs wie ADSI, System.DirectoryServices usw. auf IIS7 -Site -Eigenschaften zugreifen.

In dem ersten Teil dieses Artikels wird erläutert, wie Sie dies unter Vista/Windows7/Windows 2008 installieren:

So installieren Sie ASP.NET 1.1 mit IIS7 auf Vista und Windows 2008 - Siehe Schritt 1

Aktualisieren:

Leider ist C ++ nicht mein starker Punkt. Ich habe jedoch ein Beispiel in C# zusammengestellt, um COM Interop zu untersuchen, um die Verwendung der zu demonstrieren 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;
}

Der obige Code findet eine Site namens "mySite" in der <sites> Sammlung. Es holt dann die Website der Site ab <bindings> Sammlung und Druckbindungen von Drucken protocol und bindingInformation Attribute.

Sie sollten in der Lage sein, dies ziemlich leicht in C ++ umzuwandeln.

Um die Frage in Ihrem Kommentar zu beantworten -

Zum Beispiel bringt mich das Path System. Gibt es eine absolute Möglichkeit, zu meinen Serverbindungen wie dieser zu gelangen (z.

Bei Verwendung der AppHostWritableAdminManager Es gibt keine Abkürzung, direkt zu der Website zu gelangen, die Sie inspizieren/ändern möchten, oder die Eigenschaften. Im obigen Beispiel werden Sie feststellen, dass ich durch die Websites -Sammlung gehen muss, um die Website zu finden, an der ich interessiert bin. Der Grund dafür ist das AppHostWritableAdminManager sieht alles als Elemente und Sammlungen von Elementen. Es ist eine ziemlich einfache API. Auch wenn die verwaltete Verwendung verwendet Microsoft.Web.Administration API finden Sie, dass es zwar einige schöne Eigenschaften gibt, z. Site.Bindings, Diese sind dünn getarnte Wrapper herum AppHostWritableAdminManager.

In der Tat, wenn ich eine Seite finden möchte, muss ich immer noch die suchen Sites Sammeln Sie entweder in A for Loop oder durch Hinzufügen von Linq -Zucker, wenn ich C#3.5 oder höher verwende:

using(ServerManager serverManager = new ServerManager())
{
    Site x = serverManager.Sites.FirstOrDefault(s => s.Name == "MySite");
}

SiteDie Basisklasse ist ConfigurationElement welche unter der Motorhaube Zugriff auf den Zugriff auf IAppHostElement.

Sobald Sie einige grundlegende Verknüpfungswrapper -Eigenschaften hinter sich haben, was wir im verwalteten Code tun, um IIS zu konfigurieren (z. B. IIS FTP), sind Elemente, Attribute und Elementsammlungen.

Update 2:

Bitte denken Sie daran, dass ich in meinem Leben noch nie eine Reihe von C ++ geschrieben habe. Es gibt keine Bereinigung von Strings oder Objekten:

#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;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top