From: Henry on
This function refuses to return the long path name when called on Windows
2000 Professional. It does not return an error value or raise an exception,
it just does nothing.

<DllImport("kernel32")> _
Private Shared Function GetLongPathNameA(<MarshalAs(UnmanagedType.LPStr)>
ByVal ShortPath As String, <MarshalAs(UnmanagedType.LPStr)> ByVal LongPath As
String, ByVal BufferSize As Integer) As Integer
End Function

Private Function LongPathName(ByVal shortPathName As String) As String

Dim RV As Integer
Dim LongPath As String = ""

'Determine the size of the buffer needed.
RV = GetLongPathNameA(shortPathName, LongPath, LongPath.Length)
If (RV = 0) Then Return ""

'Allocate storage for the buffer and call again.
LongPath = Space(RV)
RV = GetLongPathNameA(shortPathName, LongPath, LongPath.Length)
If (RV = 0) Then Return ""
Return LongPath

End Function

When I call the function with shortPathName =
"C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp", the second call to GetLongPathNameA
returns the LongPath variable still filled with spaces and nothing happens.
This is not the case with the Unicode version of the function. I have left
out the try...catch block for simplicity.

Just a note. Some API functions let you call them with no buffer; however,
this one does not.

ie RV = GetShortPathNameW(longPathName, Nothing, 0)


From: Herfried K. Wagner [MVP] on
"Henry" <Henry(a)discussions.microsoft.com> schrieb:
> This function refuses to return the long path name when called on Windows
> 2000 Professional. It does not return an error value or raise an
> exception,
> it just does nothing.
>
> <DllImport("kernel32")> _
> Private Shared Function GetLongPathNameA(<MarshalAs(UnmanagedType.LPStr)>
> ByVal ShortPath As String, <MarshalAs(UnmanagedType.LPStr)> ByVal LongPath
> As
> String, ByVal BufferSize As Integer) As Integer
> End Function
>
> Private Function LongPathName(ByVal shortPathName As String) As String
>
> Dim RV As Integer
> Dim LongPath As String = ""
>
> 'Determine the size of the buffer needed.
> RV = GetLongPathNameA(shortPathName, LongPath, LongPath.Length)
> If (RV = 0) Then Return ""
>
> 'Allocate storage for the buffer and call again.
> LongPath = Space(RV)
> RV = GetLongPathNameA(shortPathName, LongPath, LongPath.Length)
> If (RV = 0) Then Return ""
> Return LongPath
>
> End Function
>
> When I call the function with shortPathName =
> "C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp", the second call to GetLongPathNameA
> returns the LongPath variable still filled with spaces and nothing
> happens.

Note that 'GetLongPathName' will only return the long path if the path
actually exists. The code below works fine for me on a Windows XP
Professional SP2 machine:

\\\
Private Declare Auto Function GetLongPathName Lib "kernel32.dll" ( _
ByVal lpszShortPath As String, _
ByVal lpszLongPath As String, _
ByVal cchBuffer As Int32 _
) As Int32

Private Const MAX_PATH As Int32 = 260

Private Function LongPathName(ByVal ShortPathName As String) As String
Dim LongPath As String = Space(MAX_PATH)
Dim dwLen As Int32 = Len(LongPath)
Dim dwRet As Int32 = _
GetLongPathName(ShortPathName, LongPath, dwLen)
If dwRet > dwLen Then
LongPath = Space(dwRet)
End If
dwRet = GetLongPathName(ShortPathName, LongPath, dwRet)
Return Strings.Left(LongPath, dwRet)
End Function
///

--
M S Herfried K. Wagner
M V P <URL:http://dotnet.mvps.org/>
V B <URL:http://classicvb.org/petition/>

From: Crouchie1998 on
Henry!

Take a look at this sample by Duncan MacKenzie from MSDN:

http://www.duncanmackenzie.net/Samples/ShortPath.zip

I hope this helps,

Crouchie1998
MCP MCSE


From: Dragon on
If string parameter is going to be changed then it's better to declare
it as StringBuilder. Params declared as String sometimes work, sometimes
not. Also with StringBuilder class you don't have to worry about
trailing spaces or zero characters.

In addition, I can't imagine why do you need to call ANSI version of the
function. Apply the Auto modifier (Charset:=CharSet.Auto in your case)
and let runtime choose.

So...

~
Friend Declare Auto Function GetLongPathName Lib "kernel32.dll" ( _
<MarshalAs(UnmanagedType.LPTStr), [In]()> ByVal lpszShortPath As
String, _
<MarshalAs(UnmanagedType.LPTStr)> ByVal lpszLongPath As
StringBuilder, _
ByVal cchBuffer As Integer _
) As Integer

REM If you still want to use ANSI version then that's it:
Friend Declare Ansi Function GetLongPathNameA Lib "kernel32.dll" ( _
<MarshalAs(UnmanagedType.LPStr), [In]()> ByVal lpszShortPath As
String, _
<MarshalAs(UnmanagedType.LPStr)> ByVal lpszLongPath As
StringBuilder, _
ByVal cchBuffer As Integer _
) As Integer

Private Function LongPathName(ByVal shortPathName As String) As
String
Dim RV As Integer
Dim LongPath As StringBuilder = Nothing

'Determine the size of the buffer needed.
RV = GetLongPathNameA(shortPathName, Nothing, 0)
If RV = 0 Then Return String.Empty

'Allocate storage for the buffer and call again.
LongPath = New StringBuilder(RV)
RV = GetLongPathNameA(shortPathName, LongPath,
LongPath.Capacity)
If RV = 0 Then Return String.Empty
Return LongPath.ToString
End Function
~

> Just a note. Some API functions let you call them with no buffer;
however,
> this one does not.

> ie RV = GetShortPathNameW(longPathName, Nothing, 0)

?

The example above works just fine for me and you see it uses Nothing for
buffer.

Roman


From: Henry on
Thanks everybody...I appreciate your help.

The reason why I am specifically calling the ANSII version on Windows 2000
Professional is to simply test some code that will execute on Windows 9x
machines. Also, the path that I am using to test the GetLongPathNameA
function is the temporary directory Environ("tmp") or Environ("temp"). So I
know the path exists.

Once again, thanks for your help. I am going to try your suggestions and I
am sure I will figure it out eventually.