![](/img/trans.png)
[英]How to get the IP address of the newly created Azure VM via Powershell
[英]How to get the proper PID of a newly created Firefox window in Powershell?
这是我遇到的问题的一个非常简单的示例:
$process = Start-Process 'C:\Program Files\Mozilla Firefox\firefox.exe' -argumentlist "-new-window https://google.com -foreground" -PassThru
Write-Host $process.Id
firefox window 将按预期启动和工作,它会返回一个进程 ID,但是当我实际检查正在运行的进程时,我看不到该 PID 的任何结果。
我试着添加这个只是为了看看,
while (-not $process.HasExited){
Write-Host "..."
}
Write-Host $process.HasExited
看起来该进程在退出前确实运行了几毫秒。
我认为这可能与 Firefox 如何处理它自己的进程有关。 因为我用其他一些随机应用程序测试了类似的设置,它们都按预期工作。
关于 Firefox 时如何解决这个问题的任何想法?
有几个挑战需要克服:
最终呈现实际浏览器 window 的firefox
进程与最初启动的进程不同。 也就是说,正如您所观察到的,已启动的进程会产生其他进程,并且它自己会快速退出。
正如Olaf指出的那样,现代浏览器通常会启动多个非瞬态进程,因此挑战在于如何识别代表浏览器 window 的进程。
浏览器可能会重用现有进程,因此单个进程可以呈现多个 windows / 选项卡,关闭其中一个不会终止整个进程。
如果您需要确保使用专用的新流程,您有两种选择:
Stop-Process -Name firefox
)。-new-instance
选项启动它,它允许多个独立的 Firefox 实例同时运行,并且可以单独跟踪其生命周期。以下 - 繁琐 - 解决方案实现了选项(b):
如果没有找到firefox
进程,则不用担心创建独立实例,Firefox可以正常启动。
否则,将创建一个临时配置文件,并通过-new-instance
和-profile
选项启动,以确保使用新进程来呈现新浏览器 window。
启动初始进程后,循环直到出现firefox
进程,该进程稍后启动并且具有非空的 window title ,然后假定它是真正感兴趣的进程。
然后,您可以等待此过程的终止,以了解专用浏览器 window 何时关闭。 如果必须创建临时配置文件,则之后会对其进行清理。
# Comment this statement out to silence the verbose messages below.
$VerbosePreference = 'Continue'
$now = Get-Date
$url = 'https://example.org' # URL to open.
# Launch a (new) Firefox instance.
if ($alreadyRunning = [bool] (Get-Process -ErrorAction Ignore firefox)) {
# Determine the path for a temporary profile with a unique name.
$tempProfilePath = Join-Path ([IO.Path]::GetTempPath()) ([datetime]::utcnow.tostring('o') -replace '\D')
Write-Verbose "Firefox is already running. Creating temp. profile $tempProfilePath..."
# Note: Creating an empty directory for the profile is seemingly enough.
$null = New-Item -Type Directory $tempProfilePath
Write-Verbose "and starting a new instance with it..."
Start-Process firefox "-new-instance -profile $tempProfilePath $url"
} else {
Write-Verbose 'Firefox isn''t running. Starting normally...'
Start-Process firefox $url
}
# Find the newly launched process that is the actual browser window.
Write-Verbose 'Waiting for a recently launched Firefox process with a nonempty window title to appear...'
while (-not (
$ps = Get-Process firefox |
Where-Object StartTime -gt $now |
Where-Object MainWindowTitle
)) {
Write-Host -NoNewLine .
Start-Sleep -MilliSeconds 500
}
Write-Host
Write-Verbose "Found. Waiting for process to exit..."
$ps.WaitForExit()
Write-Verbose 'Process has exited.'
if ($alreadyRunning) {
Write-Verbose "Cleaning up temporary profile $tempProfilePath..."
do {
# The profile dir. is typically held on to for a little while longer by associated processes that may not have terminated yet.
Start-Sleep -MilliSeconds 200
Remove-Item -ErrorAction Ignore -Literalpath $tempProfilePath -Recurse -Force
}
while (Test-Path -LiteralPath $tempProfilePath)
}
感谢@mklement0 的工作,在您的情况下,您可以使用父进程 ID。
我使用 WMI 获取父进程,但它适用于第一次启动。
$parentProcess = Start-Process 'C:\Program Files\Mozilla Firefox\firefox.exe' -argumentlist "-new-window https://google.com -foreground" -PassThru
$childProcess = get-process -id $(Get-CimInstance -Class Win32_Process -Filter "Name = 'firefox.exe'" | where {$_.ParentProcessId -eq $parentProcess.id}).ProcessId
# effectively stop the child
$childProcess | Stop-Process
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.