这是我的第二篇帖子。不知何故,原帖被关闭了,没有回复。
我制作了一个小型 PS 表单,试图让我的日常生活更轻松一些。因此,我创建了一个带有 MenuStrip 和一些功能的 PS 表单。在 VS Code 中,我第一次运行它时,MenuStrip 可以工作,但其他功能则不行。它在 PS 终端中的行为方式相同。只有 MenuStrip 可以工作。当我在 VS Code 中第二次运行它时,一切都正常,MenuStrip 和不同的功能集按预期运行。
如果我从 PS 终端运行相同的表单/应用程序(无论它叫什么),它将运行,并且 MenuStrip 操作将按预期执行,就像从 VS Code 运行时一样,但实际任务根本不起作用,无论您通过 PS 终端启动表单的频率如何。我想知道脚本是否必须将程序集加载到会话中,然后这些操作才能起作用。因此,在 VS Code 中运行第二次会成功,因为它从第一次运行中加载了程序集,但每次从 PS 终端运行它时,它都是不同的会话,因此它无法引用程序集?类似于 .NET 在第一次启动时必须“启动”自身的方式。我不知道这是否准确,这就是我在这里的原因。
这是我的第一个 PS 表格,我非常确定代码中有很多地方可以改进,但这里有一个精简版和说明:
- 在 VS Code 中,单击以运行脚本。
- 点击主页 > 收集信息
- 点击功能 > 上次启动时间
- 输入要获取上次启动时间的远程系统的名称
- 点击按钮
请注意,第一次从 VS Code 中运行脚本时,它不起作用。菜单项会执行它们需要执行的操作,但不会获取上次启动时间。
当您从 VS Code 中第二次运行它时(按照上述相同的步骤),它将获取远程系统的上次启动时间并输出结果。
如果您从 PS 终端运行 ps1,菜单功能可以运行,但无论您运行多少次,获取上次启动时间的操作都不会运行。
我的最终目标是将其打包为可执行文件,并让整个程序在第一次加载时运行。有谁知道如何让这个小家伙按预期工作吗?
# Load external assemblies
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
[System.Windows.Forms.Application]::EnableVisualStyles()
#Get the screen resolution dimentions for dynamic main form sizing
$res = Get-CimInstance CIM_VideoController | Select CurrentHorizontalResolution, CurrentVerticalResolution
# ****************************************************
# **************Begin Menu Creation*******************
# ****************************************************
#Instantiate the menu strip object
$MS_Main = new-object System.Windows.Forms.MenuStrip
#Create Home menu items
$HomeMenu = new-object System.Windows.Forms.ToolStripMenuItem
$HomeGatherMenu = new-object System.Windows.Forms.ToolStripMenuItem
# Home menu buildout - This adds all the items to the HomeMenu menu
$HomeMenu.DropDownItems.AddRange(@($HomeGatherMenu))
$HomeMenu.Name = "HomeMenu"
$HomeMenu.Size = new-object System.Drawing.Size(35, 20)
$HomeMenu.Text = "&Home"
#Create Function menu items
$FunctionMenu = new-object System.Windows.Forms.ToolStripMenuItem
# ******* Gather Menu Items
$FunctionGLastBootMenu = new-object System.Windows.Forms.ToolStripMenuItem
# Function Menu buildout - This adds all the items to the FunctionMenu menu
$FunctionMenu.DropDownItems.AddRange(@($FunctionGLastBootMenu))
$FunctionMenu.Name = "FunctionMenu"
$FunctionMenu.Size = new-object System.Drawing.Size(75, 20)
$FunctionMenu.Text = "&Function"
# Menu Strip Main (MS_Main) setup
# This will add the Home, Function and Help/About menu items to the menu bar
$MS_Main.Items.AddRange(@($HomeMenu,$FunctionMenu))
$MS_Main.Location = new-object System.Drawing.Point(0, 0)
$MS_Main.Name = "MS_Main"
$MS_Main.Size = new-object System.Drawing.Size(354, 24)
$MS_Main.TabIndex = 0
$MS_Main.Text = "menuStrip1"
# ****************************************************
# ************** End Menu Creation *******************
# ****************************************************
# ****************************************************
# **** Begin Menu Item Creation and Implementation ***
# ****************************************************
# *********** Home Menu Item Buildout ***********
# HomeGatherMenu
$HomeGatherMenu.Name = "HomeGatherMenu"
$HomeGatherMenu.Size = new-object System.Drawing.Size(152, 22)
$HomeGatherMenu.Text = "&Gather Information"
$HomeGatherMenu.Add_Click( { OnClick_HomeGatherMenu $HomeGatherMenu $EventArgs} )
function OnClick_HomeGatherMenu($Sender,$e){
# ******** Show Gather Menu
$FunctionGLastBootMenu.Visible = $true
}
# ****** FUNCTION MENU ***********
# Populate the Function menu with the contextual functions
$FunctionGLastBootMenu.Name = "FunctionGLastBootMenu"
$FunctionGLastBootMenu.Size = New-Object System.Drawing.Size(152, 22)
$FunctionGLastBootMenu.Text = "&Last Boot Time"
$FunctionGLastBootMenu.Visible = $false
$FunctionGLastBootMenu.Add_Click({ OnClick_FunctionGLastBootMenu $FunctionGLastBootMenu $EventArgs})
# ****************************************************
# **** End Menu Item Creation and Implementation *****
# ****************************************************
# Create the main form for the app
$YAYMainForm = new-object System.Windows.Forms.form
$YAYMainForm.ClientSize = new-object System.Drawing.Size(($res.CurrentHorizontalResolution / 2), ($res.CurrentVerticalResolution / 1.75))
$YAYMainForm.Controls.Add($MS_Main)
$YAYMainForm.MainMenuStrip = $MS_Main
$YAYMainForm.BackgroundImage = $Image
$YAYMainForm.BackgroundImageLayout = "None"
$YAYMainForm.FormBorderStyle = 1
$YAYMainForm.MaximizeBox = $false
$YAYMainForm.Name = "YAYMainForm"
$YAYMainForm.BackColor = "#eeeeee"
#*******Create BTNGet (CONSTANT)*******
$BTNGet = New-Object system.Windows.Forms.Button
#$BTNGet.text = "Fetch"
$BTNGet.height=25
$BTNGet.width=75
$BTNGet.AutoSize = $true
$BTNGet.top= 73
$BTNGet.left=135
$BTNGet.BackColor = "#E6F3FF"
$BTNGet.Visible = $false
$BTNGet.add_click($BTNGetClick)
$YAYMainForm.controls.add($BTNGet)
#*******End button 1*******
#*******Status Label*****
# Placement needs to stay static
$LBLStatus = New-Object System.Windows.Forms.Label
$LBLStatus.Width = 40
$LBLStatus.Height = 20
$LBLStatus.top = 165
$LBLStatus.left = 26
$LBLStatus.visible = $true
$LBLStatus.text = "Status: "
$LBLStatus.BackColor = "#777777"
$LBLStatus.ForeColor = "#ffffff"
#*******End Status label********
#*******Status Output Label*****
# Placement needs to stay static
$LBLStatusOut = New-Object System.Windows.Forms.Label
#$LBLStatusOut.AutoSize = $true
$LBLStatusOut.Width = $res.CurrentHorizontalResolution / 2.212
$LBLStatusOut.Height = 20
$LBLStatusOut.top = 165
$LBLStatusOut.left = 67
$LBLStatusOut.visible = $true
$LBLStatusOut.BackColor = "#f6fcf5"
#*******End Status Output label********
#*******Host Name Label (CONSTANT)*****
$LBLHostName = New-Object System.Windows.Forms.Label
$LBLHostName.AutoSize = $true
$LBLHostName.top = 55
$LBLHostName.left = 26
$LBLHostName.Text = "Host Name:"
$LBLHostName.visible = $false
#*******End Host Name Label********
#*******Host Name Textbox*****
$TBHostName = New-object System.Windows.Forms.TextBox
$TBHostName.top = 75
$TBHostName.Left = 26
$TBHostName.BorderStyle = 1
$TBHostName.Visible = $false
$YAYMainForm.Controls.add($TBHostName)
#*******End Textbox 1********
# This next line adds the various labels to the form.
$YAYMainForm.Controls.AddRange(@($LBLStatusOut,$LBLHostName, $LBLStatus))
#********** Button Clicks **********
$BTNGetClick = {
$MethodSeed = $GLOBAL:BTNGetText
BTNGetRun -MethodSeed $MethodSeed
}
#********** END Buttn Clicks *******
#***********************************
#********** Button functions ***********
function BTNSeed ($ValueSeed) {
Switch ($ValueSeed){
"GLB" {$GLOBAL:BTNGetText = "Get Last Boot Time"}
} #End Switch
} #End Function
function BTNGetRun ($MethodSeed){
Switch ($MethodSeed){
"Get Last Boot Time" {
try {
$LBLStatusOut.Text = "Figuring out when this guy was last rebooted. Stay tuned..."
$GLBT = gcim -ComputerName $TBHostName.Text Win32_OperatingSystem
$TXTOutPut.text = ($TBHostName.text+" was last booted: "+$GLBT.LastBootUpTime)
$LBLStatusOut.Text = "Complete. Last boot information is below."
}
catch {
$LBLStatusOut.text = "An error occurred: see the message below."
$TXTOutPut.text = $_
}
} #END Last Boot Try/catch
}
}
#********** END Button functions ***********
#*******************************************
#*******************************************
#************* Menu functions ***************
function OnClick_FunctionGLastBootMenu{
#Set the seed for the button text value
$ValueSeed = "GLB"
#Call the function to get the BTNGET text
BTNSeed -ValueSeed $ValueSeed
#Set the BTNGet text value
$BTNGet.Text = $GLOBAL:BTNGetText
$BTNGet.Visible = $true
$TBHostName.Visible = $true
$LBLHostName.Visible = $true
}
#*********************************************
#***********END Menu Functions****************
#*********************************************
#*******Informational Output TextArea*****
$TXTOutPut = New-Object System.Windows.Forms.TextBox
$TXTOutPut.AutoSize = $true
$TXTOutPut.Height = ($res.CurrentVerticalResolution / 2.6)
$TXTOutPut.Width = ($res.CurrentHorizontalResolution / 2.11)
$TXTOutPut.multiline = $True
$TXTOutPut.scrollbars = "Vertical, Horizontal"
$TXTOutPut.Font="Lucida Console"
$TXTOutPut.wordwrap = $false
$TXTOutPut.top = 190
$TXTOutPut.left = 25
$YAYMainForm.Controls.Add($TXTOutPut)
#*******EndInformational Output TextArea********
function OnFormClosing_YAYMainForm($Sender,$e){
# $this represent sender (object)
# $_ represent e (eventarg)
# Allow closing
($_).Cancel= $False
}
$YAYMainForm.Add_FormClosing( { OnFormClosing_YAYMainForm $YAYMainForm $EventArgs} )
$YAYMainForm.Add_Shown({$YAYMainForm.Activate()})
$YAYMainForm.ShowDialog()
#Free ressources
$YAYMainForm.Dispose()
答案1
如果某些代码只能在第二次运行,那么很可能是因为代码定义顺序错误。我发现了以下代码:
$BTNGet.add_click($BTNGetClick)
$BTNGetClick
在被设定之前被执行
#********** Button Clicks **********
$BTNGetClick = {
因此,表单在首次启动时点击后将运行空操作。
重新排序这些部分后,function BTNSeed (
表格即可正确初始化所有内容并第一次运行。
附注:$res = Get-CimInstance CIM_VideoController
如果像我这样的人有多个,你当前的尺寸调整方法会导致问题