希望有些勇敢的人会帮助我!
我现在正在使用Powershell工具工作几天,该工具在屏幕角上显示一个仪表板,为计算机提供一些网络“实时”诊断。可以在通知区域中最小化此仪表板。
首先,我创建了一个获取诊断并在表单上显示状态的函数。我尝试使用计时器刷新数据(参见:Real Time Data With Powershell GUI)。
问题是我的函数花了太多时间执行并冻结了界面。因此,表单上的按钮不再可用......(请参阅:Mouse event don't work after first timer Tick)。
现在,我尝试使用后台作业。我的想法是以循环模式启动作业并在计时器间隔内获得其状态。
首先,Job无法调用在我的主脚本中声明的函数(第361行)。我知道我可以使用全局和/或不使用函数但直接在ScriptBlock上编写代码但是......即使有了这个,我也不知道如何让作业转入循环并按间隔获取状态(第368行)......
你可以看到我在PowerShell和GUI中没有真正进行过实验......自从我开发以来已经有一段时间了,而且它是用另一种语言...
提前感谢您的帮助
如果你想运行它,我在这里上传了images文件夹: https://omerta.is/2A1L
以下是我的代码
####################################### FUNCTIONS ########################################
#Get diagnostics status
function GetStatus
{
#Create a return table
[hashtable]$Return = @{}
###Test LAN adapter###
$EthernetAdapter = (Get-WMIObject Win32_NetworkAdapter | Select Name, NetConnectionStatus | Where Name -like "*Gigabit*")
If ($EthernetAdapter -ne $null)
{
If ($EthernetAdapter.NetConnectionStatus -eq 2)
{$Return.LANOnStatus = $True}
else
{$Return.LANOnStatus = $False}
}
else
{
$Return.LANOnStatus = $False
}
###Test Wi-Fi adapter###
$WiFiAdapter = (Get-WMIObject Win32_NetworkAdapter | Select Name, NetConnectionStatus | Where Name -like "*Wireless*")
If ($WiFiAdapter -ne $null)
{
If ($WiFiAdapter.NetConnectionStatus -eq 2)
{$Return.WiFiOnStatus = $True}
else
{$Return.WiFiOnStatus = $False}
}
else
{
$Return.WiFiOnStatus = $False
}
###Test Network (Default Gateway Reachable)###
$DefaultGateway = (Get-WmiObject -Class Win32_IP4RouteTable | where { $_.destination -eq '0.0.0.0' -and $_.mask -eq '0.0.0.0'} | Sort-Object metric1 | select nexthop, metric1, interfaceindex).nexthop
If ($DefaultGateway -ne $null)
{
If (Test-Connection -ComputerName $DefaultGateway -Count 1 -TTL 4 -Quiet)
{$Return.NetworkStatus = $True}
else
{$Return.NetworkStatus = $False}
}
else
{
$Return.NetworkStatus = $False
}
#Test Internet connection
$GoogleWebSite = "www.google.com"
Try
{$Return.GoogleStatus = Test-Connection -ComputerName $GoogleWebSite -Count 1 -TTL 64 -Quiet}
Catch
{$Return.GoogleStatus = $False}
###DontReplyToo###
$DontReplyTooWebSite = "mdm.pictet.com"
Try
{$Return.DontReplyTooStatus = Test-Connection -ComputerName $DontReplyTooWebSite -Count 1 -TTL 64 -Quiet}
Catch
{$Return.DontReplyTooStatus = $False}
###DONT REPLY###
$DontReplyWebsite = "www.idontreply.com"
Try
{$Return.DontReplyStatus = Test-Connection -ComputerName $DontReplyWebsite -Count 1 -TTL 64 -Quiet}
Catch
{$Return.DontReplyStatus = $False}
#Return the table
Return $Return
}
########################################### EVENTS ###########################################
#Manual Synchronization
function ManualSync
{
Sync-Content
}
#Open Browser from dashboard
function Open-Browser
{
&($BrowserExe)
}
#Open a help message on click on help icon
function Open-Help($HelpText)
{
[System.Windows.Forms.MessageBox]::Show($HelpText,"Hotlines",0,32)
}
#Close Dashboard form on click on minimize icon
function Minimize-Dashboard
{
#Close Dashboard on click minimize
$Form.WindowState = "Minimize"
$Form.Visible = $False
$objNotifyIcon.Visible = $True
#!!!!! TO CHECK !!!!!
Wait-Event -Timeout 15 -SourceIdentifier NotifyIcon_Event
Remove-Event -SourceIdentifier NotifyIcon_Event
}
#Open Dashboard form on double click on agent icon in notification area
function OpenDashboard
{
#Open Dashboard on double-click
$Form.Visible = $True
$Form.WindowState = "Normal"
}
######################################### ASSEMBLIES #########################################
[void] [Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void] [Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Timers")
[void] [System.Windows.Forms.Application]::EnableVisualStyles()
######################################### VAR & CONST ########################################
#Screen placement
$Screen = [system.windows.forms.screen]::PrimaryScreen
$FormPos = $Screen.Bounds.Width - 160
#Dashboard Timer
$Timer = New-Object 'System.Windows.Forms.Timer'
$Timer.Interval = 3000
#Home directory of the program
$HomeDir = Split-Path $script:MyInvocation.MyCommand.Path
#Dashboard Images
$Background = [system.drawing.image]::FromFile("$HomeDir\img\interface.png")
$GreenLight = [system.drawing.image]::FromFile("$HomeDir\img\greenlight.png")
$RedLight = [system.drawing.image]::FromFile("$HomeDir\img\redlight.png")
$SyncImg = [system.drawing.image]::FromFile("$HomeDir\img\sync.png")
$BrowserImg = [system.drawing.image]::FromFile("$HomeDir\img\browser.png")
$HelpImg = [system.drawing.image]::FromFile("$HomeDir\img\help.png")
$MinimizeImg = [system.drawing.image]::FromFile("$HomeDir\img\minimize.png")
#Agent Images
$IconStd = New-Object system.drawing.icon ("$HomeDir\img\icon.ico")
$IconFocus = New-Object system.drawing.icon ("$HomeDir\img\icon_focus.ico")
#Log files
$LogLastSync = ("$HomeDir\Logs\LastSync.log")
$LogSyncAgent = ("$HomeDir\Logs\SyncAgentError.log")
#Browser Module
$BrowserExe = "$HomeDir\bin\Browser.exe"
#Free File Sync Module
$SyncAgentExe = "$HomeDir\bin\SyncAgent.exe"
$SyncJob = "$HomeDir\bin\SyncSettings.xml"
#Strings
$HelpText = "Hotline: 432423432423423"
########################################### FORMS ###########################################
#Dashboard Windows Forms
$Form = New-Object System.Windows.Forms.Form
$Font = New-Object System.Drawing.Font("Arial Unicode MS",10,[System.Drawing.FontStyle]::Bold)
$Lb_LANOn = New-Object System.Windows.Forms.Label
$Lb_WiFiOn = New-Object System.Windows.Forms.Label
$Lb_Network = New-Object System.Windows.Forms.Label
$Lb_Google = New-Object System.Windows.Forms.Label
$Lb_DontReplyToo = New-Object System.Windows.Forms.Label
$Lb_DontReply = New-Object System.Windows.Forms.Label
$Pb_LANOn = New-Object System.Windows.Forms.PictureBox
$Pb_WiFiOn = New-Object System.Windows.Forms.PictureBox
$Pb_Network = New-Object System.Windows.Forms.PictureBox
$Pb_Google = New-Object System.Windows.Forms.PictureBox
$Pb_DontReplyToo = New-Object System.Windows.Forms.PictureBox
$Pb_DontReply = New-Object System.Windows.Forms.PictureBox
$Pb_Sync = New-Object System.Windows.Forms.PictureBox
$Pb_Browser = New-Object System.Windows.Forms.PictureBox
$Pb_Help = New-Object System.Windows.Forms.PictureBox
$Pb_Minimize = New-Object System.Windows.Forms.PictureBox
#Agent Windows Form
$objNotifyIcon = New-Object System.Windows.Forms.NotifyIcon
$objNotifyIcon.Add_Click({OpenDashboard})
Register-ObjectEvent $objNotifyIcon Click NotifyIcon_Event
#Dashboard Interface Generation
$Form.Size = '150, 220'
$Form.FormBorderStyle = 'None'
$Form.Name = "Form"
$Form.StartPosition = 'Manual'
$Form.Location = $FormPos.ToString()+', 10'
$Form.Text = "Dashboard"
$Form.Font = $Font
$Form.BackgroundImage = $Background
$Form.BackgroundImageLayout = "None"
$Form.TransparencyKey = "White"
$Form.BackColor = "White"
#$Form.Opacity = '.85'
$Form.Controls.Add($Lb_LANOn)
$Lb_LANOn.Location = '10, 30'
$Lb_LANOn.Size = '75, 20'
$Lb_LANOn.Text = "LAN On"
$Lb_LANOn.ForeColor = 'Gray'
$Lb_LANOn.BackColor = "Transparent"
$Form.Controls.Add($Lb_WiFiOn)
$Lb_WiFiOn.Location = '10, 55'
$Lb_WiFiOn.Size = '75, 20'
$Lb_WiFiOn.Text = "Wi-Fi On"
$Lb_WiFiOn.ForeColor = 'Gray'
$Lb_WiFiOn.BackColor = "Transparent"
$Form.Controls.Add($Lb_Network)
$Lb_Network.Location = '10, 80'
$Lb_Network.Size = '75, 20'
$Lb_Network.Text = "Network"
$Lb_Network.ForeColor = 'Gray'
$Lb_Network.BackColor = "Transparent"
$Form.Controls.Add($Lb_Google)
$Lb_Google.Location = '10, 105'
$Lb_Google.Size = '75, 20'
$Lb_Google.Text = "Google"
$Lb_Google.ForeColor = 'Gray'
$Lb_Google.BackColor = "Transparent"
$Form.Controls.Add($Lb_DontReplyToo)
$Lb_DontReplyToo.Location = '10, 130'
$Lb_DontReplyToo.Size = '75, 20'
$Lb_DontReplyToo.Text = "DontReplyToo"
$Lb_DontReplyToo.ForeColor = 'Gray'
$Lb_DontReplyToo.BackColor = "Transparent"
$Form.Controls.Add($Lb_DontReply)
$Lb_DontReply.Location = '10, 155'
$Lb_DontReply.Size = '75, 20'
$Lb_DontReply.Text = "Dont Reply"
$Lb_DontReply.ForeColor = 'Gray'
$Lb_DontReply.BackColor = "Transparent"
$Form.Controls.Add($Pb_LANOn)
$Pb_LANOn.Location = '115, 33'
$Pb_LANOn.Size = '15, 15'
$Pb_LANOn.Image = $RedLight
$Pb_LANOn.BackColor = "Transparent"
$Form.Controls.Add($Pb_WiFiOn)
$Pb_WiFiOn.Location = '115, 58'
$Pb_WiFiOn.Size = '15, 15'
$Pb_WiFiOn.Image = $RedLight
$Pb_WiFiOn.BackColor = "Transparent"
$Form.Controls.Add($Pb_Network)
$Pb_Network.Location = '115, 83'
$Pb_Network.Size = '15, 15'
$Pb_Network.Image = $RedLight
$Pb_Network.BackColor = "Transparent"
$Form.Controls.Add($Pb_Google)
$Pb_Google.Location = '115, 108'
$Pb_Google.Size = '15, 15'
$Pb_Google.Image = $RedLight
$Pb_Google.BackColor = "Transparent"
$Form.Controls.Add($Pb_DontReplyToo)
$Pb_DontReplyToo.Location = '115, 133'
$Pb_DontReplyToo.Size = '15, 15'
$Pb_DontReplyToo.Image = $RedLight
$Pb_DontReplyToo.BackColor = "Transparent"
$Form.Controls.Add($Pb_DontReply)
$Pb_DontReply.Location = '115, 158'
$Pb_DontReply.Size = '15, 15'
$Pb_DontReply.Image = $RedLight
$Pb_DontReply.BackColor = "Transparent"
#Toolbar
$Form.Controls.Add($Pb_Sync)
$Pb_Sync.Location = '20, 195'
$Pb_Sync.Size = '20, 20'
$Pb_Sync.Image = $SyncImg
$Pb_Sync.BackColor = "Transparent"
$Pb_Sync.Add_Click({Sync-Content})
$Form.Controls.Add($Pb_Browser)
$Pb_Browser.Location = '51, 195'
$Pb_Browser.Size = '20, 20'
$Pb_Browser.Image = $BrowserImg
$Pb_Browser.BackColor = "Transparent"
$Pb_Browser.Add_Click({Open-Browser})
$Form.Controls.Add($Pb_Help)
$Pb_Help.Location = '82, 195'
$Pb_Help.Size = '20, 20'
$Pb_Help.Image = $HelpImg
$Pb_Help.BackColor = "Transparent"
$Pb_Help.Add_Click({Open-Help($HelpText)})
$Form.Controls.Add($Pb_Minimize)
$Pb_Minimize.Location = '113, 195'
$Pb_Minimize.Size = '20, 20'
$Pb_Minimize.Image = $MinimizeImg
$Pb_Minimize.BackColor = "Transparent"
$Pb_Minimize.Add_Click({Minimize-Dashboard})
########## MAIN
#Status Init
#$Status = GetStatus
#Create the Status Background Job
Start-Job -Name "jobGetStatus" -ScriptBlock {$Status = GetStatus} #function not recognized by Background Job
#Wait for job result
While (Get-Job -Name "jobGetStatus" | where { $_.State -eq "Running" })
{Start-Sleep 1}
#Get Status on Timer Tick
$Timer.Add_Tick({Get-Job -Name "jobGetStatus" | Receive-Job}) #job not updated
#Display new status on tick
$Timer.Add_Tick({
#LAN
If ($Status.LANOnStatus -eq $True)
{$Pb_LANOn.Image = $GreenLight}
else
{$Pb_LANOn.Image = $RedLight}
#WIFI
If ($Status.WiFiOnStatus -eq $True)
{$Pb_WiFiOn.Image = $GreenLight}
else
{$Pb_WiFiOn.Image = $RedLight}
#NETWORK
If ($Status.NetworkStatus -eq $True)
{$Pb_Network.Image = $GreenLight}
else
{$Pb_Network.Image = $RedLight}
#GOOGLE
If ($Status.GoogleStatus -eq $True)
{$Pb_Google.Image = $GreenLight}
else
{$Pb_Google.Image = $RedLight}
#DontReplyToo
If ($Status.DontReplyTooStatus -eq $True)
{$Pb_DontReplyToo.Image = $GreenLight}
else
{$Pb_DontReplyToo.Image = $RedLight}
#BING
If ($Status.DontReplyStatus -eq $True)
{$Pb_DontReply.Image = $GreenLight}
else
{$Pb_DontReply.Image = $RedLight}
})
#Start Timer
$Timer.Enabled = $True
#Agent Init
$objNotifyIcon.Icon = $IconStd
$objNotifyIcon.Text = "Dashboard"
$objNotifyIcon.Visible = $True
#Show Interface
$Form.ShowDialog()
############## END
答案 0 :(得分:1)
很好的小实用程序。
我删除了对Job
的所有引用,并将作业中的代码添加到Tick本身:
$Timer.Add_Tick({
$Status = GetStatus
#LAN
If ($Status.LANOnStatus -eq $True)
{$Pb_LANOn.Image = $GreenLight}
else
{$Pb_LANOn.Image = $RedLight}
...
})
由于您提到该功能花费了太多时间,我还将Tick间隔从3秒增加到10秒。这似乎在我的电脑上运行良好。