Rust PowerShell脚本执行库powershell_script的使用,支持在Rust中无缝运行和管理PowerShell命令与脚本
Rust PowerShell脚本执行库powershell_script的使用
基本介绍
powershell_script是一个基础的Rust库,它使用std::process::Command
将命令传递给PowerShell,并提供了对process::Output
的便捷包装器,特别适合在Rust中运行Windows PowerShell命令。
基础使用方法
建议将PowerShell命令写入.ps
文件中,这样可以更好地利用现有工具创建和维护脚本。
示例1:创建桌面快捷方式
PowerShell脚本文件 (script.ps)
$SourceFileLocation="C:\Windows\notepad.exe"
$ShortcutLocation=[Environment]::GetFolderPath("Desktop")+"\notepad.lnk"
$WScriptShell=New-Object -ComObject WScript.Shell
$Shortcut=$WScriptShell.CreateShortcut($ShortcutLocation)
$Shortcut.TargetPath=$SourceFileLocation
$Shortcut.Save()
Rust代码 (main.rs)
use powershell_script;
fn main() {
// 包含PowerShell脚本文件内容
let create_shortcut = include_str!("script.ps");
// 运行脚本并处理结果
match powershell_script::run(create_shortcut) {
Ok(output) => {
println!("{}", output);
}
Err(e) => {
println!("Error: {}", e);
}
}
}
高级控制 - 使用PsScriptBuilder
PsScriptBuilder
提供了更多配置选项来控制PowerShell脚本的执行方式。
示例2:使用PsScriptBuilder配置执行选项
use powershell_script::PsScriptBuilder;
fn main() {
// 创建PowerShell脚本构建器并配置选项
let ps = PsScriptBuilder::new()
.no_profile(true) // 不加载用户配置文件
.non_interactive(true) // 非交互模式
.hidden(false) // 不隐藏窗口
.print_commands(false) // 不打印执行的命令
.build();
// 执行简单命令
let output = ps.run(r#"echo "hello world""#).unwrap();
// 验证输出
assert!(output.stdout().unwrap().contains("hello world"));
}
完整示例代码
示例3:获取系统进程信息
use powershell_script::PsScriptBuilder;
fn get_process_info() {
// 创建配置好的PowerShell执行器
let ps = PsScriptBuilder::new()
.no_profile(true)
.build();
// 执行获取进程信息的命令
let output = ps.run(r#"
Get-Process |
Select-Object -Property ProcessName, Id, CPU |
ConvertTo-Json -Compress
"#).unwrap();
// 解析JSON输出
if let Ok(processes) = serde_json::from_str::<Vec<serde_json::Value>>(output.stdout().unwrap()) {
for process in processes {
println!("进程: {}, ID: {}, CPU使用: {}",
process["ProcessName"].as_str().unwrap(),
process["Id"].as_u64().unwrap(),
process["CPU"].as_f64().unwrap());
}
}
}
示例4:系统服务管理
use powershell_script;
fn manage_services() {
// 直接运行多行PowerShell命令
let commands = r#"
# 获取所有运行中的服务
$running = Get-Service | Where-Object { $_.Status -eq 'Running' }
# 输出服务数量
Write-Output "当前有 $($running.Count) 个服务正在运行"
# 获取前5个服务详细信息
$running | Select-Object -First 5 | Format-Table -AutoSize
"#;
match powershell_script::run(commands) {
Ok(output) => {
println!("服务信息:\n{}", output);
}
Err(e) => {
eprintln!("获取服务信息失败: {}", e);
}
}
}
功能特点
-
跨平台支持:
- Windows: 默认使用系统自带的PowerShell,也可通过
core
功能使用PowerShell Core - 其他操作系统: 使用PowerShell Core运行脚本
- Windows: 默认使用系统自带的PowerShell,也可通过
-
灵活的脚本执行方式:
- 支持从文件加载脚本
- 支持直接执行字符串命令
- 支持多行命令执行
-
丰富的输出处理:
- 提供对stdout/stderr的便捷访问
- 支持错误处理和状态检查
-
执行控制选项:
- 控制是否加载用户配置文件(no_profile)
- 设置交互模式(non_interactive)
- 控制窗口显示(hidden)
- 调试输出(print_commands)
使用建议
- 对于复杂脚本,建议保存在单独的.ps文件中
- 使用PsScriptBuilder配置执行环境,特别是生产环境
- 处理输出时考虑使用JSON格式以便于解析
- 注意错误处理,特别是跨平台使用时
1 回复
Rust PowerShell脚本执行库 powershell_script
使用指南
powershell_script
是一个 Rust 库,允许开发者在 Rust 程序中无缝执行和管理 PowerShell 命令与脚本。它提供了简单易用的 API 来运行 PowerShell 命令并获取结果。
安装
在 Cargo.toml
中添加依赖:
[dependencies]
powershell_script = "1.0"
基本用法
执行简单命令
use powershell_script::PsScriptBuilder;
fn main() {
// 定义要执行的PowerShell命令
let cmd = "Get-Process | Select-Object -First 3";
// 构建并执行PowerShell脚本
let output = PsScriptBuilder::new()
.no_profile(true) // 不加载用户配置文件
.non_interactive(true) // 非交互模式
.hidden(false) // 不隐藏窗口
.print_commands(false) // 不打印执行的命令
.build()
.run(cmd)
.unwrap();
// 输出执行结果
println!("Status: {}", output.status.success());
println!("Stdout: {}", output.stdout());
println!("Stderr: {}", output.stderr());
}
执行脚本文件
use powershell_script::PsScriptBuilder;
fn main() {
// 执行指定的PowerShell脚本文件
let output = PsScriptBuilder::new()
.run_from_file("script.ps1")
.unwrap();
// 输出脚本执行结果
println!("Script output: {}", output.stdout());
}
高级功能
传递参数
use powershell_script::{PsScriptBuilder, EscapePowerShellArg};
fn main() {
// 安全转义参数
let param1 = "Hello".escape_powershell_arg();
let param2 = "World".escape_powershell_arg();
// 构建带参数的PowerShell命令
let cmd = format!("param($p1, $p2) Write-Output \"$p1 $p2\" -args {}, {}", param1, param2);
// 执行命令
let output = PsScriptBuilder::new()
.run(&cmd)
.unwrap();
println!("Output: {}", output.stdout());
}
异步执行
use powershell_script::PsScriptBuilder;
use tokio::runtime::Runtime;
fn main() {
// 创建Tokio运行时
let rt = Runtime::new().unwrap();
// 异步执行PowerShell命令
let output = rt.block_on(async {
PsScriptBuilder::new()
.run_async("Get-Service | Where-Object { $_.Status -eq 'Running' }")
.await
}).unwrap();
println!("Running services:\n{}", output.stdout());
}
处理二进制输出
use powershell_script::PsScriptBuilder;
fn main() {
// 执行生成二进制数据的命令
let output = PsScriptBuilder::new()
.run("[System.Text.Encoding]::UTF8.GetBytes('Binary data')")
.unwrap();
// 获取二进制输出
let binary_data = output.stdout_bytes();
println!("Binary data length: {}", binary_data.len());
}
错误处理
use powershell_script::{PsScriptBuilder, PowerShellError};
fn main() -> Result<(), PowerShellError> {
// 尝试执行不存在的命令
let output = PsScriptBuilder::new()
.run("This-Command-Does-Not-Exist")?;
// 检查命令是否执行成功
if !output.status.success() {
eprintln!("PowerShell error: {}", output.stderr());
}
Ok(())
}
完整示例
下面是一个结合了多个功能的完整示例:
use powershell_script::{PsScriptBuilder, EscapePowerShellArg};
use tokio::runtime::Runtime;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 示例1: 执行简单命令
println!("=== 示例1: 执行简单命令 ===");
let cmd = "Get-ChildItem | Select-Object -First 5";
let output = PsScriptBuilder::new()
.no_profile(true)
.non_interactive(true)
.run(cmd)?;
println!("Command output:\n{}", output.stdout());
// 示例2: 传递参数
println!("\n=== 示例2: 传递参数 ===");
let user = "Admin".escape_powershell_arg();
let message = "Welcome!".escape_powershell_arg();
let param_cmd = format!(
"param($user, $msg) Write-Output \"User: $user, Message: $msg\" -args {}, {}",
user, message
);
let param_output = PsScriptBuilder::new().run(¶m_cmd)?;
println!("Parameter output: {}", param_output.stdout());
// 示例3: 异步执行
println!("\n=== 示例3: 异步执行 ===");
let rt = Runtime::new()?;
let async_output = rt.block_on(async {
PsScriptBuilder::new()
.run_async("Get-Date -Format 'yyyy-MM-dd HH:mm:ss'")
.await
})?;
println!("Current date: {}", async_output.stdout());
// 示例4: 错误处理
println!("\n=== 示例4: 错误处理 ===");
match PsScriptBuilder::new().run("Non-Existent-Cmdlet") {
Ok(output) => {
if !output.status.success() {
println!("Command failed with error: {}", output.stderr());
}
}
Err(e) => println!("Execution error: {}", e),
}
Ok(())
}
注意事项
- 在 Windows 上需要安装 PowerShell
- 在非 Windows 平台上需要安装 PowerShell Core (
pwsh
) - 对于敏感命令,考虑使用
.hidden(true)
来隐藏 PowerShell 窗口 - 使用
.escape_powershell_arg()
方法来安全地传递参数,防止注入攻击
这个库为 Rust 和 PowerShell 之间的互操作提供了强大的支持,特别适合需要在 Rust 应用中集成 Windows 管理功能的场景。