Domanda

Ho un C ++ applicazione che ha bisogno di recuperare un IIS 7 proprietà del sito (ad esempio le proprietà della metabase simili a quelle in IIS6 - Path, AppFriendlyName ecc).

Con IIS 7, il mio codice fa questo:

  1. Prendi il AppHostWritableAdminManager e commettere il MACHINE/WEBROOT/APPHOST/Default Web Site/ percorso.
  2. GetAdminSection chiamata con il nome della sezione appSettings.
  3. Poi cerca nella collezione restituita e il look per la proprietà (Path per esempio).

Questo funziona in IIS 6, ma non su IIS7 / 7.5.

Quali cambiamenti cosa devo fare per fare questo lavoro?

È stato utile?

Soluzione

in IIS7 i dati di configurazione non vengono memorizzati in un "metabase" e anche le proprietà della metabase che siamo abituati in IIS6 non sono gli stessi. IIS7 memorizza la maggior parte dei suoi dati di configurazione nel seguente file:

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

Ci sono altri file, ma ai fini di rispondere a questa domanda, questo è il file che ci interessa.

La documentazione di applicationHost.config può essere trovato qui:

<system.applicationHost> - IIS.NET
configuration Element [IIS 7 Impostazioni Schema]
system.applicationHost Sezione Gruppo [IIS 7 Impostazioni Schema]

È possibile trovare un elenco di IIS6 metabase -> IIS7 mappature di configurazione XML qui:

Conversione proprietà della metabase di impostazioni di configurazione [IIS 7 ]

Ad esempio in IIS6 il percorso di /root di un sito viene memorizzato nell'attributo Path di IIsWebVirtualDir. cioè:.

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

Ma in IIS7 è memorizzato in modo diverso:

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

Tuttavia, se il codice deve lavorare sia con IIS6 e IIS7 quindi è possibile installare i componenti di gestione IIS6 compatibilità. Questo vi permetterà di proprietà del sito l'accesso IIS7 usando tradizionale ad esempio ADSI, System.DirectoryServices ecc Il livello di compatibilità mapperà queste proprietà al nuovo schema di IIS7 per voi.

API IIS6 metabase

La prima parte di questo articolo spiega come installare questo su Vista / Windows7 / Windows 2008:

Come installare ASP.NET 1.1 con IIS7 su Vista e Windows 2008 - vedere il passo # 1

Aggiornamento:

Purtroppo C ++ non è il mio punto di forza. Tuttavia ho messo insieme un esempio in C # utilizzando COM Interop per dimostrare utilizzando il 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;
}

Il codice sopra individua un sito denominato "MySite" nella raccolta <sites>. E poi recupera collezione <bindings> del sito e la stampa di ogni binding protocol e attributi bindingInformation.

Il tuo dovrebbe essere in grado di convertire questo in C ++ abbastanza facilmente.

Per rispondere alla domanda nel tuo commento -

Per esempio, il percorso system.applicationHost siti / otterrà Mi all'elenco dei siti. C'è un modo assoluto per arrivare al mio server binding come questa (ad esempio mediante fare system.applicationHost / sites / default Sito Web / Associazioni

Quando si utilizza il AppHostWritableAdminManager non c'è una scorciatoia per ottenere direttamente al sito che si desidera esaminare / modificare o le sue proprietà. Nell'esempio di cui sopra, vedrete che ho bisogno di collegare attraverso la raccolta siti per trovare il sito che mi interessa. La ragione di questo è che AppHostWritableAdminManager vede tutto come elementi e raccolte di elementi. Si tratta di un'API abbastanza semplice. Anche quando si utilizza l'API Microsoft.Web.Administration gestito si scopre che mentre ci sono alcune interessanti proprietà quali Site.Bindings, questi sono sottili involucri attorno AppHostWritableAdminManager mascherati.

In realtà, se voglio trovare un sito devo ancora cercare la collezione Sites sia in un ciclo for o con l'aggiunta di un po 'di zucchero LINQ se sto usando C # 3.5 o versione successiva:

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

classe di base del Site è ConfigurationElement che sotto il cofano avvolge l'accesso a IAppHostElement.

Una volta che sei passato un po 'di scelta rapida di base involucro proprietà molto di quello che facciamo in codice gestito Per configurare IIS (ad esempio IIS FTP) è elementi, attributi e collezioni di elementi.

Aggiornamento 2:

Si prega di tenere a mente non ho mai scritto una riga di C ++ nella mia vita. Non c'è pulizia di stringhe o oggetti:

#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;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top