212 lines
7.5 KiB
C#
212 lines
7.5 KiB
C#
//
|
|
// Copyright (c) 2006 Microsoft Corporation. All rights reserved.
|
|
//
|
|
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
|
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
|
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
|
// PARTICULAR PURPOSE.
|
|
//
|
|
using System;
|
|
using System.Diagnostics;
|
|
using System.Collections;
|
|
using Win32Exception = System.ComponentModel.Win32Exception;
|
|
using System.Management.Automation; // Windows PowerShell namespace
|
|
using System.Globalization;
|
|
|
|
// This sample shows how to implement a PassThru parameter that indicates that
|
|
// the user wants the cmdlet to return an object, and how to request
|
|
// user feedback by calls to the ShouldProcess and ShouldContinue methods.
|
|
//
|
|
// To test this cmdlet, create a module folder that has the same name as
|
|
// this assembly (StopProcesssample01), save the assembly in the module folder, and then run the
|
|
// following command:
|
|
// import-module stopprocesssample01
|
|
|
|
namespace Microsoft.Samples.PowerShell.Commands
|
|
{
|
|
#region StopProcCommand
|
|
|
|
/// <summary>
|
|
/// This class implements the stop-proc cmdlet.
|
|
/// </summary>
|
|
[Cmdlet(VerbsLifecycle.Stop, "Proc",
|
|
SupportsShouldProcess = true)]
|
|
public class StopProcCommand : Cmdlet
|
|
{
|
|
#region Parameters
|
|
|
|
/// <summary>
|
|
/// This parameter provides the list of process names on
|
|
/// which the Stop-Proc cmdlet will work.
|
|
/// </summary>
|
|
[Parameter(
|
|
Position = 0,
|
|
Mandatory = true,
|
|
ValueFromPipeline = true,
|
|
ValueFromPipelineByPropertyName = true
|
|
)]
|
|
public string[] Name
|
|
{
|
|
get { return processNames; }
|
|
set { processNames = value; }
|
|
}
|
|
private string[] processNames;
|
|
|
|
/// <summary>
|
|
/// This parameter overrides 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 force; }
|
|
set { force = value; }
|
|
}
|
|
private bool force;
|
|
|
|
/// <summary>
|
|
/// This parameter indicates that the cmdlet should return
|
|
/// an object to the pipeline after the processing has been
|
|
/// completed.
|
|
/// </summary>
|
|
[Parameter]
|
|
public SwitchParameter PassThru
|
|
{
|
|
get { return passThru; }
|
|
set { passThru = value; }
|
|
}
|
|
private bool passThru;
|
|
|
|
#endregion Parameters
|
|
|
|
#region Cmdlet Overrides
|
|
|
|
/// <summary>
|
|
/// The ProcessRecord method does the following for each of the
|
|
/// requested process names:
|
|
/// 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()
|
|
{
|
|
foreach (string name in processNames)
|
|
{
|
|
// For every process name passed to the cmdlet, get the associated
|
|
// processes.
|
|
// Write a nonterminating error for failure to retrieve
|
|
// a process.
|
|
Process[] processes;
|
|
|
|
try
|
|
{
|
|
processes = Process.GetProcessesByName(name);
|
|
}
|
|
catch (InvalidOperationException ioe)
|
|
{
|
|
WriteError(new ErrorRecord(ioe,"UnableToAccessProcessByName",
|
|
ErrorCategory.InvalidOperation, name));
|
|
|
|
continue;
|
|
}
|
|
|
|
// Try to stop the processes that have been retrieved.
|
|
foreach (Process process in processes)
|
|
{
|
|
string processName;
|
|
|
|
try
|
|
{
|
|
processName = process.ProcessName;
|
|
}
|
|
catch (Win32Exception e)
|
|
{
|
|
WriteError(new ErrorRecord(e, "ProcessNameNotFound",
|
|
ErrorCategory.ReadError, process));
|
|
continue;
|
|
}
|
|
|
|
// Confirm the operation with the user first.
|
|
// This is always false if the WhatIf parameter is set.
|
|
if (!ShouldProcess(string.Format(CultureInfo.CurrentCulture,"{0} ({1})", processName,
|
|
process.Id)))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// Make sure that the user really wants to stop a critical
|
|
// process that culd possibly stop the computer.
|
|
bool criticalProcess =
|
|
criticalProcessNames.Contains(processName.ToLower(CultureInfo.CurrentCulture));
|
|
|
|
if (criticalProcess &&!force)
|
|
{
|
|
string 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 recieved 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 yesToAll, ref noToAll))
|
|
{
|
|
continue;
|
|
}
|
|
} // if (cricicalProcess...
|
|
|
|
// Stop the named process.
|
|
try
|
|
{
|
|
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));
|
|
continue;
|
|
} // if ((e is...
|
|
else throw;
|
|
} // catch
|
|
|
|
// If the PassThru parameter is
|
|
// specified, return the terminated process.
|
|
if (passThru)
|
|
{
|
|
WriteObject(process);
|
|
}
|
|
} // foreach (Process...
|
|
} // foreach (string...
|
|
} // ProcessRecord
|
|
|
|
#endregion Cmdlet Overrides
|
|
|
|
#region Private Data
|
|
|
|
private bool yesToAll, noToAll;
|
|
|
|
/// <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" }
|
|
);
|
|
|
|
#endregion Private Data
|
|
|
|
} // StopProcCommand
|
|
|
|
#endregion StopProcCommand
|
|
}
|
|
|