我有一个脚本,它接受一个目录作为用户的参数。我想显示在Windows中显示的目录路径的名称。即,
PS C:\SomeDirectory> cd .\anotherdirectory
PS C:\AnotherDirectory> . .\myscript.ps1 "c:\somedirectory"
C:\SomeDirectory
如果给出“c:\ somedirectory”,如何检索“C:\ SomeDirectory”?
答案 0 :(得分:6)
这应该有效:
function Get-PathCanonicalCase {
param($path)
$newPath = (Resolve-Path $path).Path
$parent = Split-Path $newPath
if($parent) {
$leaf = Split-Path $newPath -Leaf
(Get-ChildItem $parent| Where-Object{$_.Name -eq $leaf}).FullName
} else {
(Get-PSDrive ($newPath -split ':')[0]).Root
}
}
答案 1 :(得分:6)
接受的答案只能获得正确的文件大小写。父路径留有用户提供的案例。这是我的解决方案。
$getPathNameSignature = @'
[DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Auto)]
public static extern uint GetLongPathName(
string shortPath,
StringBuilder sb,
int bufferSize);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError=true)]
public static extern uint GetShortPathName(
string longPath,
StringBuilder shortPath,
uint bufferSize);
'@
$getPathNameType = Add-Type -MemberDefinition $getPathNameSignature -Name GetPathNameType -UsingNamespace System.Text -PassThru
function Get-PathCanonicalCase
{
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[string]
# Gets the real case of a path
$Path
)
if( -not (Test-Path $Path) )
{
Write-Error "Path '$Path' doesn't exist."
return
}
$shortBuffer = New-Object Text.StringBuilder ($Path.Length * 2)
[void] $getPathNameType::GetShortPathName( $Path, $shortBuffer, $shortBuffer.Capacity )
$longBuffer = New-Object Text.StringBuilder ($Path.Length * 2)
[void] $getPathNameType::GetLongPathName( $shortBuffer.ToString(), $longBuffer, $longBuffer.Capacity )
return $longBuffer.ToString()
}
我已将上述代码集成到Resolve-PathCase Carbon PowerShell模块的一部分中。 免责声明:我是Carbon的所有者/维护者。
答案 2 :(得分:1)
使用Christian的GetDirectories
建议,这是另一个不太复杂的解决方案:
function Get-PathCanonicalCase
{
param( $path )
$newPath = (Resolve-Path $path).Path
$root = [System.IO.Path]::GetPathRoot( $newPath )
if ( $newPath -ne $root ) # Handle case where changing to root directory
{ $newPath = [System.IO.Directory]::GetDirectories( $root, $newPath.Substring( $root.Length ) )[ 0 ] }
$newPath
}
编辑:感谢您的帮助。
顺便说一句,我想要的只是在一个小的实用程序脚本中使用,覆盖默认的cd别名,允许我指定一些搜索的“根”目录,如果相对于当前目录的路径不存在的话。也就是说,无论我当前的位置如何,它都允许我cd Documents
,cd trunk
,cd Release-10.4
。在我输入的情况下,而不是实际情况,我很高兴得到提示。
# Usage:
# Set up in $profile - define the functions and reassign 'cd'. Example:
# -----
# . .\Set-LocationEx.ps1 "c:\dev\Code", "c:\dev\Code\releases", "$HOME" -Verbose
# if (test-path alias:cd) { remove-item alias:cd > $null }
# Set-Alias cd Set-LocationEx
# -----
param( [parameter(Mandatory = $true)][string[]]$roots )
Set-StrictMode -Version Latest
Write-Verbose "Set-LocationEx roots: $(Join-String -Strings $roots -Separator ', ')"
function Set-LocationEx
{
param( [Parameter( Mandatory="true" )]$path )
process
{
$verbose = ( $PSCmdlet.MyInvocation.BoundParameters.ContainsKey( "Verbose" ) -and $PSCmdlet.MyInvocation.BoundParameters[ "Verbose" ].IsPresent )
if ( $verbose )
{ Write-Verbose( "$(Join-String -Strings $roots -Separator ', ')" ) }
if ( !( Test-Path $path ) )
{
foreach ( $p in $roots )
{
$newPath = Join-Path $p $path
if ( $verbose ) { Write-Verbose "Looking for $newPath" }
if ( Test-Path $newPath )
{
$newPath = Get-PathCanonicalCase( $newPath )
if ( $verbose ) { Write-Verbose "Found $newPath" }
Push-Location $newPath
return
}
}
}
if ( Test-Path $path )
{ $path = Get-PathCanonicalCase( $path ) }
Push-Location $path
}
}
function Get-LocationExRoots
{
process
{
Write-Output (Join-String -Strings $roots -NewLine)
}
}
function Get-PathCanonicalCase
{
param( $path )
$newPath = (Resolve-Path $path).Path
$root = [System.IO.Path]::GetPathRoot( $newPath )
if ( $newPath -ne $root ) # Handle root directory
{ $newPath = [System.IO.Directory]::GetDirectories( $root, $newPath.Substring( $root.Length ) )[ 0 ] }
$newPath
}
答案 3 :(得分:1)
我发现使用PowerShell通配符的方法更简单。
$canonicalCasePath = Get-ChildItem -Path $wrongCasingPath.Replace("\","\*") | Where FullName -IEQ $wrongCasingPath | Select -ExpandProperty FullName