Jump to content
Mark Williams

Manipulating IIS with the Application Host Administration Interface - OLE issues

Recommended Posts

I cannot understand why the following code does not work:

 

function IsOleObjectActive(OleObject: OleVariant): Boolean;
begin
  Result := not VarIsClear(OleObject) and not VarIsEmpty(OleObject) and not VarIsNull(OleObject);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  ServerManager: OleVariant;
  Site: OleVariant;
  AppPool: OleVariant;
  Security: OleVariant;
begin
  // Initialize COM library
  CoInitialize(nil);
  try
    // Create an instance of the ServerManager object
    ServerManager := CreateOleObject
      ('Microsoft.ApplicationHost.WritableAdminManager');

    ServerManager.CommitPath := 'MACHINE/WEBROOT/APPHOST';

    // Add a new site
    Site := ServerManager.GetAdminSection('system.applicationHost/sites',
      'MACHINE/WEBROOT/APPHOST');

-    if IsOleObjectActive(Site) then
      Showmessage('Active')
	 else
		exit;

    Site := Site.Collection.AddElement('site'); //FAILS HERE
    
	Site.Properties.Item('name').Value := trim(eSiteName.text);
    
    // Site.Properties.Item('id').Value := 2;
    Site.Properties.Item('physicalPath').Value := 'C:\inetpub\wwwroot\' + trim(ePhysicalPath.text);
    
    // Configure bindings
    Site.Bindings.Collection.AddElement('binding');
    Site.Bindings.Collection.Item(0).Properties.Item('protocol').Value
      := 'http';
    Site.Bindings.Collection.Item(0).Properties.Item('bindingInformation').Value
      := '*:80';

   
    Site.Bindings.Collection.AddElement('binding');
    Site.Bindings.Collection.Item(1).Properties.Item('protocol').Value
      := 'https';
    Site.Bindings.Collection.Item(1).Properties.Item('bindingInformation').Value
      := '*:443';
    
    // Add an application pool
    AppPool := ServerManager.GetAdminSection
      ('system.applicationHost/applicationPools', 'MACHINE/WEBROOT/APPHOST');
    AppPool := AppPool.Collection.AddElement('add');
  	AppPool.Properties.Item('name').Value := trim(eSiteName.text);
    AppPool.Properties.Item('managedRuntimeVersion').Value :=
      trim(eNetFramework.text);

    // Assign the application pool to the site
    Site.Applications.Collection.Item(0).Properties.Item('applicationPool')
      .Value := trim(eSiteName.text);
    
    // Commit the changes
    ServerManager.CommitChanges;
  finally
    // Uninitialize COM library
    CoUninitialize;
  end;

When I try to add the new site I get "Variant does not reference an automation object." 

 

I've tried adding the application pool first, but same problem.

 

As far as I can see the section names are correct as per the applicationHost.config file and all functions, properties are correct as per the nativerd.dll.

 

I've also tried running the app in elevated mode. Makes no difference.

Edited by Mark Williams

Share this post


Link to post

Try

Result := not (VarIsClear(OleObject) or VarIsEmpty(OleObject) or VarIsNull(OleObject)) and (VarType(OleObject) = VT_DISPATCH);

 

Share this post


Link to post

There is a type library you can import - would save a lot of casting C:\Windows\System32\inetsrv\nativerd.dll

 

It's a pretty awful api to work with, it's been a while since I looked at it - Microsoft created a pretty extensive dotnet wrapper for it - https://www.nuget.org/packages/Microsoft.Web.Administration you could download the nuget package and use Ilspy to have a look at it - might help

  • Thanks 1

Share this post


Link to post
On 1/6/2025 at 12:06 PM, PeterBelow said:

Try


Result := not (VarIsClear(OleObject) or VarIsEmpty(OleObject) or VarIsNull(OleObject)) and (VarType(OleObject) = VT_DISPATCH);

 

Same result. It reports true for Server Manager, but then fails with the variant does not reference... error on the call to ServerManager.GetAdminSection.

Share this post


Link to post
14 hours ago, Vincent Parrett said:

There is a type library you can import - would save a lot of casting C:\Windows\System32\inetsrv\nativerd.dll

 

It's a pretty awful api to work with, it's been a while since I looked at it - Microsoft created a pretty extensive dotnet wrapper for it - https://www.nuget.org/packages/Microsoft.Web.Administration you could download the nuget package and use Ilspy to have a look at it - might help

I had started to go down this route. I'm using the 64 bit type library, which is even more of a pain to use. It does seem to work however. Thanks for the reference to the dotnet wrapper.

Share this post


Link to post
11 hours ago, Mark Williams said:

Same result. It reports true for Server Manager, but then fails with the variant does not reference... error on the call to ServerManager.GetAdminSection.

Looks like the GetAdminSection function does not return an automation-compatible interface. Can you check what VarType the returned OleVariant has?

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×