0

I am writing a small app that installs IIS and configures a website before deploying the files to it. On a freshly reset Windows 10, the first attempt always fails with the 0x80040154 COM+ component failure as documented in This question

I looked at the version I am using and it is the latest and correct one for .net standard (4.8) and not the one meant for .net core

When I press the button to rerun the function it always finishes correctly. I tried using a retry routine, and it fails on each retry, yet runs fine again when the button is pressed. The reason for this I assume is that the server manager object isn't disposed when it hits the catch block since its in a using statement.

I can work around that, but I really want to understand the issue and make a permanent fix.

My routine simply creates a website in IIS and creates an app pool to assign to it.

And it is running with elevated privileges

For reference: Machine is Windows 10 latest from the downloadable media creator. Microsoft.Web.Administrator version is 7.0.0.0 App is .net 4.8 standard windows forms

using (var serverManager = new ServerManager())
{
    string iisrootdir = drive;
    //Check for inetpub/wwwroot
    if (!Directory.Exists(iisrootdir)) //Check for Drive D
    {
        iisrootdir = @"C:\";
    }

    string iiscmsdir = Path.Combine(iisrootdir, "webdir", "appdir");

    if (!Directory.Exists(iiscmsdir))
        Directory.CreateDirectory(iiscmsdir);

    var settings = new ApplicationSettings();
    settings.ReadFromFile();
    settings.CMSPATH = iiscmsdir;
    settings.SaveToFile();

    try
    {
        string poolName = "DefaultAppPool";

        if (serverManager.Sites.Count > 0)
        {
            Site myDefualtWebsite = serverManager.Sites[0];
            if (myDefualtWebsite != null)
            {
                OnRaiseInstallEvent(new InstallEventArgs("CreateWebsite", ProcessState.Started,
                    "Remove Default Website"));
                serverManager.Sites.Remove(myDefualtWebsite);
                serverManager.CommitChanges();
            }
        }

        if (!WebsiteExists("sitename"))
        {
            mySite.ServerAutoStart = true;
        }

        Site site = serverManager.Sites["sitename"];
        
        if (!AppPoolExists(poolName))
        {
            serverManager.ApplicationPools.Add(poolName);
        }
        
        ApplicationPool apppool = serverManager.ApplicationPools[poolName];
        apppool.ManagedPipelineMode = ManagedPipelineMode.Integrated;

        apppool.ManagedRuntimeVersion = "";
        serverManager.Sites["sitename"].ApplicationDefaults.ApplicationPoolName = poolName;
        foreach (var item in serverManager.Sites["sitename"].Applications)
        {
            item.ApplicationPoolName = poolName;
        }

        serverManager.CommitChanges();
        apppool.Recycle();
        serverManager.CommitChanges();
    }
    catch (Exception ex)
    {
        if (ex.Message.Contains("80040154") && errorCount < 4)
        {
            if (serverManager != null)
                serverManager.Dispose();
            errorCount++;
            OnRaiseInstallEvent(new InstallEventArgs("CreateWebsite", ProcessState.Started,
                "Error encountered with COM+ object, trying again: " + errorCount));
            CreateWebsite(@"D:\");
        }
        else
        {
            if (serverManager != null)
                serverManager.Dispose();
            errorCount = 0;
            OnRaiseErrorEvent(new InstallErrorEventArgs("CreateWebsite", ProcessState.Error, ex));
            return false;
        }
    }
    finally
    {
        serverManager?.Dispose();
    }
john scott
  • 11
  • 2
  • Are you using any resources on IIS like files or registry? Is app running AsAdmin? You have little access to the IIS resource unless app is running AsAdmin. – jdweng Nov 02 '20 at 09:36
  • Hi jdweng, yes, app is running as admin. Nothing in registry. No files either. At this stage I simply create the folder, remove the default website, create a new website and app pool. – john scott Nov 02 '20 at 09:55
  • Are you running from VS? VS does not automatically go into AdMin mode unless you right click shortcut and select Run AsAdmin. Can you manually delete the file? – jdweng Nov 02 '20 at 10:33
  • No this is testing of the application on a clean target machine. It doesn't fail when i test on my dev machine. Well, there's no file to delete. My application first uses DISM to install IIS then it runs the above code to configure it – john scott Nov 02 '20 at 10:51
  • Can you better isolate the issue? Could failure be due to first time running or a missing folder? – jdweng Nov 02 '20 at 14:18
  • From where did you get the Microsoft.Web.Administration reference? https://blog.lextudio.com/whats-microsoft-web-administration-and-the-horrible-facts-you-should-know-b82f2c974da6 – Lex Li Nov 02 '20 at 16:11
  • I will attempt to better isolate the issue, and figure out which specific call is causing the exception. – john scott Nov 03 '20 at 05:42
  • The Microsoft.Web.Administration was in the Add References section in the IDE. Its part of .net 4.8 afaik – john scott Nov 03 '20 at 05:43

1 Answers1

0

Thanks for the help Guys. I found the problem.

DISM was running in its own thread. The Process object exited the moment it launched. My function was then attempting to configure IIS before it had finished installing.

john scott
  • 11
  • 2