我们有一个PowerShell表单,其中包含按钮和复选框,以及一个用于显示输出的文本框; 我们有3个复选框分别标记为“ folder1”,“ folder2”和“ folder3”。 我们有一个用于启动robocopy的按钮(无ForEach循环) 我们有一个显示所有脚本输出的文本框 注意:这已经可以完美工作了;我们只是想用一个ForEach循环来完成它
我们希望robocopy仅在选中相应复选框的情况下使用foreach循环复制文件夹(c:\ folder1,c:\ folder2,c:\ folder3)。
如果每个文件夹都有一个单独的robocopy实例,则它可以正常工作,并且仅在选中复选框后才复制一个文件夹。 (请参见下面的代码) 我们只想使用ForEach循环来完成此操作,因为在每段代码中唯一不同的是文件夹的名称和复选框的名称
我们认为问题是,由于“ if($ folder.Checked)”代码,PowerShell正在寻找一个名为“ $ folder”的复选框,而不是像使用文件夹名称和日志文件。
重要说明;我们意识到在这个示例中,没有多少行代码被删除(如果有的话),但是当我们使之工作时,文件夹和复选框的数量将超过3,因此这就是为什么我们希望这样做的原因
TL; DR: 我们有一个带有复选框的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")}
}
}
}
预期结果: 仅当选中相应的checlbox并使用ForEach循环时,才复制文件夹。使用ForEach时,只有没有ForEach,我们才能让PowerShell来检查已选中的复选框
表格的完整代码:
#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()
答案 0 :(得分:1)
您已经创建了一个数组或字符串,并正在循环遍历。
这就是您的代码所见。
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]
答案 1 :(得分:0)
只需松开引号即可:
$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")
}
}
}