StopProcessSample01 示例
此示例演示如何编写一个在尝试停止进程之前请求用户反馈的 cmdlet,以及如何实现一个 PassThru 参数来指示用户希望该 cmdlet 返回一个对象。此 cmdlet 类似于 Windows PowerShell 2.0 提供的 Stop-Process cmdlet。
如何使用 Visual Studio 构建示例
安装 Windows PowerShell 2.0 SDK 后,导航到 StopProcessSample01 文件夹。默认位置为 C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0\Samples\sysmgmt\WindowsPowerShell\csharp\StopProcessSample01。
双击解决方案 (.sln) 文件的图标。这将在 Microsoft Visual Studio 中打开示例项目。
在构建菜单中,选择构建解决方案在默认的
\bin或\bin\debug<中构建示例的库/代码> 文件夹。
如何运行示例
创建以下模块文件夹:
[user]\Documents\WindowsPowerShell\Modules\StopProcessSample01-
将示例程序集复制到模块文件夹。
启动 Windows PowerShell。
运行以下命令将程序集加载到 Windows PowerShell 中:
Import-Module stopprossessample01运行以下命令来运行 cmdlet:
stop-proc
要求
此示例需要 Windows PowerShell 2.0。
示范
该示例演示了以下内容。
使用 Cmdlet 属性声明 cmdlet 类。
使用 Parameter 属性声明 cmdlet 参数。
调用 ShouldProcess 方法请求确认。
实现一个
PassThru参数,指示用户是否希望 cmdlet 返回对象。默认情况下,此 cmdlet 不会将对象返回到管道。
例子
此示例演示如何实现一个 PassThru 参数来指示用户希望 cmdlet 返回一个对象,以及如何通过调用 ShouldProcess 和 请求用户反馈>ShouldContinue 方法。
using System;
using System.Diagnostics;
using System.Collections;
using Win32Exception = System.ComponentModel.Win32Exception;
using System.Management.Automation; // Windows PowerShell namespace
using System.Globalization;
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 non-terminating 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 could 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 received as inputs from
// the pipeline. So to retain YesToAll and NoToAll input that
// the user may enter across multiple calls to this function,
// they are stored as private members of the cmdlet.
if (!ShouldContinue(message, "Warning!",
ref yesToAll, ref noToAll))
{
continue;
}
} // if (criticalProcess...
// 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 non-terminating 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
}
参见
- 编写 Windows PowerShell Cmdlet