带GUI的Powershell脚本执行缓慢

时间:2011-11-15 15:22:34

标签: winforms powershell user-interface

我用powershell创建了一个gui,允许我将文件从文件夹中复制到一个地方。

示例您有一个文件夹A,在文件夹A中,所有这些文件夹中都有文件夹B和C,您有一堆名为logfile + date.log的日志文件

我的应用可以搜索所有文件夹并将日志文件移动到一个位置。

该脚本可以正常工作,但是当它获取要复制的文件列表时,它很慢并且在窗口顶部“将文件复制到一个目录”旁边显示“未响应”

我添加了脚本,你们可以看看,让我知道如何加快速度。 它导致问题的功能是在“这些是我似乎遇到问题的功能”之后

感谢您的帮助。 代码     

    #------------------------------------------------------------------------
    # Source File Information (DO NOT MODIFY)
    # Source ID: 3020bcd1-4cba-4aca-968e-b4bc4ca05d76
    # Source File: Copy\Copy.pfproj
    #------------------------------------------------------------------------
    #========================================================================
    # Generated On: 11/15/2011 5:11 PM
    # Generated By: justin
    #========================================================================

#---------------------------------------------- #region Import Assemblies #---------------------------------------------- [void][Reflection.Assembly]::Load("System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") [void][Reflection.Assembly]::Load("System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") [void][Reflection.Assembly]::Load("System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a") [void][Reflection.Assembly]::Load("mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") [void][Reflection.Assembly]::Load("System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") [void][Reflection.Assembly]::Load("System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") [void][Reflection.Assembly]::Load("System.DirectoryServices, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a") #endregion Import Assemblies #Define a Param block to use custom parameters in the project #Param ($CustomParameter) function Main { Param ([String]$Commandline) #Note: This function starts the application #Note: $Commandline contains the complete argument string passed to the packager #Note: $Args contains the parsed arguments passed to the packager (Type: System.Array) #Note: To get the script directory in the Packager use: Split-Path $hostinvocation.MyCommand.path #Note: To get the console output in the Packager (Windows Mode) use: $ConsoleOutput (Type: System.Collections.ArrayList) #TODO: Initialize and add Function calls to forms if((Call-MainForm_pff) -eq "OK") { } $global:ExitCode = 0 #Set the exit code for the Packager } #region Call-MainForm_pff function Call-MainForm_pff { #---------------------------------------------- #region Import the Assemblies #---------------------------------------------- [void][reflection.assembly]::Load("System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") [void][reflection.assembly]::Load("System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") [void][reflection.assembly]::Load("System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a") [void][reflection.assembly]::Load("mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") [void][reflection.assembly]::Load("System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") [void][reflection.assembly]::Load("System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") [void][reflection.assembly]::Load("System.DirectoryServices, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a") #endregion Import Assemblies #---------------------------------------------- #region Generated Form Objects #---------------------------------------------- [System.Windows.Forms.Application]::EnableVisualStyles() $CopyFilesToOneDirectoy = New-Object System.Windows.Forms.Form $labelExtension = New-Object System.Windows.Forms.Label $labelFileName = New-Object System.Windows.Forms.Label $Extension = New-Object System.Windows.Forms.TextBox $FileName = New-Object System.Windows.Forms.TextBox $buttonSetDestination = New-Object System.Windows.Forms.Button $buttonSetSource = New-Object System.Windows.Forms.Button $Dlabel = New-Object System.Windows.Forms.Label $Slabel = New-Object System.Windows.Forms.Label $DestinationFolder = New-Object System.Windows.Forms.TextBox $SourceFolder = New-Object System.Windows.Forms.TextBox $progress = New-Object System.Windows.Forms.ProgressBar $buttonCopyFiles = New-Object System.Windows.Forms.Button $sourcebrowserdialog = New-Object System.Windows.Forms.FolderBrowserDialog $destinationbrowserdialog = New-Object System.Windows.Forms.FolderBrowserDialog $InitialFormWindowState = New-Object System.Windows.Forms.FormWindowState #endregion Generated Form Objects #---------------------------------------------- # User Generated Script #---------------------------------------------- $OnLoadFormEvent={ } $buttonSetSource_Click={ $result = $sourcebrowserdialog.ShowDialog() if ($result -eq 'Ok'){ $SourceFolder.Text =$sourcebrowserdialog.SelectedPath } else{ $SourceFolder.Text = '' } } $buttonSetDestination_Click={ $result = $destinationbrowserdialog.ShowDialog() if ($result -eq 'Ok'){ $DestinationFolder.Text =$destinationbrowserdialog.SelectedPath } else{ $DestinationFolder.Text = '' } } $buttonCopyFiles_Click={ #TODO: Place custom script here $progress.Value = 0 $CName = $FileName.Text $CExtension = "." + $Extension.Text $CSource = $SourceFolder.Text $CDestination = $DestinationFolder.Text CopyfFiles $CSource $CDestination $CName $CExtension } # --End User Generated Script-- #---------------------------------------------- #region Generated Events #---------------------------------------------- $Form_StateCorrection_Load= { #Correct the initial state of the form to prevent the .Net maximized form issue $CopyFilesToOneDirectoy.WindowState = $InitialFormWindowState } $Form_StoreValues_Closing= { #Store the control values $script:MainForm_Extension = $Extension.Text $script:MainForm_FileName = $FileName.Text $script:MainForm_DestinationFolder = $DestinationFolder.Text $script:MainForm_SourceFolder = $SourceFolder.Text } $Form_Cleanup_FormClosed= { #Remove all event handlers from the controls try { $buttonSetDestination.remove_Click($buttonSetDestination_Click) $buttonSetSource.remove_Click($buttonSetSource_Click) $buttonCopyFiles.remove_Click($buttonCopyFiles_Click) $CopyFilesToOneDirectoy.remove_Load($OnLoadFormEvent) $CopyFilesToOneDirectoy.remove_Load($Form_StateCorrection_Load) $CopyFilesToOneDirectoy.remove_Closing($Form_StoreValues_Closing) $CopyFilesToOneDirectoy.remove_FormClosed($Form_Cleanup_FormClosed) } catch [Exception] { } } #endregion Generated Events #---------------------------------------------- #region Generated Form Code #---------------------------------------------- # # CopyFilesToOneDirectoy # $CopyFilesToOneDirectoy.Controls.Add($labelExtension) $CopyFilesToOneDirectoy.Controls.Add($labelFileName) $CopyFilesToOneDirectoy.Controls.Add($Extension) $CopyFilesToOneDirectoy.Controls.Add($FileName) $CopyFilesToOneDirectoy.Controls.Add($buttonSetDestination) $CopyFilesToOneDirectoy.Controls.Add($buttonSetSource) $CopyFilesToOneDirectoy.Controls.Add($Dlabel) $CopyFilesToOneDirectoy.Controls.Add($Slabel) $CopyFilesToOneDirectoy.Controls.Add($DestinationFolder) $CopyFilesToOneDirectoy.Controls.Add($SourceFolder) $CopyFilesToOneDirectoy.Controls.Add($progress) $CopyFilesToOneDirectoy.Controls.Add($buttonCopyFiles) $CopyFilesToOneDirectoy.ClientSize = '458, 245' $CopyFilesToOneDirectoy.Name = "CopyFilesToOneDirectoy" $CopyFilesToOneDirectoy.StartPosition = 'CenterScreen' $CopyFilesToOneDirectoy.Text = "Copy Files To One Directoy" $CopyFilesToOneDirectoy.add_Load($OnLoadFormEvent) # # labelExtension # $labelExtension.AutoSize = $True $labelExtension.Font = "Microsoft Sans Serif, 9.75pt, style=Bold" $labelExtension.Location = '349, 54' $labelExtension.Name = "labelExtension" $labelExtension.Size = '75, 16' $labelExtension.TabIndex = 11 $labelExtension.Text = "Extension" # # labelFileName # $labelFileName.AutoSize = $True $labelFileName.Font = "Microsoft Sans Serif, 9.75pt, style=Bold" $labelFileName.Location = '12, 54' $labelFileName.Name = "labelFileName" $labelFileName.Size = '79, 16' $labelFileName.TabIndex = 10 $labelFileName.Text = "File Name" # # Extension # $Extension.Font = "Microsoft Sans Serif, 9.75pt" $Extension.Location = '349, 74' $Extension.Name = "Extension" $Extension.Size = '93, 22' $Extension.TabIndex = 9 # # FileName # $FileName.Font = "Microsoft Sans Serif, 9.75pt" $FileName.Location = '12, 74' $FileName.Name = "FileName" $FileName.Size = '300, 22' $FileName.TabIndex = 8 # # buttonSetDestination # $buttonSetDestination.Location = '349, 173' $buttonSetDestination.Name = "buttonSetDestination" $buttonSetDestination.Size = '93, 23' $buttonSetDestination.TabIndex = 7 $buttonSetDestination.Text = "Set Destination" $buttonSetDestination.TextAlign = 'MiddleLeft' $buttonSetDestination.UseVisualStyleBackColor = $True $buttonSetDestination.add_Click($buttonSetDestination_Click) # # buttonSetSource # $buttonSetSource.Location = '349, 123' $buttonSetSource.Name = "buttonSetSource" $buttonSetSource.Size = '93, 23' $buttonSetSource.TabIndex = 6 $buttonSetSource.Text = "Set Source" $buttonSetSource.UseVisualStyleBackColor = $True $buttonSetSource.add_Click($buttonSetSource_Click) # # Dlabel # $Dlabel.AutoSize = $True $Dlabel.Font = "Microsoft Sans Serif, 9.75pt, style=Bold" $Dlabel.Location = '12, 154' $Dlabel.Name = "Dlabel" $Dlabel.Size = '135, 16' $Dlabel.TabIndex = 5 $Dlabel.Text = "Destination Folder" # # Slabel # $Slabel.AutoSize = $True $Slabel.Font = "Microsoft Sans Serif, 9.75pt, style=Bold" $Slabel.Location = '12, 104' $Slabel.Name = "Slabel" $Slabel.Size = '106, 16' $Slabel.TabIndex = 4 $Slabel.Text = "Source Folder" # # DestinationFolder # $DestinationFolder.Font = "Microsoft Sans Serif, 9.75pt" $DestinationFolder.Location = '12, 174' $DestinationFolder.Name = "DestinationFolder" $DestinationFolder.Size = '300, 22' $DestinationFolder.TabIndex = 3 $DestinationFolder.Text = "c:\td" # # SourceFolder # $SourceFolder.Font = "Microsoft Sans Serif, 9.75pt" $SourceFolder.Location = '12, 124' $SourceFolder.Name = "SourceFolder" $SourceFolder.Size = '300, 22' $SourceFolder.TabIndex = 2 $SourceFolder.Text = "c:\ts" # # progress # $progress.Location = '12, 212' $progress.Name = "progress" $progress.Size = '300, 23' $progress.TabIndex = 1 # # buttonCopyFiles # $buttonCopyFiles.Location = '349, 212' $buttonCopyFiles.Name = "buttonCopyFiles" $buttonCopyFiles.Size = '93, 23' $buttonCopyFiles.TabIndex = 0 $buttonCopyFiles.Text = "Copy Files" $buttonCopyFiles.UseVisualStyleBackColor = $True $buttonCopyFiles.add_Click($buttonCopyFiles_Click) # # sourcebrowserdialog # $sourcebrowserdialog.RootFolder = 'MyComputer' $sourcebrowserdialog.ShowNewFolderButton = $False # # destinationbrowserdialog # $destinationbrowserdialog.RootFolder = 'MyComputer' $destinationbrowserdialog.ShowNewFolderButton = $False #endregion Generated Form Code #---------------------------------------------- #Save the initial state of the form $InitialFormWindowState = $CopyFilesToOneDirectoy.WindowState #Init the OnLoad event to correct the initial state of the form $CopyFilesToOneDirectoy.add_Load($Form_StateCorrection_Load) #Clean up the control events $CopyFilesToOneDirectoy.add_FormClosed($Form_Cleanup_FormClosed) #Store the control values when form is closing $CopyFilesToOneDirectoy.add_Closing($Form_StoreValues_Closing) #Show the Form return $CopyFilesToOneDirectoy.ShowDialog() } #endregion #-------------------------------------------------------------------------------------------------------------------------------------------------- # These are the function I seems to be havig a problem with #Sample function that provides the location of the script function Get-ScriptDirectory { if($hostinvocation -ne $null) { Split-Path $hostinvocation.MyCommand.path } else { Split-Path $script:MyInvocation.MyCommand.Path } } function ListOfFiles ($Source,$Name,$Extension){ $FileListArray = @() foreach($file in Get-ChildItem $Source -Force -Recurse | Where-Object {$_.name -like $Name -and $_.Extension -eq $Extension}) { If ($FileListArray -match "$file") { $NewFileName = $file.Directory.Name + "." + $file.Name $FileListArray += ,@($file,$file.FullName,$NewFileName) } Else { $FileListArray += ,@($file,$file.FullName,$file) } } Return $FileListArray } Function CopyfFiles ($Source,$Destination,$Name,$Extension){ $ListFiles = @(listOfFiles -Source $Source -Name $Name -Extension $Extension) $ListFilesTemp = @() Foreach ($CF in $ListFiles) { $Check = $Destination + "\"+ $CF[2] #If The File is Not Already In The Destination Add It To The Temp Array IF (Test-Path -Path "$Check") {} Else {$ListFilesTemp += ,@($CF[0],$CF[1],$CF[2])} $ListFiles = $ListFilesTemp } $progress.Minimum = 0 $progress.Maximum = $ListFiles.Count $progress.Step = 1 Foreach ($File in $ListFiles) { $FileDestination = $Destination + "\"+ $File[2] Copy-Item -Path $File[1] -Destination $FileDestination $progress.PerformStep() } } #Sample variable that provides the location of the script [string]$ScriptDirectory = Get-ScriptDirectory #-------------------------------------------------------------------------------------------------------------------------------------------------- #endregion #Start the application Main ($CommandLine) <code>

2 个答案:

答案 0 :(得分:0)

“Not Responding”表示线程没有等待窗口输入(在您的示例中,线程正在运行powershell代码)。我不认为在Powershell中创建新线程有一个微不足道的方法。但是,您可以使用 PowerBoots powershell工作(例如此example)使您的GUI更具响应性。

答案 1 :(得分:0)

您在函数内部声明局部变量(Call-MainForm_pff)并在其他函数中使用这些变量。那样不行。请参阅示例代码。只显示$ Var2。

#=================
Function One-Set-Value {
    $Var1 = "This is a test."
}

Function Two-Display-Value
{
    $Var2 = "This is a second test."
    Write-Host "Var2" $Var2
    Write-Host "Var1" $Var1
}
One-Set-Value
Two-Display-Value
#=================

将这些变量转换为函数。这将与返回值一起使用。