EN
Ce contenu n’est pas disponible dans votre langue. Voici la version anglaise.

StopProcessSample03 Sample

This sample shows how to write a cmdlet whose parameters have aliases and whose parameters support wildcard characters. 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 StopProcessSample03 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/StopProcessSample03

  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 stopprossessample03

  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 aliases to parameter declarations..

  • Adding wildcard support to parameters.

Example

The following code shows an implementation of the Stop-Proc cmdlet whose parameters have aliases and that support wildcard characters.

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",
          SupportsShouldProcess = true)]
  public class StopProcCommand : Cmdlet
  {
    #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;
    
    #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,
               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(
               ValueFromPipelineByPropertyName = true,
               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; }
    }
    
    #endregion Parameters

    #region Cmdlet Overrides
    /// <summary>
    /// The ProcessRecord method does the following for each of the 
    /// requested process names:
    /// 1. Checks that the process is not a critical process.
    /// 2. Attempts to stop that process.
    /// If no process is requested then nothing occurs.
    /// </summary>   
    protected override void ProcessRecord()
    {   
      Process[] processes = null;
      
      try 
      { 
        processes = Process.GetProcesses(); 
      }
      catch (InvalidOperationException ioe)
      {
        this.ThrowTerminatingError(new ErrorRecord(
                                                   ioe,
                                                   "UnableToAcessProcessList",
                                                   ErrorCategory.InvalidOperation,
                                                   null));
      }
      
      // For every process name passed to the cmdlet, stop the associated 
      // processes.  
      // Write a nonterminating error for failure to stop a process.
      foreach (string name in this.processNames)
      {
        // Write a user-friendly verbose message to the pipeline. These 
        // messages are intended to give the user detailed information 
        // on the operations performed by the cmdlet. These messages will
        // appear with the -Verbose option.
        string message = String.Format(
                                       CultureInfo.CurrentCulture, 
                                       "Attempting to stop process \"{0}\".", 
                                       name);
        WriteVerbose(message);
        
        // Validate the process name against a wildcard pattern.  
        // If the name does not contain any wildcard patterns, it 
        // will be treated as an exact match.
        WildcardOptions options = WildcardOptions.IgnoreCase | 
                                  WildcardOptions.Compiled;
        WildcardPattern wildcard = new WildcardPattern(name, options);           
        
        foreach (Process process in processes)
        {
          string processName;
          
          try
          {
             processName = process.ProcessName;
          }
          catch (Win32Exception e)
          {
            WriteError(new ErrorRecord(
                                       e, 
                                       "ProcessNameNotFound",
                                       ErrorCategory.ObjectNotFound,
                                       process));
            continue;
          }
           
          // 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, 
                                   "Acquired name for pid {0} : \"{1}\"",
                                   process.Id, 
                                   processName);
          WriteDebug(message);
          
          // Check to see if this process matches the current process 
          // name pattern. Skip this process if it does not.
          if (!wildcard.IsMatch(processName))
          {
            continue;
          } 
          
          // Stop the process.
          this.SafeStopProcess(process);
        } // End foreach (Process...).
      } // End foreach (string...).
    } // End ProcessRecord.
    
    #endregion Cmdlet Overrides

    #region Helper Methods
    
    /// <summary>
    /// Safely stops a named process.  Used as a 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,
                                   "ProcessNameNotFound",
                                   ErrorCategory.ObjectNotFound, 
                                   process));
        return;               
      }
      
      string message = null;
      
      // Confirm the operation first.
      // This is always false if the WhatIf parametr 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 could possibly stop the computer.
      bool criticalProcess = this.criticalProcessNames.Contains(processName.ToLower(CultureInfo.CurrentCulture));
      
      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 ProcessRecord is called multiple 
        // when objects are received as inputs from a 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. 
        
      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)
      {
        message = String.Format(
                                CultureInfo.CurrentCulture, 
                                "Writing process \"{0}\" to pipeline",
                                processName);
        WriteDebug(message);
        WriteObject(process);
      } // End if (passThru...).
    } // End SafeStopProcess.

    #endregion Helper Methods

    #region Private Data
  
    /// <summary>
    /// Partial list of the 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" });
  
    #endregion Private Data
  } // End StopProcCommand.
  
  #endregion StopProcCommand
}

See Also



Afficher:
© 2014 Microsoft