EN
Este conteúdo não está disponível em seu idioma, mas aqui está a versão em inglês.

StopProcessSample04 Sample

This sample shows how to write a cmdlet that declares parameter sets, specifies the default parameter set, and can accept an input object. This cmdlet is similar to the Stop-Process cmdlet provided by Windows PowerShell.

How to build the sample by using Visual Studio.

  1. Open Windows Internet Explorer and navigate to the StopProcessSample04 directory under the Samples directory.

  2. Double-click the icon for the solution (.sln) file. This opens the sample project in Microsoft Visual Studio.

  3. In the Build menu, select Build Solution.

The library for the sample will be built in the default \bin or \bin\debug directories.

How to run the sample

  1. Create the following module folder:

    [user]/documents/windowspowershell/modules/StopProcessSample04

  2. Copy the sample assembly to the module folder.

  3. Start Windows PowerShell.

  4. Run the following command to load the assembly into Windows PowerShell:

    import-module stopprossessample04

  5. Run the following command to run the cmdlet:

    stop-proc

Requirements

This sample requires Windows PowerShell 2.0.

Demonstrates

This sample demonstrates the following.

  • Declaring a cmdlet class by using the Cmdlet attribute.

  • Declaring a cmdlet parameters by using the Parameter attribute.

  • Adding a parameter that accepts input object.

  • Adding parameters to parameter sets

  • Specifying the default parameter set.

Example

The following code shows an implementation of the Stop-Proc cmdlet that declare parameter sets, specifies the default parameter set, and can accept an input object.

namespace Microsoft.Samples.PowerShell.Commands
{
  using System;
  using System.Collections;
  using System.Diagnostics;
  using System.Globalization;
  using System.Management.Automation;     // Windows PowerShell namespace.
  using Win32Exception = System.ComponentModel.Win32Exception;
  
  #region StopProcCommand

  /// <summary>
  /// This class implements the stop-proc cmdlet.
  /// </summary>
  [Cmdlet(VerbsLifecycle.Stop, "Proc",
          DefaultParameterSetName = "ProcessId",
          SupportsShouldProcess = true)]
  public class StopProcCommand : PSCmdlet
  {
    #region Fields
     
    /// <summary>
    /// Names of processes to be stopped.
    /// </summary>
    private string[] processNames;
      
    /// <summary>
    /// Indicates if the Force parameter was specified.
    /// </summary>
    private bool force;
    
    /// <summary>
    /// Indicates if the PassThru parameter was specified.
    /// </summary>
    private bool passThru;
    
    /// <summary>
    /// Indicates that the user returned YesToAll or NoToAll
    /// to confirmation request.
    /// </summary>
    private bool yesToAll, noToAll;

    /// <summary>
    /// Identifiers of the processes to be stopped.
    /// </summary>
    private int[] processIds;

    /// <summary>
    /// Objects passed to the cmdlet.
    /// </summary>
    private Process[] inputObject;
    
    #endregion Fields
    
    #region Parameters
    
    /// <summary>
    /// Gets or sets the list of process names on 
    /// which the Stop-Proc cmdlet will work.
    /// </summary>
    [Parameter(
               Position = 0,
               ParameterSetName = "ProcessName",
               Mandatory = true,
               ValueFromPipeline = true,
               ValueFromPipelineByPropertyName = true,
               HelpMessage = "The name of one or more processes to stop. Wildcards are permitted.")]
    [Alias("ProcessName")]
    public string[] Name
    {
      get { return this.processNames; }
      set { this.processNames = value; }
    }

    /// <summary>
    /// Gets or sets an indicator used to override the 
    /// ShouldContinue call to force the cmdlet to stop 
    /// its operation. This parameter should always be 
    /// used with caution.
    /// </summary>
    [Parameter]
    public SwitchParameter Force
    {
      get { return this.force; }
      set { this.force = value; }
    }

    /// <summary>
    /// Gets or sets an indicator used to direct the cmdlet 
    /// to return an object to the pipeline after the specified 
    /// processes have been stopped.
    /// </summary>
    [Parameter(
          HelpMessage = "If set the process(es) will be passed to the pipeline after stopped.")]
    public SwitchParameter PassThru
    {
      get { return this.passThru; }
      set { this.passThru = value; }
    }
   
    /// <summary>
    /// Gets or sets the list of process identifiers on 
    /// which the Stop-Proc cmdlet will work.
    /// </summary>
    [Parameter(
               ParameterSetName = "ProcessId",
               Mandatory = true,
               ValueFromPipelineByPropertyName = true,
               ValueFromPipeline = true)]
    [Alias("ProcessId")]
    public int[] Id
    {
      get { return this.processIds; }
      set { this.processIds = value; }
    }
 
    /// <summary>
    /// Gets or sets an array of Process objects from the 
    /// the pipeline. This object contains the processes to stop.
    /// </summary>
    /// <value>Process objects</value>
    [Parameter(
               ParameterSetName = "InputObject",
               Mandatory = true,
               ValueFromPipeline = true)]
    public Process[] InputObject
    {
      get { return this.inputObject; }
      set { this.inputObject = value; }
    }
    
    #endregion Parameters

    #region CmdletOverrides
    
    /// <summary>
    /// The ProcessRecord method does the following for each of the 
    /// requested processes:
    /// 1. Check that the process is not a critical process.
    /// 2. Attempt to stop that process.
    /// If no process is requested then nothing occurs.
    /// </summary>     
    protected override void ProcessRecord()
    {
      switch (ParameterSetName)
      {
        case "ProcessName":
             this.ProcessByName();
             break;
        
        case "ProcessId":
             this.ProcessById();
             break;
        
        case "InputObject":
             foreach (Process process in this.inputObject)
             {
               this.SafeStopProcess(process);
             }

             break;
        
        default:
               throw new ArgumentException("Bad ParameterSet Name");
      } // End switch (ParameterSetName...
    } // End ProcessRecord.

    #endregion Cmdlet Overrides
    
    #region Helper Methods
    
    /// <summary>
    /// Returns all processes with matching names.
    /// </summary>
    /// <param name="processName">
    /// The name of the processes to return.
    /// </param>
    /// <param name="allProcesses">An array of all 
    /// computer processes.</param>
    /// <returns>An array of matching processes.</returns>
    internal ArrayList SafeGetProcessesByName(
                                              string processName, 
                                              ref ArrayList allProcesses)
    {
      // Create and array to store the matching processes.
      ArrayList matchingProcesses = new ArrayList();
      
      // Create the wildcard for pattern matching.
      WildcardOptions options = WildcardOptions.IgnoreCase |
                                WildcardOptions.Compiled;
      WildcardPattern wildcard = new WildcardPattern(processName, options);           
      
      // retrieve all of the computer processes.
      foreach (Process process in allProcesses)
      {
        string processNameToMatch = null;
        try
        {
          processNameToMatch = process.ProcessName;
        }
        catch (Win32Exception e)
        {
          // Remove the process from the list so that it is not 
          // checked again.
          allProcesses.Remove(process);
          
          string message = String.Format(
                                         CultureInfo.CurrentCulture, 
                                         "The process \"{0}\" could not be found",
                                         processName);
          WriteVerbose(message);
          WriteError(new ErrorRecord(
                                     e,
                                     "ProcessNotFound",
                                     ErrorCategory.ObjectNotFound, 
                                     processName));
          
          continue;
        }
        
        if (!wildcard.IsMatch(processNameToMatch))
        {
          continue;
        }
        
        matchingProcesses.Add(process); 
      } // End foreach(Process...).

      return matchingProcesses;
    } // End SafeGetProcessesByName.
    
    /// <summary>
    /// Safely stops a named process.  Used as standalone function
    /// to declutter the ProcessRecord method.
    /// </summary>
    /// <param name="process">The process to stop.</param>
    private void SafeStopProcess(Process process)
    {
      string processName = null;
           
      try
      {
        processName = process.ProcessName;
      }
      catch (Win32Exception e)
      {
        WriteError(new ErrorRecord(
                                   e,
                                   "ProcessNotFound",
                                   ErrorCategory.OpenError,
                                   processName));
        return;
      }          

      // Confirm the operation first.
      // This is always false if the WhatIf parameter is specified.
      if (!ShouldProcess(string.Format(
                                       CultureInfo.CurrentCulture, 
                                       "{0} ({1})", 
                                       processName, 
                                       process.Id)))
      {
        return;
      }
      
      // Make sure that the user really wants to stop a critical
      // process that can possibly stop the computer.
      bool criticalProcess = this.criticalProcessNames.Contains(processName.ToLower(CultureInfo.CurrentCulture));
      
      string message = null;
      if (criticalProcess && !this.force)
      {
        message = String.Format(
                                CultureInfo.CurrentCulture, 
                                "The process \"{0}\" is a critical process and should not be stopped. Are you sure you wish to stop the process?",
                                processName);

        // It is possible that the ProcessRecord method is called 
        // multiple times when objects are received as inputs from 
        // the pipeline. So to retain YesToAll and NoToAll input that 
        // the user may enter across mutilple calls to this function, 
        // they are stored as private members of the cmdlet.
        if (!ShouldContinue(
                            message, 
                            "Warning!",
                            ref this.yesToAll, 
                            ref this.noToAll))
        {
          return;
        }
      } // End if (criticalProcess...).
      
      // Display a warning message if stopping a critical 
      // process.
      if (criticalProcess)
      {
        message = String.Format(
                                CultureInfo.CurrentCulture,
                                "Stopping the critical process \"{0}\".",
                                processName);
        WriteWarning(message);
      } // End if (criticalProcess...).
      
      try
      {
        // Stop the process.
        process.Kill();
      }
      catch (Exception e)
      {
        if ((e is Win32Exception) || (e is SystemException) ||
            (e is InvalidOperationException))
        {
          // This process could not be stopped so write
          // a nonterminating error.
          WriteError(new ErrorRecord(
                                     e,
                                     "CouldNotStopProcess",
                                     ErrorCategory.CloseError,
                                     process));
          return;
        } // End if(e is...).
        else
        {
          throw;
        }
      } // End catch. 

      // Write a user-level verbose message to the pipeline. These are 
      // intended to give the user detailed information on the 
      // operations performed by the cmdlet. These messages will
      // appear with the -Verbose option.
      message = String.Format(
                              CultureInfo.CurrentCulture, 
                              "Stopped process \"{0}\", pid {1}.",
                              processName, 
                              process.Id);
        
      WriteVerbose(message);

      // If the PassThru parameter is specified, return the terminated 
      // process to the pipeline.
      if (this.passThru)
      {
        // Write a debug message to the host that can be used
        // when troubleshooting a problem. All debug messages
        // will appear with the -Debug option
        message = String.Format(
                                CultureInfo.CurrentCulture, 
                                "Writing process \"{0}\" to pipeline",
                                processName);
        WriteDebug(message);
        WriteObject(process);
      } // End if (passThru...).
    } // End SafeStopProcess
      
    /// <summary>
    /// Stop processes based on their names (using the
    /// ParameterSetName as ProcessName)
    /// </summary>
    private void ProcessByName()
    {
      ArrayList allProcesses = null;
       
      // Get a list of all the processes.
      try
      {
        allProcesses = new ArrayList(Process.GetProcesses());
      }
      catch (InvalidOperationException ioe)
      {
        this.ThrowTerminatingError(new ErrorRecord(
                                                   ioe, 
                                                   "UnableToAccessProcessList",
                                                   ErrorCategory.InvalidOperation, 
                                                   null));
      }
        
      // If a process name is passed to the cmdlet, get 
      // the associated processes. 
      // Write a nonterminating error for failure to
      // retrieve a process.
      foreach (string name in this.processNames)
      {
        // The allProcesses array list is passed as a reference because 
        // any process whose name cannot be obtained will be removed
        // from the list so that its not compared the next time.
        ArrayList processes =
                 this.SafeGetProcessesByName(name, ref allProcesses);
          
        // If no processes were found write a non-
        // terminating error.
        if (processes.Count == 0)
        {
          WriteError(new ErrorRecord(
                     new Exception(
                                   "Process not found."),
                                   "ProcessNotFound",
                                   ErrorCategory.ObjectNotFound,
                                   name));
        } // End if (processes...).
          
        // Otherwise terminate all processes in the list.
        else
        {
          foreach (Process process in processes)
          {
            this.SafeStopProcess(process);
          } // End foreach (Process...).
        } // End else.
      } // End foreach (string...).
    } // End ProcessByName.

    /// <summary>
    /// Stop processes based on their identifiers (using the
    /// ParameterSetName as ProcessIds)
    /// </summary>
    internal void ProcessById()
    {
      foreach (int processId in this.processIds)
      {
        Process process = null;
        try
        {
          process = Process.GetProcessById(processId);
            
          // Write a debug message to the host that can be used
          // when troubleshooting a problem. All debug messages
          // will appear with the -Debug option
          string message = String.Format(
                                         CultureInfo.CurrentCulture, 
                                         "Acquired process for pid : {0}",
                                         process.Id);
          WriteDebug(message);
        }
        catch (ArgumentException ae)
        {
          string message = String.Format(
                                         CultureInfo.CurrentCulture, 
                                         "The process id {0} could not be found",
                                         processId);
          WriteVerbose(message);
          WriteError(new ErrorRecord(
                                     ae, 
                                     "ProcessIdNotFound",
                                     ErrorCategory.ObjectNotFound, 
                                     processId));
          continue;
        }
          
        this.SafeStopProcess(process);
      } // foreach (int...
    } // ProcessById
    
    #endregion Helper Methods

    #region Private Data

    /// <summary>
    /// Partial list of critical processes that should not be 
    /// stopped.  Lower case is used for case insensitive matching.
    /// </summary>
    private ArrayList criticalProcessNames = new ArrayList(
          new string[] { "system", "winlogon", "spoolsv", "calc" });
    
    #endregion Private Data
  } // End StopProcCommand.
  
  #endregion StopProcCommand
}

See Also



Mostrar:
© 2014 Microsoft