对数组中的每个文件夹执行 Robocopy - 仅当相应的复选框被选中时?
Perform Robocopy foreach folder in array - ONLY if corresponding checkbox is checked?
我们有一个 PowerShell 表单,带有按钮和复选框,以及一个用于显示输出的文本框;
我们有 3 个标记为 "folder1"、"folder2" 和 "folder3" 的复选框。
我们有一个启动 robocopy 的按钮(没有 ForEach 循环)
我们有一个显示所有脚本输出的文本框
注意:这已经很完美了;我们只想用 ForEach 循环来完成它
如果相应的复选框被选中,我们希望 robocopy 仅复制文件夹(c:\folder1、c:\folder2、c:\folder3),并使用 foreach 循环。
如果我们为每个文件夹都有一个单独的 robocopy 实例,它会完美地工作,并且仅在选中复选框时才复制文件夹。 (见下面的代码)
我们只想用 ForEach 循环来完成它,因为每段代码中唯一不同的是文件夹的名称和复选框的名称
我们认为问题在于,PowerShell 正在寻找一个名为“$folder”的复选框,因为 "if ($folder.Checked)" 代码,而不是像 foldernames 和日志文件。
重要提示;我们意识到这个例子并没有删除多少行代码(如果有的话),但是当我们让它工作时,将会有比 3 个更多的文件夹和复选框,所以这就是为什么我们希望尽可能以这种方式完成.
长话短说:
我们有一个带有复选框的 PowerShell 表单和一个启动 robocopy 的按钮。如果选中 "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")}
}
}
}
预期结果:
仅在选中相应的复选框时才复制文件夹,并使用 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----------------------------------------------------------------------------#
Button = New-Object System.Windows.Forms.Button
Button.Location = New-Object System.Drawing.Size(10,270)
Button.Size = New-Object System.Drawing.Size(150,20)
Button.Text = "foreach robocopy test"
#Button.Add_Click({RobocopyForEveryCheckbox})
Button.Add_Click({RobocopyForEach})
$form.Controls.Add(Button)
#----------------------------------------------------------------------------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()
您已经创建了一个数组或字符串,并且正在遍历它。
这就是您的代码所看到的。
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(真)或 0(假)
($folder.Split(": "))[3]
只需松开引号:
$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")
}
}
}
我们有一个 PowerShell 表单,带有按钮和复选框,以及一个用于显示输出的文本框; 我们有 3 个标记为 "folder1"、"folder2" 和 "folder3" 的复选框。 我们有一个启动 robocopy 的按钮(没有 ForEach 循环) 我们有一个显示所有脚本输出的文本框 注意:这已经很完美了;我们只想用 ForEach 循环来完成它
如果相应的复选框被选中,我们希望 robocopy 仅复制文件夹(c:\folder1、c:\folder2、c:\folder3),并使用 foreach 循环。
如果我们为每个文件夹都有一个单独的 robocopy 实例,它会完美地工作,并且仅在选中复选框时才复制文件夹。 (见下面的代码) 我们只想用 ForEach 循环来完成它,因为每段代码中唯一不同的是文件夹的名称和复选框的名称
我们认为问题在于,PowerShell 正在寻找一个名为“$folder”的复选框,因为 "if ($folder.Checked)" 代码,而不是像 foldernames 和日志文件。
重要提示;我们意识到这个例子并没有删除多少行代码(如果有的话),但是当我们让它工作时,将会有比 3 个更多的文件夹和复选框,所以这就是为什么我们希望尽可能以这种方式完成.
长话短说: 我们有一个带有复选框的 PowerShell 表单和一个启动 robocopy 的按钮。如果选中 "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")}
}
}
}
预期结果: 仅在选中相应的复选框时才复制文件夹,并使用 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----------------------------------------------------------------------------#
Button = New-Object System.Windows.Forms.Button
Button.Location = New-Object System.Drawing.Size(10,270)
Button.Size = New-Object System.Drawing.Size(150,20)
Button.Text = "foreach robocopy test"
#Button.Add_Click({RobocopyForEveryCheckbox})
Button.Add_Click({RobocopyForEach})
$form.Controls.Add(Button)
#----------------------------------------------------------------------------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()
您已经创建了一个数组或字符串,并且正在遍历它。
这就是您的代码所看到的。
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(真)或 0(假)($folder.Split(": "))[3]
只需松开引号:
$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")
}
}
}