locked
AppPool.Invoke() always returns null RRS feed

  • Question

  • Hi.

    I have some code I wrote to stop and start and app pool on a remote machine.  The code works but the action that actually stops or starts the app pool always returns null, so I cannot evaluate the return value.

    The code is as follows:

                try
                {
                    DirectoryEntry appPools = new DirectoryEntry("IIS://" + targetMachine + "/w3svc/apppools", svcDomain+ @"\" + svcServiceID, svcPassword);
                    foreach (DirectoryEntry AppPool in appPools.Children)
                    {
                        if (appPoolName.Equals(AppPool.Name, StringComparison.OrdinalIgnoreCase))
                        {
                            object OutParam = AppPool.Invoke(appPoolAction, null);
    
                            if (appPoolName == "Stop")
                                Console.WriteLine("The " + appPoolName + " app pool has been stopped.");
                            else
                                Console.WriteLine("The " + appPoolName + " app pool has been started.");
                            break;
                        }
                    }
                    appPools = null;
                    System.Threading.Thread.Sleep(10000);
                }
    


    In the above, this line of code:

    object OutParam = AppPool.Invoke(appPoolAction, null);

    always returns null.  I need to examine the value so I can know for sure whether the app pool was stop/started or not, and then process accordingly.

    Does anyone know why I cannot get a return value from the Invoke() call?

    Thanks in advance.

    Logan

    Friday, August 24, 2012 1:19 PM

Answers

  • Yes: the Start and Stop method have no return value. Since the Invoke method must return something, it returns null.
    Wednesday, September 5, 2012 3:16 PM
  • I finally figured out the problem I was having and I wanted to post the code here in case anyone else might have a use for it.  Now I'm able to stop and start an app pool on a remote server and log the events to the event viewer without any problems.

    Thanks everyone for your help!

    namespace StopStartAppPool
    {
        class StopStartAppPool
        {
            private static string svcDomain;
            private static string svcServiceID;
            private static string svcPassword;
            private static string appPoolName;
            private static string targetMachine;
            private static string appPoolAction;
            private static string invalidArg;
    
            static void Main(string[] args)
            {
                // ***** The command line arguments should be as follows: *****//
                // *****       DefaultAppPool stop FLJAX tfsservice 12345pwd VMDEVServer1 *****//
                // *****       DefaultAppPool start FLJAX tfsservice 12345pwd VMDEVServer1 *****//
    
                if (args.Length != 6)
                {
                    Console.WriteLine("Six arguments must be passed for a service to be stopped or started.");
                    Console.WriteLine("(1) the service name to stop or start, (2) 'stop' or 'start', (3) service ID domain, (4), service ID, (5) service ID password, (6) target machine.");
                    Console.WriteLine("No services will be stopped or started.");
                    return;
                }
    
                // ***** If any of the arguments input by the user are invalid, exit the program *****//
                if (!AssignUserInput(args, out invalidArg))
                {
                    Console.WriteLine(invalidArg);
                    return;
                }
    
                // ***** Create EventLog object so the Event Viewer can be updated *****//
                EventLog ev = new EventLog();
                ev = CreateEventLog(appPoolName, targetMachine);
    
                try
                {
                    ConnectionOptions connOptions = new ConnectionOptions(); 
                    connOptions = CreateConnOptions(svcDomain, svcServiceID, svcPassword, targetMachine);
                    ManagementScope ms = new ManagementScope();
                    ms = CreateRemoteConnectionObject(svcDomain, svcServiceID, svcPassword, targetMachine, connOptions);
                    ms.Connect();
    
                    ObjectGetOptions objectGetOptions = new ObjectGetOptions();
                    ManagementPath managementPath = new ManagementPath(@"\\" + targetMachine + @"\ROOT\CIMV2:Win32_Process");
                    ManagementClass processClass = new ManagementClass(ms, managementPath, objectGetOptions);
                    ManagementBaseObject inParams = processClass.GetMethodParameters("Create");
    
    
                    // ***** App pool values are:  1 (starting), 2 (started), 3 (stopping), 4 (stopped), 5 (pausing), 6 (paused), 7 (continuing) *****
                    int appPoolState = GetAppPoolState(appPoolName, targetMachine, connOptions, ms);
    
    
                    if (appPoolAction.ToLower().Contains("start"))
                    {
                        // ***** Only try to start the app pool if it's either in the stopped or paused state *****//
                        if ((appPoolState == 4) || (appPoolState == 6))
                        {
                            inParams["CommandLine"] = @"c:\windows\system32\inetsrv\appcmd.exe start apppool " + appPoolName;
                            ManagementBaseObject outParams = processClass.InvokeMethod("Create", inParams, null);
    
                            // ***** Write results to the event log *****//
                            string tmp = String.Format("The {0} application pool was started on {1} with an exit code of {2}:  ", appPoolName, targetMachine, outParams["returnValue"]);
                            ev.WriteEntry(tmp, EventLogEntryType.Information);
                        }
                        else
                        {
                            // ***** Write no action performed to the event log *****//
                            string tmp = String.Format("The {0} application pool could not be started on {1} becuase it's current state is:  {2}.", appPoolName, targetMachine, GetAppPoolState(appPoolState));
                            ev.WriteEntry(tmp, EventLogEntryType.Information);
                        }
                    }
    
                    if (appPoolAction.ToLower().Contains("stop"))
                    {
                        // ***** Only try to stop the app pool if it's either in the started or paused state *****//
                        if ((appPoolState == 2) || (appPoolState == 6))
                        {
                            inParams["CommandLine"] = @"c:\windows\system32\inetsrv\appcmd.exe stop apppool " + appPoolName;
                            ManagementBaseObject outParams = processClass.InvokeMethod("Create", inParams, null);
    
                            // ***** Write results to the event log *****//
                            string tmp = String.Format("The {0} application pool was stopped on {1} with an exit code of {2}.", appPoolName, targetMachine, outParams["returnValue"]);
                            ev.WriteEntry(tmp, EventLogEntryType.Information);
                        }
                        else
                        {
                            // ***** Write no action performed to the event log *****//
                            string tmp = String.Format("The {1} application pool could not be stopped on {1} becuase it's current state is:  {2}.", appPoolName, targetMachine, GetAppPoolState(appPoolState));
                            ev.WriteEntry(tmp, EventLogEntryType.Information);
                        }
                    }
                }
                catch (Exception ex)
                {
                    string tmp = String.Format("The StopStartAppPool.exe encountered an error and exited with code {0}:     {1}:     {2}:     {3}:     ", ex.Message, ex.Data, ex.InnerException, ex.StackTrace);
                    ev.WriteEntry(tmp, EventLogEntryType.Information);
                    Console.WriteLine(ex.StackTrace);
                    Console.WriteLine(ex.Data);
                    Console.WriteLine(ex.InnerException);
                    Console.WriteLine(ex.Message);
                    Console.WriteLine(ex.Source);
                }
            }
    
            private static int GetAppPoolState(string appPoolName, string targetMachine, ConnectionOptions connOptions, ManagementScope ms)
            {
                try
                {
                    DirectoryEntry appPools = new DirectoryEntry("IIS://" + targetMachine + "/w3svc/apppools", svcDomain + @"\" + svcServiceID, svcPassword);
                    foreach (DirectoryEntry AppPool in appPools.Children)
                    {
                        if (appPoolName.Equals(AppPool.Name, StringComparison.OrdinalIgnoreCase))
                        {
                            // ***** Values are:  1 (starting), 2 (started), 3 (stopping), 4 (stopped), 5 (pausing), 6 (paused), 7 (continuing) *****
                            PropertyCollection appPoolProps = AppPool.Properties;
                            appPoolState = Convert.ToInt32(appPoolProps["AppPoolState"].Value);
                        }
                    }
                }
                catch (ManagementException e)
                {
                } 
                return appPoolState;
            }
    
            private static string GetAppPoolState(int appPoolState)
            {
                // ***** App pool values are:  1 (starting), 2 (started), 3 (stopping), 4 (stopped), 5 (pausing), 6 (paused), 7 (continuing) *****
                switch (appPoolState)
                {
                    case 1:
                        return "Starting";
                    case 2:
                        return "Started";
                    case 3:
                        return "Stopping";
                    case 4:
                        return "Stopped";
                    case 5:
                        return "Pausing";
                    case 6:
                        return "Paused";
                    default:
                        return "Continuing";
                }
            }
    
            private static bool AssignUserInput(string[] args, out string invalidArg)
            {
                if (IsValidAppPoolName(args[0]))
                    appPoolName = args[0];
                else
                {
                    invalidArg = args[0];
                    return false;
                }
    
                if (args[1].ToLower() == "stop")
                    appPoolAction = "stop";
                else
                    appPoolAction = "start";
    
                if (IsValidDomainName(args[2]))
                    svcDomain = args[2];
                else
                {
                    invalidArg = args[2];
                    return false;
                }
    
                if (IsValidServiceID(args[3]))
                    svcServiceID = args[3];
                else
                {
                    invalidArg = args[3];
                    return false;
                }
    
                svcPassword = args[4];
                targetMachine = args[5];
    
                invalidArg = null;
                return true;
            }
    
            private static EventLog CreateEventLog(string svcName, string targetMachine)
            {
                if (!EventLog.SourceExists(svcName, targetMachine))
                {
                    EventSourceCreationData evData = new EventSourceCreationData(svcName, "Application");
                    evData.MachineName = targetMachine;
                    EventLog.CreateEventSource(evData);
                }
                EventLog ev = new EventLog();
                ev.Source = svcName;
                ev.MachineName = targetMachine;
                return ev;
            }
    
            private static ManagementScope CreateRemoteConnectionObject(string svcDomain, string svcServiceID, string svcPassword, string targetMachine, ConnectionOptions connOptions)
            {
                ManagementScope ms = null;
                System.Management.ManagementPath path = new System.Management.ManagementPath(@"\\" + targetMachine + @"\root\cimv2:Win32_Process");
                ms = new ManagementScope(path, connOptions);
                return ms;
            }
    
            private static ConnectionOptions CreateConnOptions(string svcDomain, string svcServiceID, string svcPassword, string targetMachine)
            {
                ConnectionOptions connOptions = new ConnectionOptions();
                connOptions.Authentication = System.Management.AuthenticationLevel.PacketPrivacy;
                connOptions.Impersonation = ImpersonationLevel.Impersonate;
                connOptions.EnablePrivileges = true;
    
                connOptions.Username = String.Format(@"{0}\{1}", svcDomain, svcServiceID);
                connOptions.Password = @svcPassword;
    
                return connOptions;
            }
    
            static bool IsValidAppPoolName(string appPool)
            {
                if (appPool.Length > 0)
                    return true;
                else
                    return false;
            }
    
            static bool IsValidDomainName(string svcDomain)
            {
                // a valid domain name must begin wtih an alpha numeric character, and cannot end with a '-' or a '.'
                if ((svcDomain.Length > 1) && (IsAlphaNumeric(svcDomain[0])) && (svcDomain[svcDomain.Length - 1] != '-') && (svcDomain[svcDomain.Length - 1] != '.'))
                    return true;
                else
                    return false;
            }
    
            static bool IsValidServiceID(string svcServiceID)
            {
                if (svcServiceID.Length > 0)
                    return true;
                else
                    return false;
            }
    
            static bool IsAlphaNumeric(char character)
            {
                Regex rg = new Regex("[a-zA-Z0-9]");
    
                //if has non AlpahNumeric char, return false, else return true.
                if (rg.IsMatch(character.ToString()))
                    return true;
                else
                    return false;
            }
    
        }
    }
    

    • Marked as answer by Logan Therrion Tuesday, November 27, 2012 7:53 PM
    Tuesday, November 27, 2012 7:52 PM

All replies

  • Some info about appPoolAction ?
    Tuesday, August 28, 2012 10:31 AM
  • appPoolAction is either stop or start.  That's is currently the only functionality I have included, is either to stop or start the app pool.




    Tuesday, August 28, 2012 1:42 PM
  • Anyone?  Please?  I really need a hand with this.  Your help is very much appreciated.

    Tuesday, September 4, 2012 2:58 PM
  • IIsWebServer.Start (ADSI) "This method has no return values."

    IIsWebServer.Stop (ADSI) "This method has no return values."

    IIsWebServer.Status (ADSI)

    "The Status method returns an integer that indicates the current status of the server. The possible values are 1 (starting), 2 (started), 3 (stopping), 4 (stopped), 5 (pausing), 6 (paused), or 7 (continuing)."

    Tuesday, September 4, 2012 3:23 PM
  • Thanks Louis!

    Do you see anything in my code that would account for a null return value?

    Tuesday, September 4, 2012 5:38 PM
  • Yes: the Start and Stop method have no return value. Since the Invoke method must return something, it returns null.
    Wednesday, September 5, 2012 3:16 PM
  • I finally figured out the problem I was having and I wanted to post the code here in case anyone else might have a use for it.  Now I'm able to stop and start an app pool on a remote server and log the events to the event viewer without any problems.

    Thanks everyone for your help!

    namespace StopStartAppPool
    {
        class StopStartAppPool
        {
            private static string svcDomain;
            private static string svcServiceID;
            private static string svcPassword;
            private static string appPoolName;
            private static string targetMachine;
            private static string appPoolAction;
            private static string invalidArg;
    
            static void Main(string[] args)
            {
                // ***** The command line arguments should be as follows: *****//
                // *****       DefaultAppPool stop FLJAX tfsservice 12345pwd VMDEVServer1 *****//
                // *****       DefaultAppPool start FLJAX tfsservice 12345pwd VMDEVServer1 *****//
    
                if (args.Length != 6)
                {
                    Console.WriteLine("Six arguments must be passed for a service to be stopped or started.");
                    Console.WriteLine("(1) the service name to stop or start, (2) 'stop' or 'start', (3) service ID domain, (4), service ID, (5) service ID password, (6) target machine.");
                    Console.WriteLine("No services will be stopped or started.");
                    return;
                }
    
                // ***** If any of the arguments input by the user are invalid, exit the program *****//
                if (!AssignUserInput(args, out invalidArg))
                {
                    Console.WriteLine(invalidArg);
                    return;
                }
    
                // ***** Create EventLog object so the Event Viewer can be updated *****//
                EventLog ev = new EventLog();
                ev = CreateEventLog(appPoolName, targetMachine);
    
                try
                {
                    ConnectionOptions connOptions = new ConnectionOptions(); 
                    connOptions = CreateConnOptions(svcDomain, svcServiceID, svcPassword, targetMachine);
                    ManagementScope ms = new ManagementScope();
                    ms = CreateRemoteConnectionObject(svcDomain, svcServiceID, svcPassword, targetMachine, connOptions);
                    ms.Connect();
    
                    ObjectGetOptions objectGetOptions = new ObjectGetOptions();
                    ManagementPath managementPath = new ManagementPath(@"\\" + targetMachine + @"\ROOT\CIMV2:Win32_Process");
                    ManagementClass processClass = new ManagementClass(ms, managementPath, objectGetOptions);
                    ManagementBaseObject inParams = processClass.GetMethodParameters("Create");
    
    
                    // ***** App pool values are:  1 (starting), 2 (started), 3 (stopping), 4 (stopped), 5 (pausing), 6 (paused), 7 (continuing) *****
                    int appPoolState = GetAppPoolState(appPoolName, targetMachine, connOptions, ms);
    
    
                    if (appPoolAction.ToLower().Contains("start"))
                    {
                        // ***** Only try to start the app pool if it's either in the stopped or paused state *****//
                        if ((appPoolState == 4) || (appPoolState == 6))
                        {
                            inParams["CommandLine"] = @"c:\windows\system32\inetsrv\appcmd.exe start apppool " + appPoolName;
                            ManagementBaseObject outParams = processClass.InvokeMethod("Create", inParams, null);
    
                            // ***** Write results to the event log *****//
                            string tmp = String.Format("The {0} application pool was started on {1} with an exit code of {2}:  ", appPoolName, targetMachine, outParams["returnValue"]);
                            ev.WriteEntry(tmp, EventLogEntryType.Information);
                        }
                        else
                        {
                            // ***** Write no action performed to the event log *****//
                            string tmp = String.Format("The {0} application pool could not be started on {1} becuase it's current state is:  {2}.", appPoolName, targetMachine, GetAppPoolState(appPoolState));
                            ev.WriteEntry(tmp, EventLogEntryType.Information);
                        }
                    }
    
                    if (appPoolAction.ToLower().Contains("stop"))
                    {
                        // ***** Only try to stop the app pool if it's either in the started or paused state *****//
                        if ((appPoolState == 2) || (appPoolState == 6))
                        {
                            inParams["CommandLine"] = @"c:\windows\system32\inetsrv\appcmd.exe stop apppool " + appPoolName;
                            ManagementBaseObject outParams = processClass.InvokeMethod("Create", inParams, null);
    
                            // ***** Write results to the event log *****//
                            string tmp = String.Format("The {0} application pool was stopped on {1} with an exit code of {2}.", appPoolName, targetMachine, outParams["returnValue"]);
                            ev.WriteEntry(tmp, EventLogEntryType.Information);
                        }
                        else
                        {
                            // ***** Write no action performed to the event log *****//
                            string tmp = String.Format("The {1} application pool could not be stopped on {1} becuase it's current state is:  {2}.", appPoolName, targetMachine, GetAppPoolState(appPoolState));
                            ev.WriteEntry(tmp, EventLogEntryType.Information);
                        }
                    }
                }
                catch (Exception ex)
                {
                    string tmp = String.Format("The StopStartAppPool.exe encountered an error and exited with code {0}:     {1}:     {2}:     {3}:     ", ex.Message, ex.Data, ex.InnerException, ex.StackTrace);
                    ev.WriteEntry(tmp, EventLogEntryType.Information);
                    Console.WriteLine(ex.StackTrace);
                    Console.WriteLine(ex.Data);
                    Console.WriteLine(ex.InnerException);
                    Console.WriteLine(ex.Message);
                    Console.WriteLine(ex.Source);
                }
            }
    
            private static int GetAppPoolState(string appPoolName, string targetMachine, ConnectionOptions connOptions, ManagementScope ms)
            {
                try
                {
                    DirectoryEntry appPools = new DirectoryEntry("IIS://" + targetMachine + "/w3svc/apppools", svcDomain + @"\" + svcServiceID, svcPassword);
                    foreach (DirectoryEntry AppPool in appPools.Children)
                    {
                        if (appPoolName.Equals(AppPool.Name, StringComparison.OrdinalIgnoreCase))
                        {
                            // ***** Values are:  1 (starting), 2 (started), 3 (stopping), 4 (stopped), 5 (pausing), 6 (paused), 7 (continuing) *****
                            PropertyCollection appPoolProps = AppPool.Properties;
                            appPoolState = Convert.ToInt32(appPoolProps["AppPoolState"].Value);
                        }
                    }
                }
                catch (ManagementException e)
                {
                } 
                return appPoolState;
            }
    
            private static string GetAppPoolState(int appPoolState)
            {
                // ***** App pool values are:  1 (starting), 2 (started), 3 (stopping), 4 (stopped), 5 (pausing), 6 (paused), 7 (continuing) *****
                switch (appPoolState)
                {
                    case 1:
                        return "Starting";
                    case 2:
                        return "Started";
                    case 3:
                        return "Stopping";
                    case 4:
                        return "Stopped";
                    case 5:
                        return "Pausing";
                    case 6:
                        return "Paused";
                    default:
                        return "Continuing";
                }
            }
    
            private static bool AssignUserInput(string[] args, out string invalidArg)
            {
                if (IsValidAppPoolName(args[0]))
                    appPoolName = args[0];
                else
                {
                    invalidArg = args[0];
                    return false;
                }
    
                if (args[1].ToLower() == "stop")
                    appPoolAction = "stop";
                else
                    appPoolAction = "start";
    
                if (IsValidDomainName(args[2]))
                    svcDomain = args[2];
                else
                {
                    invalidArg = args[2];
                    return false;
                }
    
                if (IsValidServiceID(args[3]))
                    svcServiceID = args[3];
                else
                {
                    invalidArg = args[3];
                    return false;
                }
    
                svcPassword = args[4];
                targetMachine = args[5];
    
                invalidArg = null;
                return true;
            }
    
            private static EventLog CreateEventLog(string svcName, string targetMachine)
            {
                if (!EventLog.SourceExists(svcName, targetMachine))
                {
                    EventSourceCreationData evData = new EventSourceCreationData(svcName, "Application");
                    evData.MachineName = targetMachine;
                    EventLog.CreateEventSource(evData);
                }
                EventLog ev = new EventLog();
                ev.Source = svcName;
                ev.MachineName = targetMachine;
                return ev;
            }
    
            private static ManagementScope CreateRemoteConnectionObject(string svcDomain, string svcServiceID, string svcPassword, string targetMachine, ConnectionOptions connOptions)
            {
                ManagementScope ms = null;
                System.Management.ManagementPath path = new System.Management.ManagementPath(@"\\" + targetMachine + @"\root\cimv2:Win32_Process");
                ms = new ManagementScope(path, connOptions);
                return ms;
            }
    
            private static ConnectionOptions CreateConnOptions(string svcDomain, string svcServiceID, string svcPassword, string targetMachine)
            {
                ConnectionOptions connOptions = new ConnectionOptions();
                connOptions.Authentication = System.Management.AuthenticationLevel.PacketPrivacy;
                connOptions.Impersonation = ImpersonationLevel.Impersonate;
                connOptions.EnablePrivileges = true;
    
                connOptions.Username = String.Format(@"{0}\{1}", svcDomain, svcServiceID);
                connOptions.Password = @svcPassword;
    
                return connOptions;
            }
    
            static bool IsValidAppPoolName(string appPool)
            {
                if (appPool.Length > 0)
                    return true;
                else
                    return false;
            }
    
            static bool IsValidDomainName(string svcDomain)
            {
                // a valid domain name must begin wtih an alpha numeric character, and cannot end with a '-' or a '.'
                if ((svcDomain.Length > 1) && (IsAlphaNumeric(svcDomain[0])) && (svcDomain[svcDomain.Length - 1] != '-') && (svcDomain[svcDomain.Length - 1] != '.'))
                    return true;
                else
                    return false;
            }
    
            static bool IsValidServiceID(string svcServiceID)
            {
                if (svcServiceID.Length > 0)
                    return true;
                else
                    return false;
            }
    
            static bool IsAlphaNumeric(char character)
            {
                Regex rg = new Regex("[a-zA-Z0-9]");
    
                //if has non AlpahNumeric char, return false, else return true.
                if (rg.IsMatch(character.ToString()))
                    return true;
                else
                    return false;
            }
    
        }
    }
    

    • Marked as answer by Logan Therrion Tuesday, November 27, 2012 7:53 PM
    Tuesday, November 27, 2012 7:52 PM