Obtenir IIS 7 propriétés du site
-
16-10-2019 - |
Question
J'ai une application C ++ qui a besoin de récupérer un IIS 7 propriétés du site (telles que les propriétés de métabase similaires à ceux IIS6 - Path
, AppFriendlyName
etc).
Avec IIS 7, mon code fait ceci:
- Obtenez le
AppHostWritableAdminManager
et engager le cheminMACHINE/WEBROOT/APPHOST/Default Web Site/
. - Appel
GetAdminSection
avec leappSettings
de nom de la section. - Ensuite, regardez la collection retournée et recherchez la propriété (
Path
par exemple).
Cela fonctionne dans IIS 6 mais pas sur IIS7 / 7.5.
Quels changements dois-je faire pour faire ce travail?
La solution
Dans IIS7 les données de configuration ne sont pas stockées dans un « métabase » et aussi les propriétés de la métabase que nous sommes habitués dans IIS6 ne sont pas les mêmes. IIS7 stocke la majeure partie de ses données de configuration dans le fichier suivant:
%systemroot%\System32\InetSrv\Config\applicationHost.config
Il existe d'autres fichiers, mais aux fins de répondre à cette question, c'est le fichier qui nous intéresse.
La documentation applicationHost.config
se trouve ici:
<system.applicationHost>
- IIS.NET
configuration élément [IIS 7 Schéma des paramètres]
system.applicationHost Section Groupe [IIS 7 Schéma des paramètres]
Vous pouvez trouver une liste de IIS6 métabase -> IIS7 applications de configuration XML ici:
Conversion des propriétés métabase des paramètres de configuration [IIS 7 ]
Par exemple, dans IIS6 le chemin vers le /root
d'un site est stocké dans l'attribut Path
de IIsWebVirtualDir
. i.e.:.
<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="...">
Mais dans IIS7 il est stocké différemment:
<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>
Cependant, si votre code doit travailler avec les deux IIS6 et IIS7 alors vous pouvez installer les composants Compatibilité avec la gestion IIS6. Cela vous permettra d'accéder aux propriétés du site IIS7 à l'aide de l'API traditionnelle IIS6 métabase tels que ADSI, System.DirectoryServices etc. La couche de compatibilité carte ces propriétés au nouveau schéma IIS7 pour vous.
La première partie de cet article explique comment installer sur Vista / Windows7 / Windows 2008:
Comment installer ASP.NET 1.1 avec IIS7 sur Vista et Windows 2008 - voir l'étape 1
Mise à jour:
Malheureusement C ++ n'est pas mon point fort. Cependant, je mets ensemble un exemple en C # en utilisant COM Interop pour démontrer à l'aide du 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;
}
Le code ci-dessus localise un site nommé "MySite" dans la collection <sites>
. Il récupère ensuite la collection de <bindings>
du site et l'impression de chaque liaisons protocol
et les attributs de bindingInformation
.
Votre devrait être en mesure de convertir en C ++ assez facilement.
Pour répondre à la question dans votre commentaire -
Par exemple, le chemin system.applicationHost / sites créés seront moi à la liste des sites. Y'a-t-il un manière absolue pour arriver à mon serveur fixations comme celle-ci (par exemple par Faire system.applicationHost / Sites / Default Site Web / Liaisons
Lorsque vous utilisez le AppHostWritableAdminManager
il n'y a pas un raccourci pour obtenir directement sur le site que vous souhaitez vérifier / modifier ou propriétés de elle. Dans l'exemple ci-dessus, vous verrez que je dois parcourir la collection de sites pour trouver le site que je suis intéressé. La raison est que AppHostWritableAdminManager
voit tout comme des éléments et des collections d'éléments. Il est une API assez basique. Même lorsque vous utilisez l'API géré Microsoft.Web.Administration
vous trouvez que si il y a des belles propriétés telles que Site.Bindings
, ceux-ci sont des emballages à peine voilés autour AppHostWritableAdminManager
.
En fait, si je veux trouver un site que je dois encore chercher la collection Sites
soit dans une boucle ou en ajoutant un peu de sucre LINQ si j'utilise C # 3.5 ou version ultérieure:
using(ServerManager serverManager = new ServerManager())
{
Site x = serverManager.Sites.FirstOrDefault(s => s.Name == "MySite");
}
La classe de base de Site
est ConfigurationElement
qui sous le capot enveloppe accès à IAppHostElement
.
Une fois que vous avez passé un certain wrapper propriétés raccourci de base une grande partie de ce que nous faisons dans le code managé à configurer IIS (par exemple IIS FTP) est éléments, les attributs et les collections d'éléments.
Mise à jour 2:
S'il vous plaît gardez à l'esprit que je ne l'ai jamais écrit une ligne de C ++ dans ma vie. Il n'y a pas de nettoyage des chaînes ou des objets:
#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;
}