集合
环境变量
- 直接
[Environment]::SetEnvironmentVariable(name,value,scope) 会超级慢,因为每次都进行广播通知(几乎没什么程序会处理这个),因此一般情况直接设置注册表即可
function main() {
$envs = @{
ANTHROPIC_BASE_URL = "https://api.deepseek.com/anthropic"
ANTHROPIC_AUTH_TOKEN = "sk-xxxx"
ANTHROPIC_MODEL = "deepseek-v4-flash[1m]"
ANTHROPIC_DEFAULT_OPUS_MODEL = "deepseek-v4-pro[1m]"
ANTHROPIC_DEFAULT_SONNET_MODEL = "deepseek-v4-pro[1m]"
ANTHROPIC_DEFAULT_HAIKU_MODEL = "deepseek-v4-flash"
CLAUDE_CODE_SUBAGENT_MODEL = "deepseek-v4-flash"
CLAUDE_CODE_EFFORT_LEVEL = "max"
}
foreach ($name in $envs.Keys) {
$value = $envs[$name]
Set-EnvVar -Name $name -Value $value
Write-Host "Set $name = $value"
}
# Send-EnvChangedBroadcast
}
function Set-EnvVar() {
param (
[string]$name,
[string]$value,
[string]$target = "User" # 可选值: "User" 或 "Machine"
)
$path = if ($target -eq "Machine") {
"HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"
}
else {
"HKCU:\Environment"
}
Set-Item -Path "env:$name" -Value $value
Set-ItemProperty -Path $path -Name $name -Value $value
}
function Remove-EnvVar() {
param (
[string]$name,
[string]$target = "User" # 可选值: "User" 或 "Machine"
)
$path = if ($target -eq "Machine") {
"HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"
}
else {
"HKCU:\Environment"
}
Remove-Item -Path "env:$name"
Remove-ItemProperty -Path $path -Name $name -ErrorAction SilentlyContinue
}
function Send-EnvChangedBroadcast {
$code = @"
using System;
using System.Runtime.InteropServices;
public class WinEnv {
[DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)]
public static extern IntPtr SendMessageTimeout(
IntPtr hWnd, uint Msg, UIntPtr wParam,
string lParam, uint fuFlags, uint uTimeout, out UIntPtr lpdwResult);
}
"@
Add-Type -TypeDefinition $code -ErrorAction SilentlyContinue
$result = [UIntPtr]::Zero
[WinEnv]::SendMessageTimeout(
[IntPtr]0xFFFF, # HWND_BROADCAST
0x001A, # WM_SETTINGCHANGE
[UIntPtr]::Zero,
"Environment",
0x0002, # SMTO_ABORTIFHUNG
1000,
[ref]$result
) | Out-Null
}
main
程序管理
## ── 配置 ──────────────────────────────────────────────
$exePath = ".\xxx.exe"
$exeName = (Get-Item $exePath).BaseName
$logRootDir = ".\logs\std" # 日志根目录
## ──────────────────────────────────────────────────────
function Start-Serv {
# 检查是否已在运行
$existing = Get-Process -Name $exeName -ErrorAction SilentlyContinue
if ($existing) {
Write-Host "⚠ 程序已在运行中(PID: $($existing.Id)),跳过启动"
return
}
# 2. 自动创建日志目录(不存在则创建,避免报错)
if (-not (Test-Path -Path $logRootDir)) {
New-Item -Path $logRootDir -ItemType Directory -Force | Out-Null
Write-Host "日志目录已创建:$logRootDir"
}
# 3. 校验可执行文件是否存在(避免启动失败)
if (-not (Test-Path -Path $exePath -PathType Leaf)) {
Write-Error "错误:可执行文件不存在 → $exePath"
exit 1
}
# # 扩展:自动清理7天前的日志(可选)
# $maxLogAge = 7 # 保留7天内的日志
# Get-ChildItem -Path $logRootDir -Filter "*.log" | Where-Object {
# $_.LastWriteTime -lt (Get-Date).AddDays(-$maxLogAge)
# } | Remove-Item -Force -ErrorAction SilentlyContinue
# Write-Host "已清理 $maxLogAge 天前的旧日志"
# 4. 启动程序(后台运行,重定向日志)
$timestamp = Get-Date -Format "yyyy-MM-dd" # 生成时间戳(精确到秒)
$stdoutLog = Join-Path -Path $logRootDir -ChildPath "${timestamp}_output.log"
$stderrLog = Join-Path -Path $logRootDir -ChildPath "${timestamp}_error.log"
try {
Start-Process -FilePath $exePath `
-RedirectStandardOutput $stdoutLog `
-RedirectStandardError $stderrLog `
-WindowStyle Hidden `
-PassThru | Out-Null # 返回进程对象但不输出,便于后续扩展
Write-Host "✅ 程序已后台启动"
Write-Host "标准输出日志:$stdoutLog"
Write-Host "错误输出日志:$stderrLog"
}
catch {
Write-Error "程序启动失败:$_"
exit 1
}
}
function Get-ServProc {
Get-Process -Name $exeName -ErrorAction SilentlyContinue
}
function Stop-Serv {
param(
[switch]$f
)
$proc = Get-ServProc
if (-not $proc) {
Write-Host "⚠ 程序未在运行"
return
}
if ($f) {
$proc | Stop-Process -Force
Write-Host "⏹ 已强制终止:$exeName(PID: $($proc.Id))"
return
}
# 尝试优雅关闭
# -WindowStyle必须不是Hidden, 比如Minimized
# $proc.CloseMainWindow() | Out-Null
$eventName = "shutdown_pid_$($proc.Id)"
# $event = [System.Threading.EventWaitHandle]::OpenExisting($eventName)
# $event.Set()
# $event.Close()
$pipe = New-Object System.IO.Pipes.NamedPipeClientStream(".", $eventName, [System.IO.Pipes.PipeDirection]::Out)
$pipe.Connect(1000)
$pipe.Close()
$maxWait = 10
for ($i = 1; $i -le $maxWait; $i++) {
if ($proc.HasExited) { break }
Write-Host "⏳ 第 $i/$maxWait 次等待($i 秒)..."
Start-Sleep -Seconds 1
}
if (-not $proc.HasExited) {
Write-Host "⚠ 程序未响应,强制终止..."
$proc | Stop-Process -Force
}
Write-Host "⏹ 已停止:$exeName"
}
function Restart-Serv {
param(
[switch]$f
)
$proc = Get-ServProc
if ($proc) {
Stop-Serv -f:$f
$proc.WaitForExit(10000) | Out-Null
}
Start-Serv
}
function Get-ServStatus {
$proc = Get-Process -Name $exeName -ErrorAction SilentlyContinue
if ($proc) {
$elapsed = (Get-Date) - $proc.StartTime
Write-Host "▶ 运行中"
Write-Host "PID : $($proc.Id)"
Write-Host "启动时间 : $($proc.StartTime)"
Write-Host "已运行 : $([int]$elapsed.TotalHours) 小时 $($elapsed.Minutes) 分钟"
Write-Host "内存占用 : $([math]::Round($proc.WorkingSet64 / 1MB, 1)) MB"
}
else {
Write-Host "⏹ 未运行"
}
}
## ── 入口 ───────────────────────────────────────────────
switch ($args[0]) {
"start" { Start-Serv }
"stop" { Stop-Serv -f:($args -contains "-f") }
"restart" { Restart-Serv -f:($args -contains "-f") }
"status" { Get-ServStatus }
default {
Write-Host "用法: .\start.ps1 [start|stop|restart|status] [-f]"
}
}
启动后台程序
- 不要
-NoNewWindow而是要 -WindowStyle Hidden
- NoNewWindow会导致需要
taskkill /f才能停止进程
## 1. 定义基础配置(方便后续修改)
$exePath = ".\xxxx.exe"
$logRootDir = ".\logs\std" # 日志根目录
$timestamp = Get-Date -Format "yyyy-MM-dd" # 生成时间戳(精确到秒)
$stdoutLog = Join-Path -Path $logRootDir -ChildPath "${timestamp}_output.log"
$stderrLog = Join-Path -Path $logRootDir -ChildPath "${timestamp}_error.log"
## 2. 自动创建日志目录(不存在则创建,避免报错)
if (-not (Test-Path -Path $logRootDir)) {
New-Item -Path $logRootDir -ItemType Directory -Force | Out-Null
Write-Host "日志目录已创建:$logRootDir"
}
## 3. 校验可执行文件是否存在(避免启动失败)
if (-not (Test-Path -Path $exePath -PathType Leaf)) {
Write-Error "错误:可执行文件不存在 → $exePath"
exit 1
}
## # 扩展:自动清理7天前的日志(可选)
## $maxLogAge = 7 # 保留7天内的日志
## Get-ChildItem -Path $logRootDir -Filter "*.log" | Where-Object {
## $_.LastWriteTime -lt (Get-Date).AddDays(-$maxLogAge)
## } | Remove-Item -Force -ErrorAction SilentlyContinue
## Write-Host "已清理 $maxLogAge 天前的旧日志"
## 4. 启动程序(后台运行,重定向日志)
try {
Start-Process -FilePath $exePath `
-RedirectStandardOutput $stdoutLog `
-RedirectStandardError $stderrLog `
-WindowStyle Hidden `
-PassThru | Out-Null # 返回进程对象但不输出,便于后续扩展
Write-Host "start: 程序已后台启动!"
Write-Host "标准输出日志:$stdoutLog"
Write-Host "错误输出日志:$stderrLog"
}
catch {
Write-Error "程序启动失败:$_"
exit 1
}
自动提权管理员
function Invoke-Elevated {
param(
[string]$WorkDir,
[string]$ScriptPath,
[array]$Arguments
)
# 1. 检测当前是否为管理员权限
$currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
$isAdmin = $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
# 2. 非管理员则自动提权重启脚本
if (-not $isAdmin) {
$cmd = @"
cd "$WorkDir"; & '$ScriptPath' $($Arguments -join " ");
"@
$escapedCmd = $cmd -replace '"', '\"'
$arguments = @(
"-NoExit",
"-NoProfile",
"-ExecutionPolicy Bypass",
"-Command", "`"$escapedCmd`""
) -join " "
# 创建管理员权限的进程启动信息
$processStartInfo = New-Object System.Diagnostics.ProcessStartInfo
$processStartInfo.FileName = "powershell.exe"
$processStartInfo.Arguments = $arguments
$processStartInfo.Verb = "runas" # 关键:指定以管理员身份运行
$processStartInfo.WindowStyle = [System.Diagnostics.ProcessWindowStyle]::Normal
try {
# 启动提权进程,会弹出UAC用户账户控制弹窗
[System.Diagnostics.Process]::Start($processStartInfo) | Out-Null
}
catch {
Write-Host "❌ 提权失败!你拒绝了管理员权限请求,脚本无法执行。" -ForegroundColor Red
Pause
exit 1
}
# 原非管理员进程退出,仅保留提权后的新进程
exit 0
}
}
实时关闭windows实时保护
$isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
if (-not $isAdmin) {
Write-Host "⚠️ 请以管理员身份运行此脚本!" -ForegroundColor Red
Pause
exit
}
Write-Host "🔁 开始每 5 秒关闭一次 Windows Defender 实时保护..." -ForegroundColor Cyan
while ($true) {
try {
Set-MpPreference -DisableRealtimeMonitoring $true -ErrorAction Stop
Write-Host "$(Get-Date -Format 'HH:mm:ss') - 实时保护已关闭。"
}
catch {
Write-Host "$(Get-Date -Format 'HH:mm:ss') - 关闭失败: $($_.Exception.Message)" -ForegroundColor Yellow
}
Start-Sleep -Seconds 5
}
<# 打开:
Set-MpPreference -DisableRealtimeMonitoring $false
\#>