对于一些我经常使用的程序,我试图写一些函数或别名来检查这个程序是否已经运行,并把它的窗口放到前台,否则启动这个程序。
np的用法示例,notepad.exe的句柄
PS> np检查notepad.exe是否正在运行(Get-Process -Name "notepad.exe"),如果没有,它将启动它。当记事本已经在运行,但我的最大控制台在前台时,我想再次执行相同的命令,但这次我希望它将已经运行的记事本进程带到前台,而不是启动一个新的进程。
为了实现这一点,我创建了一个名为Program的类,我将为我想要处理的每个程序实例化这个类。然后我有了这个类的实例的HashTable $knownprograms,最后我尝试为每个程序定义函数,这样我就可以在控制台上输入两个或三个字母来启动一个程序或将其运行的进程带回前台。
class Program {
[string]$Name
[string]$Path
[string]$Executable
[string[]]$Arguments
Program(
[string]$n,
[string]$p,
[string]$e,
[string[]]$a
){
$this.Name = $n
$this.Path = $p
$this.Executable = $e
$this.Arguments = $a
}
[string]FullPath(){
return ("{0}\{1}" -f $this.Path, $this.Executable)
}
[void]ShowOrStart(){
try {
# Adapted from https://community.idera.com/database-tools/powershell/powertips/b/tips/posts/bringing-window-in-the-foreground
$Process = Get-Process -Name $this.Name -ErrorAction Stop
Write-Host "Found at least one process called $this.Name"
$sig = '
[DllImport("user32.dll")] public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
[DllImport("user32.dll")] public static extern int SetForegroundWindow(IntPtr hwnd);
'
$Mode = 4 # Will restore the window, not maximize it
$type = Add-Type -MemberDefinition $sig -Name WindowAPI -PassThru
$hwnd = $process.MainWindowHandle
$null = $type::ShowWindowAsync($hwnd, $Mode)
$null = $type::SetForegroundWindow($hwnd)
} catch [Microsoft.PowerShell.Commands.ProcessCommandException] {
Write-Host "Did not find any process called $this.Name"
Invoke-Command -ScriptBlock { & $this.FullPath() $this.Arguments }
}
}
}
$knownprograms = @{}
$knownprograms.Add("np", [Program]::new(
"np",
"$Env:SystemRoot\System32",
"notepad.exe",
@())
)
$knownprograms.Add("pt", [Program]::new(
"pt",
"$Env:SystemRoot\System32",
"mspaint.exe",
@())
)
Function np {
[cmdletbinding()]
Param()
$knownprograms.np.ShowOrStart()
}
Function pt {
[cmdletbinding()]
Param()
$knownprograms.pt.ShowOrStart()
}我的想法是,我将在我的profile.ps1中获取这个脚本,然后使用预分解的函数。但是,这段代码似乎总是打开程序的一个新实例,而不是使用它正在运行的过程。也许我需要某种延迟的评估,以便ShowOrStart()方法在调用np或pt时检查相关进程是否存在。有什么办法做到这一点吗?
发布于 2021-12-20 11:07:38
notepad.exe的进程名是notepad。更新
$knownprograms.Add("np", [Program]::new(
"notepad",
"$Env:SystemRoot\System32",
"notepad.exe",
@())
)这就像预期的一样。
这可能是很有趣的注册$sig一次为所有人,而不是每次调用(这可能会引发一个错误)。
https://stackoverflow.com/questions/70420316
复制相似问题