My goal is to write a simple Powershell script that will take one mandatory argument, that argument must be a full file path to a shortcut (.lnk) file, then the script will resolve the shortcut's target item (a file or a directory) and copy it into the current working directory of the script.
The problem I found is when testing a shortcut whose target item points to a file or folder that contains emoji chars in the path, like for example:
"C:\Movies\β’ Unidentified\[πͺπΈ]\Amor, curiosidad, prozak y dudas (2001)\File.mkv
"
Firstly I've tried with Copy-Item cmdlet, and after that I tried with Shell.NameSpace + Folder.CopyHere() method from Windows Shell Scripting as shown in this example:
https://mcmap.net/q/472836/-invoke-windows-copy-from-powershell
That methodology is what I finally pretend to use for this script instead of Copy-Item cmdlet, because it displays the default file progress UI and I prefer it for this reason.
Note that I'm not very experienced with PowerShell, but in both cases the Copy-Item cmdlet and the CopyHere method are executed without giving any exception message, it just does not perform the file copy operation.
If the item path of the shortcut's target item does not contain emoji chars, it works fine.
I'm not sure if it's some kind of encoding issue. My default O.S encoding is Windows-1252.
What I'm doing wrong and how can I fix this issue?.
# Takes 1 mandatory argument pointing to a shortcut (.lnk) file,
# resolves the shortcut's target item (a file or directory),
# and copies that target item to the specified destination folder
# using Windows default IFileOperation progress UI.
# - File copy method took from here:
# https://mcmap.net/q/472836/-invoke-windows-copy-from-powershell
# - "Shell.NameSpace" method and "Folder" object Docs:
# https://learn.microsoft.com/en-us/windows/win32/shell/shell-namespace
# https://learn.microsoft.com/en-us/windows/win32/shell/folder
param (
[Parameter(
Position=0,
Mandatory,
ValueFromPipeline,
HelpMessage="Enter the full path to a shortcut (.lnk) file.")
] [string] $linkFile = "",
[Parameter(
Position=1,
ValueFromPipeline,
HelpMessage="Enter the full path to the destination folder.")
] [string] $destinationFolder = $(Get-Location)
)
$wsShell = New-Object -ComObject WScript.Shell
$shellApp = New-Object -ComObject Shell.Application
$targetItem = $wsShell.CreateShortcut($linkFile).TargetPath
Write-Host [i] Link File..: ($linkFile)
Write-Host [i] Target Item: ($targetItem)
Write-Host [i] Destination: ($destinationFolder)
Write-Host [i] Copying target item to destination folder...
$shellApp.NameSpace("$destinationFolder").CopyHere("$targetItem")
Write-Host [i] Copy operation completed.
#[System.Console]::WriteLine("Press any key to exit...")
#[System.Console]::ReadKey($true)
Exit(0)
UPDATE
I've put all this after the param block and nothing has changed:
[Text.Encoding] $encoding = [Text.Encoding]::UTF8
[console]::InputEncoding = $encoding
[console]::OutputEncoding = $encoding
$OutputEncoding = $encoding
$PSDefaultParameterValues['Out-File:Encoding'] = $encoding
$PSDefaultParameterValues['*:Encoding'] = $encoding
$targetItem
already displays with??
. β MiniverοΏ½
. The encoding problem definitely happens earlier. You can also write$targetItem
to a file and get the same result:$targetItem | Set-Content test.txt -Encoding utf8
β Miniver$shellApp.NameSpace("$destinationFolder").CopyHere("$targetItem")
, did you try the Copy-Item cmdlet with parameter-LiteralPath $targetItem
? β Witted$targetItem
value is already broken. β Miniver$Folder = Split-Path $targetItem
and when I try to set this object$shellApp.NameSpace($Folder)
it becomes NUL. So I can't go forward to try:$Item = $objFolder.Items().Item($File)
and to finally try:$Target = $objFolder.GetDetailsOf($Item, 203)
β Chrysolite