我正在 Powershell ISE 中制作一个脚本,为了防止盗版,脚本的一部分需要定位文件名,如果它存在于计算机上,则脚本将无法工作。这会起作用,因为下载一个文件两次会给它一点点(1)。
我用谷歌搜索了各种问题,但我真的想找出下载中文件的文件路径。
tl;博士
"$HOME\Downloads"
(New-Object -ComObject Shell.Application).NameSpace('shell:Downloads').Self.Path
"$HOME\Downloads"
假设了两件事,但它们不一定是正确的:
相当于环境变量
$HOME
(USERPROFILE
) 的 $env:USERPROFILE
是用户 documents 的根目录并不总是正确的,即不适用于 漫游配置文件 - 仅适用于 "${env:HOMEDRIVE}${env:HOMEPATH}"
可靠地反映文档文件夹。
更重要的是,下载文件夹可能已显式配置位于任意位置,与文档位置无关
确定下载文件夹位置的唯一可靠方法是向系统询问:
从 PowerShell Core 7.0.0-preview.3 开始,PowerShell 没有 PowerShell-native 向系统询问已知文件夹位置的方式。
虽然 PowerShell 几乎可以无限制地访问 .NET 框架,因此可以使用
System.Environment
类型的 .GetFolderPath()
方法来请求特殊的已知文件夹,但令人惊讶的是,指定的下载文件夹并不在其中。
只有 WinAPI 的已知文件夹 API 允许以稳健的方式检索指定的下载文件夹,而不依赖于与其他已知文件夹的固定关系:
在 PowerShell 中,您可以通过
Shell.Application
COM 服务器访问它:
(New-Object -ComObject Shell.Application).NameSpace('shell:Downloads').Self.Path
有关所有支持的(
shell:
前缀)文件夹标识符的列表,请参阅本文。
[1] 我所说的“天真”是指:一种人们“可以理解”想要使用的解决方案,但在“所有”情况下都不起作用。
使用Windows API:
function Get-DownloadFolderPath() {
$SHGetKnownFolderPathSignature = @'
[DllImport("shell32.dll", CharSet = CharSet.Unicode)]
public extern static int SHGetKnownFolderPath(
ref Guid folderId,
uint flags,
IntPtr token,
out IntPtr lpszProfilePath);
'@
$GetKnownFoldersType = Add-Type -MemberDefinition $SHGetKnownFolderPathSignature -Name 'GetKnownFolders' -Namespace 'SHGetKnownFolderPath' -Using "System.Text" -PassThru
$folderNameptr = [intptr]::Zero
[void]$GetKnownFoldersType::SHGetKnownFolderPath([Ref]"374DE290-123F-4565-9164-39C4925E467B", 0, 0, [ref]$folderNameptr)
$folderName = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($folderNameptr)
[System.Runtime.InteropServices.Marshal]::FreeCoTaskMem($folderNameptr)
$folderName
}
$downloadFolderPath = Get-DownloadFolderPath
write-host "Download folder path: $($downloadFolderPath)"
$downloadFolderPath = (Get-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders").PSObject.Properties["{374DE290-123F-4565-9164-39C4925E467B}"].Value
$path = Join-Path -Path "$([System.Environment]::GetFolderPath(40))" -ChildPath "Downloads"
嗯... C:/Users/这里是你的名字
/下载