此示例演示如何编写在停止本地计算机上的进程时写入调试(WriteDebug)、详细(WriteVerbose)和警告(WriteWarning)消息的 cmdlet。 此 cmdlet 类似于 Windows PowerShell 2.0 提供的 Stop-Process
cmdlet。
如何使用 Visual Studio 生成示例
打开 Windows Internet Explorer 并导航到 Samples 目录下的 StopProcessSample02 目录。
安装 Windows PowerShell 2.0 SDK 后,导航到 StopProcessSample02 文件夹。 默认位置为
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0\Samples\sysmgmt\WindowsPowerShell\csharp\StopProcessSample02
。双击解决方案(.sln)文件的图标。 这将在 Visual Studio 中打开示例项目Microsoft。
在 生成 菜单中,选择 “生成解决方案”,以在默认
\bin
或\bin\debug
文件夹中为示例生成库。
如何运行示例
创建以下模块文件夹:
[user]\Documents\WindowsPowerShell\Modules\StopProcessSample02
将示例程序集复制到模块文件夹。
启动 Windows PowerShell。
运行以下命令将程序集加载到 Windows PowerShell 中:
Import-Module stopprossessample02
运行以下命令以运行 cmdlet:
Stop-Proc
要求
此示例需要 Windows PowerShell 2.0。
演示
此示例演示了以下内容。
使用 Cmdlet 属性声明 cmdlet 类。
使用 Parameter 属性声明 cmdlet 参数。
编写详细消息。 有关用于编写详细消息的方法的详细信息,请参阅 System.Management.Automation.Cmdlet.WriteVerbose。
编写错误消息。 有关用于写入错误消息的方法的详细信息,请参阅 System.Management.Automation.Cmdlet.WriteError。
编写警告消息。 有关用于编写警告消息的方法的详细信息,请参阅 System.Management.Automation.Cmdlet.WriteWarning。
示例
此示例演示如何使用 WriteDebug
、WriteVerbose
和 WriteWarning
方法编写调试、详细和警告消息。
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)
{
string message = null;
// For every process name passed to the cmdlet, get the associated
// processes.
// Write a non-terminating error for failure to retrieve
// a process.
// 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.
message = String.Format(CultureInfo.CurrentCulture,
"Attempting to stop process \"{0}\".", name);
WriteVerbose(message);
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.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);
// 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)))
{
continue;
}
// Make sure that the user really wants to stop a critical
// process that can possibly stop the computer.
bool criticalProcess = criticalProcessNames.Contains(processName.ToLower(CultureInfo.CurrentCulture));
if (criticalProcess && !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 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...
// Display a warning message if the cmdlet is stopping a
// critical process.
if (criticalProcess)
{
message = String.Format(CultureInfo.CurrentCulture,
"Stopping the critical process \"{0}\".",
processName);
WriteWarning(message);
} // 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
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 object to the pipeline.
if (passThru)
{
message = String.Format(CultureInfo.CurrentCulture,
"Writing process \"{0}\" to pipeline",
processName);
WriteDebug(message);
WriteObject(process);
} // if (passThru...
} // 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
}