Запустить скрипт в бесконечном цикле с возможностью его остановки - PullRequest
1 голос
/ 24 октября 2019

Я пытаюсь разработать форму из PowerShell, которая контролирует и контролирует выполнение скрипта (в моем случае vbs, но это может быть любой другой) в бесконечном цикле.

Я новичок в PowerShell, поэтомуЯ извиняюсь за структуру кода. Английский язык не является моим родным языком, поэтому я также извиняюсь за ошибки.

Я использую PowerShell, потому что я хочу, чтобы в моей форме были значок и меню на панели задач уведомления Windows. К настоящему времени единственное, что я получил, это значок, но я также получу меню. Это не проблема.

Мне нужна моя форма после нажатия кнопки, чтобы запускать скрипт VisualBasic Script в цикле INFINITE каждые 3 секунды, пока я снова не нажму кнопку (или другую кнопку). Но я получил бесконечный цикл без возможности остановки, потому что после нажатия кнопки форма зависает, потому что она находится внутри цикла do while.

Кто-нибудь знает, как я могу решить мою проблему? главная цель - запускать один и тот же VBS каждые 3 секунды, пока я не захочу его остановить ...

В качестве теста VisualBasic Script, который я пытаюсь запустить с помощью моей программы PowerShell, представляет собой простой MsgBox, который яс именем 'hello.vbs':

MsgBox "hello world"

Для этого я создал 3 файла кода. Он начинается с скрипта VisualBasic с именем 'program.vbs', который вызывает команду PowerShell:

Set WshShell = CreateObject("WScript.Shell")
WshShell.Run chr(34) & "C:\Users\XXX\Desktop\Program\program.bat" & Chr(34), 0
Set WshShell = Nothing

Во-вторых, выполняется летучая мышь с именем 'program.bat', которая вызывает скрипт PowerShell:

powershell -executionpolicy bypass -file "C:\Users\XXX\Desktop\Program\program.ps1"

И, наконец, MAIN Script с именем 'program.ps1' создает форму с инструкциями управления и монитора:

[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")

$functions = {
    function Test() 
    {
        do
        {
            Invoke-Expression "C:\Users\XXX\Desktop\Programita\hello.vbs"
            Start-Sleep -Seconds 2
        }while ($Label2.Text -ne 0)
    }
}

Function Principal {
    $ProgIcon1 = "C:\Users\XXX\Desktop\Program\icon1.ico"
    $ProgIcon2 = "C:\Users\XXX\Desktop\Program\icon2.ico"
    $Form = New-Object System.Windows.Forms.Form
    $ContextMenuProg = New-Object System.Windows.Forms.ContextMenu
    $Menu = New-Object System.Windows.Forms.MenuItem
    $Icon1 = New-Object System.Drawing.Icon ($ProgIcon1)
    $Icon2 = New-Object System.Drawing.Icon ($ProgIcon2)
    $Label1 = New-Object System.Windows.Forms.Label
    $Label2 = New-Object System.Windows.Forms.Label
    $ComButt1 = New-Object System.Windows.Forms.Button
    $ComButt2 = New-Object System.Windows.Forms.Button
    $objNotifyIcon = New-Object System.Windows.Forms.NotifyIcon

    $Form.Text = "Application stopped"

    $Form.Controls.Add($Label1)
    $Form.Controls.Add($Label2)
    $Form.Controls.Add($ComButt1)
    $Form.Controls.Add($ComButt2)

    $Form.Width = 260
    $Form.Height = 180
    $Form.FormBorderStyle = "FixedSingle"
    $Form.MaximizeBox = $False
    $Form.StartPosition = "CenterScreen"
    $Form.Icon = $Icon2

    $Label1.Text = "My first form with icon inside task bar"
    $Label1.Left = 30
    $Label1.Top = 20
    $Label1.AutoSize = $True

    $ComButt1.Text = "Start application"
    $ComButt1.Left = 12
    $ComButt1.Top = 100
    $ComButt1.Width = 102

    $ComButt2.Text = "Close application"
    $ComButt2.Left = 124
    $ComButt2.Top = 100
    $ComButt2.Width = 102
    $ComButt2.Add_Click({
        [System.Windows.Forms.DialogResult]::Cancel
    })
    $ComButt2.DialogResult = [System.Windows.Forms.DialogResult]::Cancel

    $Label2.Text=0
    $ComButt1.Add_Click(
        {
            if ($Label2.Text -eq 0)
            {
                $Form.Text = "Active application"
                $ComButt1.Text = "Application paused"
                $Label2.Text = 1
                $objNotifyIcon.Icon = $ProgIcon1
                $Form.Icon = $ProgIcon1
                #####
                Start-Job -InitializationScript $functions -ScriptBlock {Test} -Name MyJob
                #####
            }else {
                $Form.Text = "Application stopped"
                $ComButt1.Text = "Launch application"
                $Label2.Text = 0
                $objNotifyIcon.Icon = $ProgIcon2
                $Form.Icon = $ProgIcon2
                Remove-Job -Name MyJob -Force
            }
        }
    )

    $Label2.Left = 30
    $Label2.Top = 50
    $Label2.AutoSize = $True

    $objNotifyIcon.Icon = $ProgIcon2
    $objNotifyIcon.ContextMenu = $ContextMenuProg

    $objNotifyIcon.Visible = $True
    $Form.ShowDialog()
    $objNotifyIcon.Visible = $False
}

Principal

Ответы [ 2 ]

3 голосов
/ 24 октября 2019

Могли бы вы использовать Start-Job. Таким образом, ваш графический интерфейс не будет зависать во время работы. Вы можете остановить / удалить задание с помощью Stop-Job / Remove-Job `.

1 голос
/ 24 октября 2019

Попробуйте это:

Class Surrounding_Class
    Private Stop_Flag As Boolean = False

    Private Sub Btn_Handler(ByVal Sender As Object, ByVal e As EventArgs)
        Stop_Flag = Not Stop_Flag
        DoAction()
    End Sub

    Private Sub DoAction()
        Do
        Loop While Stop_Flag = False
    End Sub
End Class
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...