VS Code 与 PS 终端 (第 2 版)

VS Code 与 PS 终端 (第 2 版)

这是我的第二篇帖子。不知何故,原帖被关闭了,没有回复。

我制作了一个小型 PS 表单,试图让我的日常生活更轻松一些。因此,我创建了一个带有 MenuStrip 和一些功能的 PS 表单。在 VS Code 中,我第一次运行它时,MenuStrip 可以工作,但其他功能则不行。它在 PS 终端中的行为方式相同。只有 MenuStrip 可以工作。当我在 VS Code 中第二次运行它时,一切都正常,MenuStrip 和不同的功能集按预期运行。

如果我从 PS 终端运行相同的表单/应用程序(无论它叫什么),它将运行,并且 MenuStrip 操作将按预期执行,就像从 VS Code 运行时一样,但实际任务根本不起作用,无论您通过 PS 终端启动表单的频率如何。我想知道脚本是否必须将程序集加载到会话中,然后这些操作才能起作用。因此,在 VS Code 中运行第二次会成功,因为它从第一次运行中加载了程序集,但每次从 PS 终端运行它时,它都是不同的会话,因此它无法引用程序集?类似于 .NET 在第一次启动时必须“启动”自身的方式。我不知道这是否准确,这就是我在这里的原因。

这是我的第一个 PS 表格,我非常确定代码中有很多地方可以改进,但这里有一个精简版和说明:

  1. 在 VS Code 中,单击以运行脚本。
  2. 点击主页 > 收集信息
  3. 点击功能 > 上次启动时间
  4. 输入要获取上次启动时间的远程系统的名称
  5. 点击按钮

请注意,第一次从 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如果像我这样的人有多个,你当前的尺寸调整方法会导致问题

相关内容