问题描述
我正在处理一个脚本,该脚本会提示您复制整个文件夹结构,包括ACL(权限)
我现在的问题是如何做到这一点,以便当我单击弹出窗口中的“取消”按钮时,它实际上会取消?
我正在使用powershell:)
**#----------------------Source Drive and Folder---------------------#
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') | Out-Null
$sourceDrive = [Microsoft.VisualBasic.Interaction]::InputBox("Please enter the source drive for copying `n(e.g: C)","source drive","")
$sourceFolder = [Microsoft.VisualBasic.Interaction]::InputBox("Please enter the source folder for copying `n(e.g: Folder\Something)","source folder","")
#----------------------Source Drive and Folder---------------------#
#-------------------Destination Drive and Folder-------------------#
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') | Out-Null
$destinationDrive = [Microsoft.VisualBasic.Interaction]::InputBox("Please enter the destination drive for copying `n(e.g: D)","destination drive","")
$destinationFolder = [Microsoft.VisualBasic.Interaction]::InputBox("Please enter the destination folder for copying `n(e.g: Folder1\Something2)","destination folder","")
#-------------------Destination Drive and Folder-------------------#
#--------------------Create new Folder for copy--------------------#
$createNewFolder = [Microsoft.VisualBasic.Interaction]::InputBox("Do you want to create a new folder in this directory? `n(e.g: y/n)","Create new folder","")
if($createNewFolder -eq "n"){
xcopy "$sourceDrive`:\$sourceFolder" "$destinationDrive`:\$destinationFolder" /O /X /E /H /K
}elseif($createNewFolder -eq "y") {
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') | Out-Null
$newFolder = [Microsoft.VisualBasic.Interaction]::InputBox("Please enter the name of the folder `n(e.g: somefolder)","New folder","")
xcopy "$sourceDrive`:\$sourceFolder" "$destinationDrive`:\$newfolder\$destinationFolder" /O /X /E /H /K
}else {
}
#--------------------Create new Folder for copy--------------------#
#xcopy "$sourceDrive`:\$sourceFolder" "$destinationDrive`:\$destinationFolder" /O /X /E /H /K**
这也发布在powershell.org中:https://powershell.org/forums/topic/how-can-i-make-my-script-stop-when-clicked-on-the-cancel-button-2/
预先感谢
马丁
解决方法
如果用户单击“取消”,则返回零长度的字符串。
所以你总是可以做
if ($sourceDrive.Length -eq 0) {
break
}
(关于使用break
,return
还是exit
,请看here。)
当然,如果用户单击“确定”但未填写输入框,则字符串也将为空。但是我认为您可以平等地对待这两种情况。或者,您可以使用Windows窗体创建自己的prompt dialog,然后返回DialogResult。
请注意,这不是在Powershell脚本中获取输入的推荐方法。您应该使用Read-Host:
$value = Read-Host "Enter value"
或更妙的是,使用parameters(powershell将自动提示输入)
param (
[Parameter(Mandatory = $true,HelpMessage = "Please enter the source drive")]
[ValidatePattern("[a-z]:")]
[string]$SourceDrive
)
,
我个人不知道为什么要使用所有这些InputBox,只需使用FolderBrowser对话框就可以了(两次)。
通过使用该对话框,您还可以确保用户不仅输入任何内容,而且不必检查所有步骤。
下面的功能Get-FolderPath
是一个帮助器功能,用于包装BrowseForFolder对话框的调用,从而使您的生活更轻松。
function Get-FolderPath {
# Show an Open Folder Dialog and return the directory selected by the user.
[CmdletBinding()]
param (
[Parameter(Mandatory=$false,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Position=0)]
[string]$Message = "Select a directory.",$InitialDirectory = [System.Environment+SpecialFolder]::MyComputer,[switch]$ShowNewFolderButton
)
# Browse Dialog Options:
# https://docs.microsoft.com/en-us/windows/win32/api/shlobj_core/ns-shlobj_core-browseinfoa
$browserForFolderOptions = 0x00000041 # BIF_RETURNONLYFSDIRS -bor BIF_NEWDIALOGSTYLE
if (!$ShowNewFolderButton) { $browserForFolderOptions += 0x00000200 } # BIF_NONEWFOLDERBUTTON
$browser = New-Object -ComObject Shell.Application
# To make the dialog topmost,you need to supply the Window handle of the current process
[intPtr]$handle = [System.Diagnostics.Process]::GetCurrentProcess().MainWindowHandle
# see: https://msdn.microsoft.com/en-us/library/windows/desktop/bb773205(v=vs.85).aspx
# ShellSpecialFolderConstants for InitialDirectory:
# https://docs.microsoft.com/en-us/windows/win32/api/shldisp/ne-shldisp-shellspecialfolderconstants#constants
$folder = $browser.BrowseForFolder($handle,$Message,$browserForFolderOptions,$InitialDirectory)
$result = if ($folder) { $folder.Self.Path } else { $null }
# Release and remove the used Com object from memory
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($browser) | Out-Null
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
return $result
}
将其放在脚本顶部,代码可能很简单:
$source = Get-FolderPath -Message 'Please enter the source folder to copy'
# if $null is returned,the user cancelled the dialog
if ($source) {
# the sourcefolder is selected,now lets do this again for the destination path
# by specifying switch '-ShowNewFolderButton',you allow the user to create a new folder
$destination = Get-FolderPath -Message 'Please enter the destination path to copy to' -ShowNewFolderButton
if ($destination) {
# both source and destination are now known,so start copying
xcopy "$source" "$destination" /O /X /E /H /K
}
}
如果用户在您两次致电Get-FolderPath
时都按“取消”,则脚本退出