首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带程序到前台或启动它

带程序到前台或启动它
EN

Stack Overflow用户
提问于 2021-12-20 10:17:24
回答 1查看 298关注 0票数 0

对于一些我经常使用的程序,我试图写一些函数或别名来检查这个程序是否已经运行,并把它的窗口放到前台,否则启动这个程序。

np的用法示例,notepad.exe的句柄

代码语言:javascript
复制
PS> np

检查notepad.exe是否正在运行(Get-Process -Name "notepad.exe"),如果没有,它将启动它。当记事本已经在运行,但我的最大控制台在前台时,我想再次执行相同的命令,但这次我希望它将已经运行的记事本进程带到前台,而不是启动一个新的进程。

为了实现这一点,我创建了一个名为Program的类,我将为我想要处理的每个程序实例化这个类。然后我有了这个类的实例的HashTable $knownprograms,最后我尝试为每个程序定义函数,这样我就可以在控制台上输入两个或三个字母来启动一个程序或将其运行的进程带回前台。

代码语言:javascript
复制
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()方法在调用nppt时检查相关进程是否存在。有什么办法做到这一点吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-12-20 11:07:38

notepad.exe的进程名是notepad。更新

代码语言:javascript
复制
$knownprograms.Add("np", [Program]::new(
    "notepad",
    "$Env:SystemRoot\System32",
    "notepad.exe",
    @())
)

这就像预期的一样。

这可能是很有趣的注册$sig一次为所有人,而不是每次调用(这可能会引发一个错误)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70420316

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档