将长路径名转换为短路径的方法返回null

时间:2018-06-11 07:52:18

标签: c# asp.net-mvc

我试图确保我可以下载文件,如果它有一个长文件名。这是我正在使用的课程。

public class ShortFileName
{
    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    public static extern int GetShortPathName(
    [MarshalAs(UnmanagedType.LPTStr)]
    string path,
    [MarshalAs(UnmanagedType.LPTStr)]
    StringBuilder shortPath,
    int shortPathLength
    );
}

这是我的控制器中实现下载的代码。

 public ActionResult Download(string path, string fileName)
    {
        try
        {
            StringBuilder shortPath = new StringBuilder(255);

            ShortFileName.GetShortPathName(path, shortPath, shortPath.Capacity);

            byte[] fileBytes = System.IO.File.ReadAllBytes(shortPath.ToString());

            return File(fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, fileName);
        }
        catch (Exception)
        {
            throw;
        }

    }

当文件路径过长时,shortPath为null。

1 个答案:

答案 0 :(得分:0)

这应该有效。如果您不需要支持超过260个字符的原始路径名,则可以删除与PREFIX相关的所有代码。

[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
static extern uint GetShortPathName(
    [MarshalAs(UnmanagedType.LPTStr)]
    string lpszLongPath,
    [MarshalAs(UnmanagedType.LPTStr)]
    StringBuilder lpszShortPath,
    uint cchBuffer);

public static string ShortFilenameFor(string longFilename)
{
    // Add to the long filename a prefix to cause the API to handle filenames longer than 260 characters.

    const string PREFIX = @"\\?\";
    longFilename = PREFIX + longFilename;

    // First check how much space is required for the short filename.

    uint length = GetShortPathName(longFilename, null, 0);

    if (length == 0)
        throw new Win32Exception(Marshal.GetLastWin32Error());

    // Now allocate buffer of the correct length and fill it.

    StringBuilder buffer = new StringBuilder((int)length);
    uint result = GetShortPathName(longFilename, buffer, length);

    if (result == 0)
        throw new Win32Exception(Marshal.GetLastWin32Error());

    buffer.Remove(0, PREFIX.Length);
    return buffer.ToString();
}