# Programmatically add an ISAPI extension dll in IIS 7 using ADSI?

I'm trying to programmatically add an ISAPI extension dll in IIS using ADSI. This has been working for ages on previous versions of IIS, but it seems to fail on IIS 7.

I am using similar code like shown in this question:

var web = GetObject("IIS://localhost/W3SVC/1/ROOT/specificVirtualDirectory");
var maps = web.ScriptMaps.toArray();
map[maps.length] = ".aaa,c:\\path\\to\\isapi\\extension.dll,1,GET,POST";
web.ScriptMaps = maps.asDictionary();
web.SetInfo();


After executing that code, I do see an "AboMapperCustom-12345678" entry for that specific dll in the "Handler mappings" of the specific virtual directory in which I added the script map. But when I try to use that extension in a browser, I always get

The page you are requesting cannot be served because of the ISAPI and CGI Restriction list settings on the Web server.

Even after adding an entry to allow that specific dll in the "ISAPI and CGI restrictions", I keep getting that error.

To make it actually work, I first have to undo these steps (encountering the same issue like the OP of the question mentioned above: after deleting the script map entry from the IIS manager GUI, I also have to programmatically delete it using ADSI before it's actually gone from the metabase).

And then manually add an entry like this:

• inetmgr -> webserver -> website -> virtual directory -> handler mappings -> add script map...
• path = *.dll, executable = <path to dll>, name = <doesn't matter, but it's mandatory>
• click "yes" on the question "do you want to allow this ISAPI extension?"

When I compare the 2 entries, they are exactly the same, except for the "Entry Type" which seems to be "Inherited" for the programmatically added one and "Local" for the one added manually.

The strange thing is, even though it says "Inherited", I don't see it anywhere in IIS on a higher level. Where is it inheriting from?

In my code, I do add the script map to the specific virtual directory so it should be "Local" as well. Maybe there is the problem, but I don't know how to add a "Local" Script Map using ADSI.

I really would like to keep using the ADSI method, as otherwise I will have to use different methods in our setup when working with IIS 7 or previous versions, and I would like to avoid that.

To recap: How can I programmatically add a script map entry and its companion CGI and ISAPI restrictions entry to IIS 7 using ADSI?

Anybody who can shed some light on this? Any help appreciated.

-

IIS7 isn't out of the box 100% compatible with the Metabase structure of previous versions, you need to enable it. In the "role services" for IIS, make sure you have "IIS6 Metabase Compatibility" enabled.

http://learn.iis.net/page.aspx/125/metabase-compatibility-with-iis-7
http://learn.iis.net/page.aspx/126/how-to-use-metabase-compatibility-with-iis-7

With that being said, I've found that ADSI and Metabase compatibility don't seem to be 100% reliable. A much better solution would be to retool your script to use appcmd.exe. The command would be something like:

appcmd set config /section:handlers /+[name='MyIsapiExtension',path='*.aaa',verb='GET,POST',scriptProcessor='c:\path\to\extension.dll']


http://technet.microsoft.com/en-us/library/cc754147(WS.10).aspx

-
Yes, I know about the IIS 6 Metabase Compatibility. It is enabled. I could use the appcmd way, but then I would have to keep the ADSI way for backwards compatibility, and add an extra check and code in the setup script. I was wondering if there was a way to avoid that (as stated in the question). –  fretje Apr 21 '10 at 17:15
Also: my question is about an isapi extension, not an isapi filter (which your last link links to). –  fretje Apr 26 '10 at 7:42
@fretje: sorry about that, I edited my answer to make it a handler mapping instead of a filter. –  MattB Apr 26 '10 at 18:56
Thanks, almost got it to work with this. Check my answer for the juicy details ;-) –  fretje Apr 27 '10 at 9:07

I eventually solved this the way I was trying to avoid, using appcmd. But to add to @MattB's answer, I needed to add an extra parameter modules='IsapiModule' to make it actually work:

appcmd set config 'website/virtualdir' /section:handlers /+[name='a name',path='*.dll',verb='*',scriptProcessor='path\to\webisapi.dll',modules='IsapiModule']


And I also had to add an entry to the "ISAPI and CGI restrictions" section:

appcmd set config /section:isapiCgiRestriction /+[path='path\to\isapi.dll', description='a description',allowed='True']


I check the existence of %windir%\system32\inetsrv\appcmd.exe to determine which way to use. If it exists, I use appcmd, if it doesn't, I fall back to ADSI.

Still interested in a pure ADSI way though!

-