Выполнять Robocopy foreach папку в массиве - ТОЛЬКО если установлен соответствующий флажок? - PullRequest
0 голосов
/ 04 июня 2019

У нас есть форма PowerShell с кнопками и флажками, а также текстовое поле для отображения вывода; У нас есть 3 флажка, помеченных как «folder1», «folder2» и «folder3». У нас есть кнопка для запуска Robocopy (без цикла ForEach) У нас есть текстовое поле, которое отображает весь вывод скрипта ПРИМЕЧАНИЕ: это уже работает отлично; мы просто хотим сделать это с помощью цикла ForEach

Мы хотим, чтобы robocopy копировал только папки (c: \ folder1, c: \ folder2, c: \ folder3), если установлен соответствующий флажок, с циклом foreach.

Если у нас есть отдельный экземпляр robocopy для каждой папки, он отлично работает и копирует папку, только если установлен флажок. (см код ниже) Мы просто хотим сделать это с помощью цикла ForEach, поскольку единственное, что отличается в каждом фрагменте кода, - это имя папки и имя флажка

Проблема заключается в том, что PowerShell ищет флажок с именем «$ folder» из-за кода «if ($ folder.Checked)» вместо сопоставления имени с массивом, как это происходит с foldernames и logfiles.

Важное примечание; мы понимаем, что в этом примере удаляется не так много строк кода (если они вообще есть), но когда мы заставим это работать, будет гораздо больше папок и флажков, чем 3, поэтому мы хотим, чтобы это было сделано таким образом, если это возможно .

TL; ДР: У нас есть форма PowerShell с флажками и кнопка, которая запускает робокопию. Если флажок «folder1» установлен, следует скопировать «c: \ src \ folder1» и т. Д. Это уже прекрасно работает без цикла ForEach, мы просто хотим сделать это с циклом ForEach вместо

Какой синтаксис для этого? Смотрите код ниже

СПАСИБО ОГРОМНОЕ В ПРЕДЕЛАХ ДЛЯ ЛЮБОЙ ПОМОЩИ

Мы попытались поместить «if ($ folder.Checked)» в скобки, кавычки, двойные кавычки, одинарные кавычки и различные их варианты. Мы также попытались определить флажки во втором массиве различными способами, а затем добавить второй ForEach внутри существующего ForEach, но он по-прежнему не проверяет, установлены ли флажки, и иногда он копирует одну и ту же папку несколько раз, что имеет смысл, когда мы пытались ForEach внутри другого ForEach.

Это решение, которое у нас есть в настоящее время, и оно отлично работает:

if ($folder1.Checked) {
 robocopy "c:\src\folder1" "c:\dst\folder1" /l /log+:"c:\folder1.txt" /njh /njs /ndl /np /tee | foreach {$outputBox.AppendText($_ + "`r`n")}
 }
if ($folder2.Checked) {
 robocopy "c:\src\folder2" "c:\dst\folder2" /l /log+:"c:\folder2.txt" /njh /njs /ndl /np /tee | foreach {$outputBox.AppendText($_ + "`r`n")}
 }
if ($folder3.Checked) {
 robocopy "c:\src\folder3" "c:\dst\folder3" /l /log+:"c:\folder3.txt" /njh /njs /ndl /np /tee | foreach {$outputBox.AppendText($_ + "`r`n")}
 }
}

Это не работает:

$Folders = @('folder1','folder2','folder3')
foreach ($Folder in $Folders) {
    if ($folder.Checked) { ##<-- Fails here because it looks for a checkbox named "$folder" instead of going through the array for names##
        robocopy "c:\src\$Folder" "c:\dst\$Folder" /l /log+:"c:\$Folder.txt" /njh /njs /ndl /np /tee | foreach {$outputBox.AppendText($_ + "`r`n")}
       } else {$outputBox.AppendText("$folder NOT SELECTED" + "`r`n")}
}
}

Этот цикл ForEach также отлично работает (но без флажков), поэтому мы знаем, что это не цикл ForEach, с которым что-то не так:

$Folders = @('folder1','folder2','folder3')
foreach ($Folder in $Folders) {
        robocopy "c:\src\$Folder" "c:\dst\$Folder" /l /log+:"c:\$Folder.txt" /njh /njs /ndl /np /tee | foreach {$outputBox.AppendText($_ + "`r`n")}
       }
}
}

Ожидаемый результат: Скопируйте папку, только если установлен соответствующий checlbox, с циклом ForEach. Мы не можем заставить PowerShell проверять флажки при использовании ForEach, только без ForEach

Полный код формы:


#ENABLE VISUALSTYLES#
[System.Windows.Forms.Application]::EnableVisualStyles()

#----------------------------------------------------------------------------GUI FORM + CONSOLE OUTPUT (TEXTBOX)----------------------------------------------------------------------------#
$form = New-Object System.Windows.Forms.Form
$form.Size = New-Object System.Drawing.Size(1100,771)
$form.FormBorderStyle = "FixedDialog"
$form.StartPosition = "CenterScreen"
$form.Topmost = $False
$form.add_Load($FormEvent_Load)

#CONSOLE OUTPUT#
$outputBox = New-Object System.Windows.Forms.TextBox 
$outputBox.Location = New-Object System.Drawing.Size(240,110) 
$outputBox.Size = New-Object System.Drawing.Size(850,500)
$outputBox.MultiLine = $True 
$outputBox.ScrollBars = "Both" #"Vertical","Horizontal" 
$outputBox.BackColor = "White"
$outputBox.WordWrap = $False
$outputBox.ReadOnly = $True
$Form.Controls.Add($outputBox)        

#----------------------------------------------------------------------------BUTTONS----------------------------------------------------------------------------#      
$3Button = New-Object System.Windows.Forms.Button
$3Button.Location = New-Object System.Drawing.Size(10,270)
$3Button.Size = New-Object System.Drawing.Size(150,20)
$3Button.Text = "foreach robocopy test"
#$3Button.Add_Click({RobocopyForEveryCheckbox})
$3Button.Add_Click({RobocopyForEach})
$form.Controls.Add($3Button)

#----------------------------------------------------------------------------CHECKBOXES----------------------------------------------------------------------------#
$folder1 = New-Object System.Windows.Forms.checkbox
$folder1.Location = New-Object System.Drawing.Size(10,55)
$folder1.Size = New-Object System.Drawing.Size(110,20)
$folder1.Checked=$True
$folder1.Text = "Folder1"
$form.Controls.Add($folder1)

$folder2 = New-Object System.Windows.Forms.checkbox
$folder2.Location = New-Object System.Drawing.Size(10,75)
$folder2.Size = New-Object System.Drawing.Size(130,20)
$folder2.Checked=$True
$folder2.Text = "Folder2"
$form.Controls.Add($folder2)

$folder3 = New-Object System.Windows.Forms.checkbox
$folder3.Location = New-Object System.Drawing.Size(10,95)
$folder3.Size = New-Object System.Drawing.Size(130,20)
$folder3.Checked=$True
$folder3.Text = "Folder3"
$form.Controls.Add($folder3)

#----------------------------------------------------------------------------FUNCTIONS----------------------------------------------------------------------------#

##############THIS FUNCTION WORKS PERFECTLY###############
function RobocopyForEveryCheckbox {
if ($folder1.Checked) {
 robocopy "c:\src\folder1" "c:\dst\folder1" /l /log+:"c:\folder1.txt" /njh /njs /ndl /np /tee | foreach {$outputBox.AppendText($_ + "`r`n")}
 }
if ($folder2.Checked) {
 robocopy "c:\src\folder2" "c:\dst\folder2" /l /log+:"c:\folder2.txt" /njh /njs /ndl /np /tee | foreach {$outputBox.AppendText($_ + "`r`n")}
 }
if ($folder3.Checked) {
 robocopy "c:\src\folder3" "c:\dst\folder3" /l /log+:"c:\folder3.txt" /njh /njs /ndl /np /tee | foreach {$outputBox.AppendText($_ + "`r`n")}
 }
}

###############THIS FUNCTION DOES -NOT- WORK. BUT IT WORKS PERFECTLY IF WE DO NOT CHECK FOR CHECKED BOXES BUT IT'S THE ONE WE WANT TO USE#########################
function RobocopyForEach {
$Folders = @('folder1','folder2','folder3')
foreach ($Folder in $Folders) {
    if ($folder.Checked) { ###<-----Fails here because it looks for a checkbox named "$folder" instead of going through the array for names and so it cannot find a checkbox named "$folder" because no such exists##
        robocopy "c:\src\$Folder" "c:\dst\$Folder" /l /log+:"c:\$Folder.txt" /njh /njs /ndl /np /tee | foreach {$outputBox.AppendText($_ + "`r`n")}
        } else {$outputBox.AppendText("$folder NOT SELECTED" + "`r`n")}
}
}

$form.ShowDialog()

Ответы [ 2 ]

1 голос
/ 04 июня 2019

Вы создали массив или строки и проходите через них.

Это то, что видит ваш код.

Foreach($Folder in $Folders) {
    If([String]Folder1.Checked) {
    }
}

Вам нужно создать массив объектов.

$Folders = @("$folder1","$folder2","$folder3")

Это должно позволить вам перебирать объекты и проверять их состояние.

System.Windows.Forms.CheckBox, CheckState: 1
System.Windows.Forms.CheckBox, CheckState: 0
System.Windows.Forms.CheckBox, CheckState: 0

Затем вы можете получить либо 1 (True), либо 0 (False), выполнив

($folder.Split(": "))[3]
0 голосов
/ 04 июня 2019

Просто потерять кавычки:

$checkbox1 = New-Object System.Windows.Forms.checkbox
$checkbox1.Location = New-Object System.Drawing.Size(10,55)
$checkbox1.Size = New-Object System.Drawing.Size(110,20)
$checkbox1.Checked = $True
$checkbox1.Text = "Folder1"
$checkbox1.Tag = "c:\Custom-Files"
$form.Controls.Add($checkbox1)

$checkbox2 = New-Object System.Windows.Forms.checkbox
$checkbox2.Location = New-Object System.Drawing.Size(10,75)
$checkbox2.Size = New-Object System.Drawing.Size(130,20)
$checkbox2.Checked = $True
$checkbox2.Text = "Folder2"
$checkbox2.Tag = "c:\somefolder"
$form.Controls.Add($checkbox2)

$checkbox3 = New-Object System.Windows.Forms.checkbox
$checkbox3.Location = New-Object System.Drawing.Size(10,95)
$checkbox3.Size = New-Object System.Drawing.Size(130,20)
$checkbox3.Checked = $True
$checkbox3.Text = "Folder3"
$checkbox3.Tag = "c:\anotherfolder"
$form.Controls.Add($checkbox3)

function RobocopyForEach 
{
    $checkboxes = @($checkbox1, $checkbox2, $checkbox3)

    foreach ($checkbox in $checkboxes) 
    {
        if ($checkbox.Checked) 
        {
            robocopy "c:\src\$($checkbox.Tag)" "c:\dst\$($checkbox.Tag)" /l /log+:"c:\$($checkbox.Tag).txt" /njh /njs /ndl /np /tee | ForEach-Object { $outputBox.AppendText($_ + "`r`n") }
        } 
        else 
        {
            $outputBox.AppendText("$($checkbox.Text) NOT SELECTED" + "`r`n")
        }
    }
}
...