Как я могу остановить мой скрипт при нажатии кнопки отмены?

Я работаю над сценарием, который предлагает вам скопировать целые структуры папок, включая 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/

заранее спасибо

Мартин

Помог ли какой-либо из наших ответов?   —  person Martin Schmidt    schedule 06.11.2020

См. также:  Как заставить установщик приложений MSIX выводить правильные настройки во время каждой сборки / публикации?
Понравилась статья? Поделиться с друзьями:
IT Шеф
Комментарии: 2
  1. Martin Schmidt

    Согласно документации </ а>:

    Если пользователь нажимает кнопку «Отмена», возвращается строка нулевой длины.

    Так ты всегда можешь сделать

    if ($sourceDrive.Length -eq 0) {
        break
    }
    

    (Чтобы узнать, использовать ли break, return или exit, см.

    здесь.)

    Конечно, строка также была бы пустой, если бы пользователь нажал «ОК», но не заполнил поле ввода. Но я думаю, что к этим двум случаям можно относиться одинаково. В качестве альтернативы вы можете создать собственное диалоговое окно запроса с помощью Windows Forms и вернуть DialogResult.

    Обратите внимание, что это не рекомендуемый способ ввода данных в сценарий Powershell. Вам следует использовать Читать -Host:

    $value = Read-Host "Enter value"
    

    Или, что еще лучше, работайте с параметры (PowerShell автоматически запросит ввод)

    param (
        [Parameter(Mandatory = $true, HelpMessage = "Please enter the source drive")]
        [ValidatePattern("[a-z]:")]
        [string]$SourceDrive
    )
    
  2. Martin Schmidt

    Лично я не понимаю, почему вы хотите использовать все эти InputBoxes, где вам может хватить простого диалога 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, сценарий завершается.

Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: