【问题标题】:Self Delete Folder with scripts powershell使用脚本 powershell 自行删除文件夹
【发布时间】:2019-01-25 21:33:21
【问题描述】:

我一直在尝试让 powershell 或批处理脚本在我完成后删除包含我所有脚本的文件夹。 最初我尝试了Remove-Item -Path "C:\Tool" -Recurse -Force,如果作为C:\Tool 之外的位置的脚本运行,它没有问题。当从其中的脚本运行时,它会抱怨文件正在使用中。 经过一番研究,我发现&cmd.exe /c rd /s /q "C:\Tool" 效果更好,但即使我关闭了 GUI,该命令也不会删除正在使用的 img 文件/文件夹。

从 USB 驱动器启动时,上述两个命令都能完美运行。

之前我在临时文件夹中创建了第二个脚本,它将删除所有文件,然后删除自身。我正在寻找一种新方法来简化我正在进行的新设计。我希望脚本可以在 C:\Tool 或 USB 驱动器中运行。

控制流程是这样的:
1)脚本加载所有函数
2)显示GUI(包含imgs)
3) 按钮被按下
4)GUI 关闭
5)删除包含脚本的文件夹

如前所述,第 5 步是我的问题。并非所有文件都被尝试的命令和命令变体删除。

我希望步骤 5 能够正常工作,无论是从 GUI 上的按钮调用命令、它作为脚本的一部分自动运行,还是其他位置(如 USB)中的脚本调用它来删除文件夹 C:\Tool

【问题讨论】:

  • 虽然是 GUI 按钮触发删除...它对问题没有影响,因为该命令可以放置在脚本中的任何位置,无论是否显示 GUI。问题是脚本在后台加载 GUI,然后运行删除,并且由于 powershell 脚本“正在使用”文件而不会删除所有内容。 cmd /c rd 命令可以毫无问题地删除所有脚本,但 GUI 使用的图像由于“正在使用”而保持不变。 Remove-Item 不会删除文件夹中的任何内容,因为 powershell 脚本正在“使用中”
  • 从 PowerShell 脚本中,您可以在脚本末尾将删除命令传递给 CMD 提示符。Invoke-Expression -Command "cmd.exe /c del /f C:\Tool* /q"

标签: winforms powershell directory delete-file self-destruction


【解决方案1】:

我们不知道您的 GUI 如何显示的细节,但是,假设您使用的是在 PowerShell 代码中构建的 WinForms GUI,您的问题可能是您的 GUI 构建方式代码从您稍后要删除的文件夹中的文件中加载图像。

值得注意的是,如果你使用类似的东西:

[Bitmap]::new(<file-path>)
[System.Drawing.Image]::FromFile(<file-path>)

指定的文件显然在 PowerShell 会话的剩余时间内保持打开状态,您将无法删除您的文件夹。

解决方案是在内存中创建一个图像实例,复制从文件加载的图像,然后dispose em> 从文件加载的图像,释放对底层文件的锁定,如this [C#] answer 所示。

这是一个演示该方法的最小脚本demo.ps1

  • 将其保存到自己的临时丢弃文件夹中。

  • 将一个名为demo.png 的小图像文件复制到同一文件夹中。

  • 然后以&lt;temp-folder&gt;/demo -SelfDestruct 调用它以查看它的运行情况;需要指定
    -SelfDescript 是一种预防措施,因为意外调用会清除脚本所在的整个文件夹。

demo.ps1:

param([switch] $SelfDestruct)

# Load the WinForms assembly.
Add-Type -AssemblyName System.Windows.Forms    

# Create the form.
$form = New-Object system.Windows.Forms.Form -Property @{
    ClientSize = New-Object System.Drawing.Point 400,100
    Text       = "Dialog"
}    

# Add a PictureBox control that loads its image from 'demo.png'
$form.Controls.Add((New-Object System.Windows.Forms.PictureBox  -Property @{
Image = & { 
    # Load the image from file in the same folder as a script into
    # a temporary variable.
    $tmpImg = [System.Drawing.Image]::FromFile((Join-Path $PSScriptRoot 'demo.png')) 
    # Create an in-memory copy of the image. 
    New-Object System.Drawing.Bitmap $tmpImg
    # Dispose of the from-file image, which releases the file.
    $tmpImg.Dispose()
}
Location = New-Object System.Drawing.Point 10, 10
}))


# Show the form and wait for the use to close it.
$null = $form.ShowDialog()

if ($SelfDestruct) { # Remove the running script's entire folder.
  if ("$($PWD.Path)\" -like "$PSScriptRoot\*") {                                                      #"
      Push-Location C:\ # must switch to different dir. before deleting.
  }
  # Remove the entire folder.
  Remove-Item -literalpath $PSScriptRoot -Recurse -Force
  exit
}

这是一个变体,它通过事件处理程序通过按钮单击触发删除

param([switch] $SelfDestruct)

Add-Type -AssemblyName System.Windows.Forms

function remove-OwnFolder {
    # If the current dir. is in the subtree of the folder to delete, 
    # we must switch to different dir. before deleting.
    if ("$($PWD.Path)\" -like "$PSScriptRoot\*") {                                                      #"
        Push-Location C:\ 
    }
    # Remove the script's parent folder as a whole.
    Remove-Item -literalpath $PSScriptRoot -Recurse -Force
}

# Create the form.
$form = New-Object system.Windows.Forms.Form -Property @{
    ClientSize = New-Object System.Drawing.Point 400,100
    Text       = "Dialog"
}    

# Add a PictureBox control that loads its image from 'demo.png'
$form.Controls.Add((New-Object System.Windows.Forms.PictureBox  -Property @{
    Image = & { 
        # Load the image from file in the same folder as a script into
        # a temporary variable.
        $tmpImg = [System.Drawing.Image]::FromFile((Join-Path $PSScriptRoot 'demo.png')) 
        # Create an in-memory copy of the image. 
        New-Object System.Drawing.Bitmap $tmpImg
        # Dispose of the from-file image, which releases the file.
        $tmpImg.Dispose()
    }
    Location = New-Object System.Drawing.Point 10, 10
}))


# Add a button that will trigger the self-destruction
$btnSelfDestruct = New-Object system.Windows.Forms.Button -Property @{
    Text              = "Submit"
    Location          = New-Object System.Drawing.Point 160, 60
}
$form.Controls.Add($btnSelfDestruct)

# Add the button-click event handler.
$btnSelfDestruct.Add_Click({
    $form.Close()
    if ($SelfDestruct) {
        remove-OwnFolder
    }
    exit
})

# Show the form and wait for the use to close it.
$null = $form.ShowDialog()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多