簡體   English   中英

重命名文件腳本-如何將當前目錄用於上下文菜單

[英]rename files script - how to use current directory for context menu

我有以下腳本,下面的一行拉出上下文/瀏覽菜單,以便用戶輕松導航到他們選擇的文件並重命名文件。 而不是使用靜態位置作為目錄,如何獲取啟動腳本的當前目錄或當前目錄?

編輯:我忘了提一提,我也希望能夠單獨重命名每個文件(提示用戶選擇文件夾中每個文件),而不是將每個文件重命名為相同的東西。

僅供參考:我使用.bat文件啟動此Powershell腳本。

##########################################################################
#Functions
##########################################################################

# Show input box popup and return the value entered by the user.
function Read-InputBoxDialog([string]$Message, [string]$WindowTitle, [string]$DefaultText)
{
Add-Type -AssemblyName Microsoft.VisualBasic
return [Microsoft.VisualBasic.Interaction]::InputBox($Message, $WindowTitle, $DefaultText)
}

# Show an Open Folder Dialog and return the directory selected by the user.
function Read-FolderBrowserDialog([string]$Message, 
[string]$InitialDirectory, [switch]$NoNewFolderButton)
{
$browseForFolderOptions = 0
if ($NoNewFolderButton) { $browseForFolderOptions += 512 }

$app = New-Object -ComObject Shell.Application
$folder = $app.BrowseForFolder(0, $Message, $browseForFolderOptions, $InitialDirectory)
if ($folder) { $selectedDirectory = $folder.Self.Path } else { $selectedDirectory = '' }
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($app) > $null
return $selectedDirectory
}

##########################################################################
#Start Code
##########################################################################

$i = 1

$directoryPath = Read-FolderBrowserDialog -Message "Please select a directory" -NoNewFolderButton -InitialDirectory 'P:\'
if (![string]::IsNullOrEmpty($directoryPath)) { Write-Host "You selected the directory: $directoryPath" }
else { "You did not select a directory." }



$acctdol = Read-InputBoxDialog -Message "Please enter the Account_DOL" -WindowTitle "Account_DateOfLoan" -DefaultText "########_MMDDYYYY_XXX"
if ($acctdol -eq $null) { Write-Host "You clicked Cancel" }
#elseif ($acctdol -eq "Something") { Write-Host "Thanks for typing Something" }
else { Write-Host "You entered $acctdol" }

If(!$acctdol){
$isnull++
}
else{
Get-ChildItem -Path $($directoryPath)*.pdf -Recurse -Force | 
ForEach-Object {
$newname = "${acctdol}_{0}.pdf" -f $i 
$i++
Rename-Item -Path $_.FullName -NewName $newname
}
}


##########################################################################
#Closing
##########################################################################
if ($Host.Name -eq "ConsoleHost")
{ 
Write-Host "Press any key to continue..."
$Host.UI.RawUI.FlushInputBuffer()   # Make sure buffered input doesn't "press a key" and skip the ReadKey().
$Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyUp") > $null
}

您無需指定PS腳本是否與批處理文件位於相同的位置,因此我不會假定它與腳本文件的路徑一樣被硬編碼到批處理文件中,並且不會將該批處理視為批處理文件文件可以在計算機上的任何位置。

正如Squashman指出的那樣, %~dp0是批處理文件中的當前路徑。 我要做的是在PS腳本中創建一個接受路徑的參數,然后在調用它時將批處理文件的當前路徑傳遞給PS腳本。 因此,像這樣啟動腳本:

[cmdletBinding()]
Param(
    [string]$CallingPath
)

然后,您可以根據需要在BrowseForFolder調用中引用該名稱。 在批處理文件中,您可以這樣稱呼它:

%windir%\system32\windowspowershell\v1.0\powershell.exe -file c:\Path\To\script.ps1 '%~dp0'

編輯:至於命名每個文件,我猜想讓用戶選擇按順序命名文件或命名每個文件是一個好主意,然后,如果他們選擇為每個文件命名一個提示。 為了詢問他們的喜好,我喜歡Windows.Forms.MessageBox,為此,我提供了此函數,並將其扔入需要它的腳本的開頭:

Function Show-MsgBox ($Text,$Title="",[Windows.Forms.MessageBoxButtons]$Button = "OK",[Windows.Forms.MessageBoxIcon]$Icon="Information"){
[Windows.Forms.MessageBox]::Show("$Text", "$Title", [Windows.Forms.MessageBoxButtons]::$Button, $Icon) | ?{(!($_ -eq "OK"))}
}

然后,您可以執行以下操作:

$NameEach = Show-MsgBox -Text "Do you want to rename each file sequentially based on the Account_DOL?`nIf you select No you will be prompted for a name for each file." -Title "Auto-Rename?" -Button YesNo -Icon Question

如果您在ISE中編寫此代碼,它將彈出選項供您選擇可供選擇的按鈕和圖標,或者在ISE和控制台上都使用完整的選項卡。

然后,為了命名文件,我將使用Windows.Forms.SaveFileDialog窗口(我喜歡使用Windows.Forms對話框,因為它們是人們所熟悉的)。 這是一個函數:

Function Get-OutputFilePath{
[CmdletBinding()]
Param(
    [String]$Filter = "All Files (*.*)|*.*",
    [String]$InitialDirectory,
    [Parameter(ValueFromPipelineByPropertyName=$true)]
    [Alias('DefaultFileName')]
    [String]$FullName,
    [Switch]$Force)
    BEGIN{
        [void][System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms")
    }
    PROCESS{
        If($FullName -match "\\.+$" -and !$InitialDirectory){$InitialDirectory = Split-Path $FullName;$FullName = Split-Path $FullName -Leaf}ElseIf(!$InitialDirectory){$InitialDirectory=[Environment]::GetFolderPath('Desktop')}
        $SaveFileDialog = New-Object System.Windows.Forms.SaveFileDialog
        $SaveFileDialog.initialDirectory = $InitialDirectory
        Try{$SaveFileDialog.filter = $Filter}Catch{Throw $_;Break}
        $SaveFileDialog.FileName = $FullName
        $SaveFileDialog.OverwritePrompt = !$Force
        If($SaveFileDialog.ShowDialog() -eq "OK"){$SaveFileDialog.FileName}
    }
}

看起來確實比實際更糟。 但是,有了函數中包​​含的功能,當您循環遍歷文件以重命名它們時,可以在ForEach循環中執行此操作:

$newname = If($NameEach -eq 'Yes'){$_|Get-OutputFilePath -Filter 'PDF File (*.pdf)|*.pdf|All Files (*.*)|*.*'|Split-Path -Leaf}Else{"${acctdol}_{0}.pdf" -f $i}
If($_.Name -ne $newname){$_|Rename-Item -NewName $newname}

這將提示他們默認情況下為正確目錄的“保存文件”對話框,並為當前文件命名,然后將$newname變量設置為所選內容。 另外,它還能執行一些方便的操作,例如提示他們是否要覆蓋文件,驗證文件名和路徑以及類似的東西。 我做的最后一件事是確保他們指定了一個新名稱,以便在嘗試將文件重命名為完全相同的名稱時不會出錯。

獎勵功能! 我注意到您在腳本末尾暫停了,所以我想傳遞用於暫停的功能,因為它在ISE中不會失敗,並允許您向其傳遞消息以顯示。 在ISE中,它會彈出一個帶有消息和“確定”按鈕的對話框,在控制台中,它會顯示消息和“按任意鍵繼續...”消息,就像您的消息一樣。 對於您的腳本,我確定您的工作完美,我只是想分享一下。

Function Invoke-Pause ($Text){
    If($psISE){
        [Windows.Forms.MessageBox]::Show("$Text", "Script Paused", [Windows.Forms.MessageBoxButtons]"OK", [Windows.Forms.MessageBoxIcon]"Information") | ?{(!($_ -eq "OK"))}
    }Else{
        Write-Host $Text
        Write-Host "Press any key to continue ..."
        $Host.UI.RawUI.FlushInputBuffer()
        $x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM