Powershell新人
Powershell newcomer
我是 Powershell 的新手,所以如果我的问题听起来很愚蠢,请原谅我。我从 Yuri Posidelov 找到了下面的脚本,我对其进行了调整以激活一个进程并显示 window 并发送击键以关闭运行良好的进程。但是,如果有两个同名的进程,它会失败任何人都可以帮我解决这个问题。
Yuriy Posidelov 的原始代码
param([string] $proc="SBDDesktop", [string]$adm)
cls
Add-Type @"
using System;
using System.Runtime.InteropServices;
public class WinAp {
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
}
"@
$p = Get-Process |where {$_.mainWindowTItle }|where {$_.Name -like "$proc"}
if (($p -eq $null) -and ($adm -ne ""))
{
Start-Process "$proc" -Verb runAs
}
elseif (($p -eq $null) -and ($adm -eq ""))
{
Start-Process "$proc" #-Verb runAs
}
else
{
$h = $p.MainWindowHandle
[void] [WinAp]::SetForegroundWindow($h)
[void] [WinAp]::ShowWindow($h,3);
$wshell = New-Object -ComObject wscript.shell;
#$wshell.SendKeys('~')
$wshell.SendKeys('%fx')
sleep 1
$wshell.SendKeys('N')
}
#|format-table id,name,mainwindowtitle –AutoSize
# static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
# powershell.exe -windowstyle hidden -file *.ps1 -adm "a"
问题是,如果有多个进程,行 $p = Get-Process |where {$_.mainWindowTItle }|where {$_.Name -like "$proc"}
将创建一个 array
类型的对象。否则它将创建一个 System.ComponentModel.Component
类型的对象。您可以使用以下方法进行测试:
$p.GetType()
为了弥补这一点,即使该数组中只有一个元素,您也可以在数组中执行代码 foreach
过程:
...
[array]$array = Get-Process |where {$_.mainWindowTItle }|where {$_.Name -like "$proc"}
foreach ($p in $array){
if (($p -eq $null) -and ($adm -ne ""))
{
Start-Process "$proc" -Verb runAs
}
elseif (($p -eq $null) -and ($adm -eq ""))
{
Start-Process "$proc" #-Verb runAs
}
else
{
$h = $p.MainWindowHandle
[void] [WinAp]::SetForegroundWindow($h)
[void] [WinAp]::ShowWindow($h,3);
$wshell = New-Object -ComObject wscript.shell;
#$wshell.SendKeys('~')
$wshell.SendKeys('%fx')
sleep 1
$wshell.SendKeys('N')
}
#|format-table id,name,mainwindowtitle –AutoSize
# static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
# powershell.exe -windowstyle hidden -file *.ps1 -adm "a"
}
如果有多个窗口句柄,则循环:
$processList = [object[]]@( Get-Process |where {$_.mainWindowTItle }|where {$_.Name -like "$proc"} )
foreach( $p in $processList ) {
if (($p -eq $null) -and ($adm -ne "")) {
Start-Process "$proc" -Verb runAs
}
elseif (($p -eq $null) -and ($adm -eq "")) {
Start-Process "$proc" #-Verb runAs
}
else {
$h = $p.MainWindowHandle
[WinAp]::SetForegroundWindow($h) | Out-Null
[WinAp]::ShowWindow($h,3) | Out-Null
$wshell = New-Object -ComObject wscript.shell;
#[void]$wshell.SendKeys('~')
[void]$wshell.SendKeys('%fx')
sleep 1 | Out-Null
[void]$wshell.SendKeys('N')
}
}
Get-Process
将 return 所有符合您条件的进程,这意味着它将 return 多个对象到变量 $p
.
所以你需要遍历它们你可以简单地使用foreach
循环
foreach($process in $p){
if (($process -eq $null) -and ($adm -ne ""))
{
Start-Process "$proc" -Verb runAs
}
elseif (($$process -eq $null) -and ($adm -eq ""))
{
Start-Process "$proc" #-Verb runAs
}
else
{
$h = $process.MainWindowHandle
[void] [WinAp]::SetForegroundWindow($h)
[void] [WinAp]::ShowWindow($h,3);
$wshell = New-Object -ComObject wscript.shell;
#$wshell.SendKeys('~')
$wshell.SendKeys('%fx')
sleep 1
$wshell.SendKeys('N')
}
}
我是 Powershell 的新手,所以如果我的问题听起来很愚蠢,请原谅我。我从 Yuri Posidelov 找到了下面的脚本,我对其进行了调整以激活一个进程并显示 window 并发送击键以关闭运行良好的进程。但是,如果有两个同名的进程,它会失败任何人都可以帮我解决这个问题。
Yuriy Posidelov 的原始代码
param([string] $proc="SBDDesktop", [string]$adm)
cls
Add-Type @"
using System;
using System.Runtime.InteropServices;
public class WinAp {
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
}
"@
$p = Get-Process |where {$_.mainWindowTItle }|where {$_.Name -like "$proc"}
if (($p -eq $null) -and ($adm -ne ""))
{
Start-Process "$proc" -Verb runAs
}
elseif (($p -eq $null) -and ($adm -eq ""))
{
Start-Process "$proc" #-Verb runAs
}
else
{
$h = $p.MainWindowHandle
[void] [WinAp]::SetForegroundWindow($h)
[void] [WinAp]::ShowWindow($h,3);
$wshell = New-Object -ComObject wscript.shell;
#$wshell.SendKeys('~')
$wshell.SendKeys('%fx')
sleep 1
$wshell.SendKeys('N')
}
#|format-table id,name,mainwindowtitle –AutoSize
# static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
# powershell.exe -windowstyle hidden -file *.ps1 -adm "a"
问题是,如果有多个进程,行 $p = Get-Process |where {$_.mainWindowTItle }|where {$_.Name -like "$proc"}
将创建一个 array
类型的对象。否则它将创建一个 System.ComponentModel.Component
类型的对象。您可以使用以下方法进行测试:
$p.GetType()
为了弥补这一点,即使该数组中只有一个元素,您也可以在数组中执行代码 foreach
过程:
...
[array]$array = Get-Process |where {$_.mainWindowTItle }|where {$_.Name -like "$proc"}
foreach ($p in $array){
if (($p -eq $null) -and ($adm -ne ""))
{
Start-Process "$proc" -Verb runAs
}
elseif (($p -eq $null) -and ($adm -eq ""))
{
Start-Process "$proc" #-Verb runAs
}
else
{
$h = $p.MainWindowHandle
[void] [WinAp]::SetForegroundWindow($h)
[void] [WinAp]::ShowWindow($h,3);
$wshell = New-Object -ComObject wscript.shell;
#$wshell.SendKeys('~')
$wshell.SendKeys('%fx')
sleep 1
$wshell.SendKeys('N')
}
#|format-table id,name,mainwindowtitle –AutoSize
# static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
# powershell.exe -windowstyle hidden -file *.ps1 -adm "a"
}
如果有多个窗口句柄,则循环:
$processList = [object[]]@( Get-Process |where {$_.mainWindowTItle }|where {$_.Name -like "$proc"} )
foreach( $p in $processList ) {
if (($p -eq $null) -and ($adm -ne "")) {
Start-Process "$proc" -Verb runAs
}
elseif (($p -eq $null) -and ($adm -eq "")) {
Start-Process "$proc" #-Verb runAs
}
else {
$h = $p.MainWindowHandle
[WinAp]::SetForegroundWindow($h) | Out-Null
[WinAp]::ShowWindow($h,3) | Out-Null
$wshell = New-Object -ComObject wscript.shell;
#[void]$wshell.SendKeys('~')
[void]$wshell.SendKeys('%fx')
sleep 1 | Out-Null
[void]$wshell.SendKeys('N')
}
}
Get-Process
将 return 所有符合您条件的进程,这意味着它将 return 多个对象到变量 $p
.
所以你需要遍历它们你可以简单地使用foreach
循环
foreach($process in $p){
if (($process -eq $null) -and ($adm -ne ""))
{
Start-Process "$proc" -Verb runAs
}
elseif (($$process -eq $null) -and ($adm -eq ""))
{
Start-Process "$proc" #-Verb runAs
}
else
{
$h = $process.MainWindowHandle
[void] [WinAp]::SetForegroundWindow($h)
[void] [WinAp]::ShowWindow($h,3);
$wshell = New-Object -ComObject wscript.shell;
#$wshell.SendKeys('~')
$wshell.SendKeys('%fx')
sleep 1
$wshell.SendKeys('N')
}
}