Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
807 views
in Technique[技术] by (71.8m points)

.net - GetShortPathNameA not working in C#

I'm trying to get get the short filename from a long filename but I'm having problem in c# code. VB.Net code is:

Declare Function GetShortPathName Lib "kernel32" _
    Alias "GetShortPathNameA" (ByVal lpszLongPath As String, _
    ByVal lpszShortPath As String, ByVal cchBuffer As Long) As Long

Public Function GetShortName(ByVal sLongFileName As String) As String
    Dim lRetVal As Long, sShortPathName As String, iLen As Integer
    'Set up buffer area for API function call return
    sShortPathName = Space(255)
    iLen = Len(sShortPathName)

    'Call the function
    lRetVal = GetShortPathName(sLongFileName, sShortPathName, iLen)
    'Strip away unwanted characters.
     GetShortName = Left(sShortPathName, lRetVal)
End Function

I've converted this function to c#:

[DllImport("kernel32", EntryPoint = "GetShortPathNameA")]
static extern long GetShortPathName(string lpszLongPath, string lpszShortPath, long cchBuffer);

public string GetShortName(string sLongFileName)
{
    long lRetVal;
    string sShortPathName;
    int iLen;

    // Set up buffer area for API function call return
    sShortPathName = new String(' ', 1024);
    iLen = sShortPathName.Length;

    // Call the function
    lRetVal = GetShortPathName(sLongFileName, sShortPathName, iLen);

    // Strip away unwanted characters.
    return sShortPathName.Trim();
}

But I cant get the c# version work. Am I missing something or what is wrong?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The VB declaration dates back to VB6, it is quite inappropriate for a .NET language. Although the P/Invoke marshaller will allow unmanaged code scribbling into a string, it causes random failure due to string interning. You also really want to use the Unicode version so you don't get unexpected character translation. And you want to do something meaningful if the function fails. Here's my version:

public static string GetShortName(string sLongFileName) {
  var buffer = new StringBuilder(259);
  int len = GetShortPathName(sLongFileName, buffer, buffer.Capacity);
  if (len == 0) throw new System.ComponentModel.Win32Exception();
  return buffer.ToString();
}

[DllImport("kernel32", EntryPoint = "GetShortPathName", CharSet = CharSet.Auto, SetLastError = true)]
private static extern int GetShortPathName(string longPath, StringBuilder shortPath, int bufSize);

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

56.8k users

...