PowerShell v7如何获取Windows资源管理器中文件的本地化名称
PowerShell 7 获取文件/文件夹本地化名称实现方案
PowerShell 7 没有内置可直接调用的原生cmdlet实现该需求,但可以通过调用Windows Shell原生API配合desktop.ini读取实现,最终效果和资源管理器显示的本地化名称完全一致。
核心实现原理
desktop.ini中LocalizedFileNames段存储的@<dll路径>,-<资源ID>格式指针,是Windows Shell标准的间接字符串标识,可通过shlwapi.dll导出的SHLoadIndirectStringAPI直接解析为当前系统语言对应的明文字符串,不需要手动加载资源文件、匹配语言ID。
可直接使用的Get-LocalizedName函数
# 仅在Windows平台加载所需API if ($IsWindows) { Add-Type -Namespace Win32 -Name NativeMethods -MemberDefinition @" [DllImport("shlwapi.dll", CharSet = CharSet.Unicode, SetLastError = true)] private static extern int SHLoadIndirectString(string pszSource, System.Text.StringBuilder pszOutBuf, int cchOutBuf, IntPtr ppvReserved); public static string GetIndirectString(string source) { if (string.IsNullOrEmpty(source)) return null; const int bufferSize = 1024; var buffer = new System.Text.StringBuilder(bufferSize); int hresult = SHLoadIndirectString(source, buffer, bufferSize, IntPtr.Zero); return hresult == 0 ? buffer.ToString() : null; } "@ } function Get-LocalizedName { [CmdletBinding()] param( [Parameter(Mandatory = $true, ValueFromPipeline = $true)] [string]$FilePath ) process { # 非Windows平台直接返回原始文件名 if (-not $IsWindows) { return Split-Path $FilePath -Leaf } # 解析目标路径信息 $fullPath = Resolve-Path $FilePath -ErrorAction Stop $item = Get-Item -LiteralPath $fullPath -ErrorAction Stop $parentDir = if ($item.PSIsContainer) { Split-Path $item.FullName -Parent } else { $item.DirectoryName } $originalName = $item.Name $desktopIniPath = Join-Path $parentDir 'desktop.ini' # 无desktop.ini直接返回原始名称 if (-not (Test-Path -LiteralPath $desktopIniPath -PathType Leaf)) { return $originalName } # 读取LocalizedFileNames段的对应值 $localizedNamePtr = $null $inSection = $false Get-Content -LiteralPath $desktopIniPath -Encoding Unicode -ErrorAction SilentlyContinue | ForEach-Object { $line = $_.Trim() if ($line -eq '[LocalizedFileNames]') { $inSection = $true return } if ($inSection -and $line.StartsWith('[')) { $inSection = $false return } if ($inSection -and $line -match "^$([regex]::Escape($originalName))=(.+)$") { $localizedNamePtr = $matches[1] } } # 无本地化配置直接返回原始名称 if ([string]::IsNullOrEmpty($localizedNamePtr)) { return $originalName } # 调用API解析资源指针 $resolvedName = [Win32.NativeMethods]::GetIndirectString($localizedNamePtr) # 解析失败则回退到原始名称 return $resolvedName ?? $originalName } }
使用示例
# 示例:读取管理工具文件夹的德语本地化名称 $adminToolsPath = [Environment]::GetFolderPath('AdministrativeTools') Get-LocalizedName -FilePath $adminToolsPath # de-DE区域下返回值:Windows-Verwaltungsprogramme
注意事项
- 该实现仅支持Windows系统,非Windows平台下不存在desktop.ini本地化机制,函数会直接返回原始文件名
- API会自动处理环境变量展开、系统语言匹配、资源加载逻辑,返回结果和资源管理器显示的名称完全一致
- 自动处理解析失败、无本地化配置的边界场景,不会抛出非预期错误,始终回退返回原始文件名
内容的提问来源于stack exchange,提问作者Surak
相关产品推荐
相关产品推荐

