|
|
Comments and Discussions
|
|
 |

|
IIS 7.5 installed on Windows 7 x64. the code always states that iis is not installed
|
|
|
|

|
any update for .net 4.0 ??
/// <summary>
/// .NET Framework 3.0
/// </summary>
Fx30,
/// <summary>
/// .NET Framework 3.5 (Orcas)
/// </summary>
Fx35,
...
AE
|
|
|
|

|
any updates for Windows 2008, Windows 2008 R2, Windows 7 ??
IIS Version Operating Systems Account
IIS 5, IIS 5.1
Windows 2000, Windows XP
localmachine\ASPNET
IIS 6, IIS 7
Windows 2003, Windows Vista, Windows Server 2008
localmachine\Network Service
IIS 7.5
Windows 2008 R2, Windows 7
IIS AppPool\
AE
|
|
|
|

|
Hi Scott. Excellent article! And written in a clear and understandable language. One thing though. I can see in my registry, that I have the key HKLM\Software\Microsoft\ASP.NET\2.0.50727.0. But I don't have IIS installed. I don't think it can be used to check whether ASP.NET is registered with IIS. We could say that you first check for IIS installed and then check for the key, but what if the framework was installed before IIS? Then the key would have been written and still ASP.NET would not be registered with IIS.
|
|
|
|

|
You are not alone, my friend!
I have been struggling with this one for yonks. We supply ASP.NET s/w, and half the time end-user-customer does have ASP.NET installed, then installs IIS, then wonders why our application just produces HTML-looking output page
So we need an installation-time programmatic way to at least see whether ASP.NET is registered with IIS, and do something about, even if just to advise they run aspnet_regiis -i or similar.
I have still not found how to do this myself, and came across your post in this thread. I doubt though that we will get an answer in a thread that is so old. Please let me know if you do discover how; I'll do same....
|
|
|
|

|
I will. In the meantime I actually just do the aspnet_regiis -i, without asking my users. I do this from my installer and it takes a few seconds, but rather that than missing it. It works whether or not ASP.NET was already registered. Do you know if there are any drawbacks from just calling it?
|
|
|
|

|
Oh dear, yes there are drawbacks, you should be very careful...
Basically, 2 areas:
* aspnet_regiis -i on its own changes all IIS ASP.NET apps to be registered with this version of ASP.NET. If they do have any existing 1.1 ASP.NET apps, they get reregisterd, and likely broken (situation better than used to be, ASP.NET 2 knows not to re-register later versions, but still...) I believe you are supposed to use -s ... argument to register just your app, that would be better, you should look into that.
* On production server, apparently this will/is likely to re-cycle all running ASP.NET apps and break existing on-line users. Recommendation never to do this while running.
If you search around web for aspnet_regiis -i you will find 95% of articles (including from MS) saying just do it, and 5% of articles from good people in the know who warn about above.
Our problem is many of our "users" are evaluators on a non-server-OS like XP, standalone. For them it might be OK. But I would not dare distribute code that did this: for the real server users it is far too dangerous. Nor would I want to do it unconditionally. At minimum maybe you should confirm with your installer that the user wants you to go ahead. I want code to check whether it (seems to) need doing; if I could do that then I would inform installer and offer to run aspnet_regiis -i but await their say-so.
|
|
|
|

|
Well, if you/anyone is interested...
I'm sure that the only way to detect whether ASP.NET registered correctly with IIS is to query IIS itself (e.g. there is no registry entry or file existence instead). You might be able to do this with System.DirectoryServices in Managed Code. For myself it has to be in a very simple (non-managed) C++ program which is my "top-level" SETUP.EXE.
I paste below extract of my code. Tested on Win 2003/XP/Vista. Not saying it couldn't be written better (e.g. I'm lazy with "," parsing), but should give you/anyone the gist. Note that header files come with VC++.
#include <windows.h>
#include <crtdbg.h>
#include <tchar.h>
#include <stdio.h>
#include <CorError.h>
#include <Shlwapi.h>
#include <WinError.h>
#include <initguid.h>
#include <objbase.h>
#include <iads.h>
#include <adshlp.h>
#include <iiisext.h>
#include <iisext_i.c>
[....]
BOOL IisFxProperlyRegistered()
{
BOOL bResult = FALSE;
HRESULT hr;
IADs *pADs = NULL;
try
{
hr = CoInitialize(NULL);
if (FAILED(hr))
throw hr;
hr = ADsGetObject( L"IIS://localhost/W3SVC", IID_IADs, (void **)&pADs );
if (FAILED(hr))
throw hr;
VARIANT varWSERL;
VariantInit( &varWSERL );
hr = pADs->Get( L"WebSvcExtRestrictionList", &varWSERL );
if (FAILED(hr))
throw hr;
SAFEARRAY *psa;
if (! V_ISARRAY(&varWSERL))
throw;
psa = V_ARRAY(&varWSERL);
long uBound;
hr = SafeArrayGetUBound(psa, 1, &uBound);
if (FAILED(hr))
throw hr;
VARIANT varWSERLElm;
VariantInit( &varWSERLElm );
for (long i = 0; i <= uBound; i++)
{
hr = SafeArrayGetElement(psa, &i, &varWSERLElm);
if (FAILED(hr))
continue;
if (V_VT(&varWSERLElm) == VT_BSTR)
{
TCHAR szStr[1000];
LPTSTR pNextTok;
LPTSTR pTokens[5];
wcstombs(szStr, V_BSTR(&varWSERLElm), 1000);
for (int i = 0; i < 5; i++)
pTokens[i] = strtok_s((i == 0) ? szStr : NULL, _T(","), &pNextTok);
BOOL bEnabled = (pTokens[0] != NULL && pTokens[0][0] == _T('1'));
BOOL bIsAspNet = (pTokens[1] != NULL && StrStrI(pTokens[1], _T("aspnet_isapi.dll")) != NULL);
if (bIsAspNet && bEnabled)
bResult = TRUE;
}
VariantClear( &varWSERLElm );
}
}
catch( ... )
{
}
if (pADs != NULL)
pADs->Release();
CoUninitialize();
return bResult;
}
|
|
|
|
|

|
Yes, this is COM/Unmanaged, using "ADSI" calls. I (now) realise this is supposed to be a Mananged Code thread! I don't know where you are putting your test, but for me this is in my installation "bootstrapper" --- I do not assume they even have .NET Framework installed (bootstrapper will offer to install that, among others), so I certainly can't use Managed at this stage!
I see the original guy has written:
>>Since this is a managed code solution, it does require that a version of the .NET Framework is already
>>installed, so this class is not guaranteed to work as part of an installation process. If you need to do
>>this reliably from an installation process, you need to look at doing the same work using unmanaged C++.
For Managed, (I believe) you can use System.DirectoryServices. You will open "IIS://localhost/W3SVC" level, like I do. The vital point is that there you need to read the "WebSvcExtRestrictionList" Property. That will give you an array of strings for each Web Service Extension installed; you need to parse it (comma-separated) and look at the tokens for each one. It is my belief that this is the only way to correctly determine whether ASP.NET registered & enabled in IIS --- effectively, it will be what IIS itself does.
modified on Thursday, August 21, 2008 3:38 AM
|
|
|
|

|
Thanks for the info, I will look into that. Btw, what installer are you using? If installing a program that depends upon .NET, wouldn't it be fine to actually use .NET in the installer? We do that here, and our installer downloads and installs the .NET framework first if it is missing.
|
|
|
|

|
Our actual application is installed as a standard (web application) .msi, generated from VS 2005. However, I have a C++ "setup.exe" wrapper at the top-level: this checks/offers to install all sorts of other things that are needed, such as .NET Framework, MDAC, SQL Express etc., as well as our own stuff. It is at this top-level that I wish to detect the IIS/ASP.NET situation. If my function returns that it is not properly registered, I inform user of the situation and offer to run aspnet_regiis.exe -i for them, but allow them to do it themselves outside if they want (as per my earlier comment).
P.S.
It doesn't execute the check till after they have installed .NET Fx, if selected. Don't forget there is no point you executing this code till Fx is installed. So you could go for Managed Code at that point. For me, I can't be bothered to write a separate Mananged installation app for after I know Fx is there, I just do it in my unmanaged C++ wrapper program.
|
|
|
|

|
JonB, thanks for coming up with a solution for this. If I find some time I will convert your C++ code to C# and incorporate it into the article.
Scott Dorman Microsoft® MVP - Visual C# | MCPD
President - Tampa Bay IASA
[ Blog][ Articles][ Forum Guidelines] Hey, hey, hey. Don't be mean. We don't have to be mean because, remember, no matter where you go, there you are. - Buckaroo Banzai
|
|
|
|

|
Thanks and sorry for the delay in responding. Looking through the thread for this message it sounds like JonB was able to come up with a solution that would work but is in C++. I will try to find some time to review his solution and turn it in to managed code to include in the article.
Scott Dorman Microsoft® MVP - Visual C# | MCPD
President - Tampa Bay IASA
[ Blog][ Articles][ Forum Guidelines] Hey, hey, hey. Don't be mean. We don't have to be mean because, remember, no matter where you go, there you are. - Buckaroo Banzai
|
|
|
|

|
Hi, JonB is back!
I thought I had this knocked on the head. Now I discover that if I (or rather, some of my end-user-installer) have:
* IIS 7/Vista; AND...
* ... IIS 6/Metabase "compatibility" *not* enabled/installed (as Windows feature)
it all blows up You cannot then communicate with IIS via metabase/ADSI at all, so the principle breaks.
Now, I might be talking out of my hat, but my (limited) understanding is that IIS 7 has a whole new interface with no ADSI. Correct me if I'm wrong, but a .NET managed solution will use "DirectoryServices" calls which will actually use *WMI* to communicate with IIS 7(?).
And when I looked at that level of stuff originally I rejected it (as an unmanaged solution) because:
a) The code looked much nastier than my "ADsGetObject"-scripting-type approach; and
b) Posts were saying "you can't rely on WMI being installed/enabled, it isn't on some systems"
So..... I don't suppose you know what direction to point me in for this last piece of the jigsaw? (Please do say if my understanding above is incorrect.)
|
|
|
|

|
JonB,
You are correct. Using ADSI to talk to IIS7 will only work if IIS6 compatability is enabled. The other options are to use WMI (which IIS7 has a specific WMI provider) or the classes in the Microsoft.Web.Administration namespace (which is part of a .NET API that ships with IIS7). You can get more information about either of these here[^]. I haven't looked at any of this in detail yet so I don't know how easy/hard it will be. I'll try and find out if the Microsoft.Web.Administration assembly (or assemblies) are redistributable outside of IIS and, if so, incorporate them into the code.
If you manage to get a working solution, please let me know and I'll incorporate it as well, giving you appropriate credit of course.
Thanks,
Scott.
Scott Dorman Microsoft® MVP - Visual C# | MCPD
President - Tampa Bay IASA
[ Blog][ Articles][ Forum Guidelines] Hey, hey, hey. Don't be mean. We don't have to be mean because, remember, no matter where you go, there you are. - Buckaroo Banzai
|
|
|
|
|

|
Hi,
Your article was indeed extremely useful.
Moving one step further, I am trying to find a way to detect if the subcomponents that are installed are enabled for execution by IIS.
This is because the component may be installed but not enabled (which if by reading the value from registry will not be accurate).
What's your advice on going about to perform this check?
Thanks in advance for making the time to reply
B@mB@m
|
|
|
|

|
Sorry for the delay in responding to this. I believe the best way to determine if a component is actually enabled is to use ADSI calls. If I get some free time I will try to look in to adding this support to the article.
Scott Dorman Microsoft® MVP - Visual C# | MCPD
President - Tampa Bay IASA
[ Blog][ Articles][ Forum Guidelines] Hey, hey, hey. Don't be mean. We don't have to be mean because, remember, no matter where you go, there you are. - Buckaroo Banzai
|
|
|
|
|

|
What does this have to do with the article?
Following your link does take you to your blog entry that shows how to do this in an MSI using WiX, but it would have been much clearer had you actually said that in your message rather than just posting the link. In either case, this article isn't about how to detect if IIS is installed through an installer, although that is one thing that it could be used for. The article presents a way to detect if IIS is installed that can be used anywhere, including other applications.
|
|
|
|

|
There were a few minor updates in the FrameworkVersionDetection class due to a registry change between the January 2007 CTP and Beta 2 of the .NET Framework v3.5, so the download for this article has been updated.
|
|
|
|

|
That one's pretty cool, all about IIS in one article.
Are you from systems engineering ?
Regards,
h.
|
|
|
|

|
Thanks, glad you liked it.
Not sure what you mean by "systems engineering", since it tends to have a pretty open meaning. I am a developer now, but I did start my career as a systems administrator (mostly on Unix systems). I actually ended up writing this article based on feedback I received on my article about detecting what versions of the .NET Framework are installed.
|
|
|
|

|
Do you know how to determine if IIS 6.0 compatibility mode is turned on in Vista?
Specifically I am looking to programatically determine the following:
1. IIS 6 Scripting Tools
2. IIS 6 WMI Compatibility
3. IIS Metabase and IIS 6 configuration compatibility.
TIA,
Razi
|
|
|
|
 |
|
|
General News Suggestion Question Bug Answer Joke Rant Admin
|
Explains how to use managed code to detect which version of Internet Information Services (IIS) is installed and if ASP or ASP.NET is registered.
| Type | Article |
| Licence | CPOL |
| First Posted | 6 Apr 2007 |
| Views | 77,606 |
| Downloads | 1,169 |
| Bookmarked | 71 times |
|
|