C# GetShortPathNameW找不到指定的文件

C# GetShortPathNameW找不到指定的文件,c#,C#,我正在尝试获取包含宽字符的路径的短路径名,下面是我正在使用的代码,它总是为找不到的文件抛出异常。文件确实存在,我做错了什么 using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; using System.ComponentModel; namespace GetShortPathNameW_Test { class Program

我正在尝试获取包含宽字符的路径的短路径名,下面是我正在使用的代码,它总是为找不到的文件抛出异常。文件确实存在,我做错了什么

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.ComponentModel;

namespace GetShortPathNameW_Test
{
    class Program
    {
        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern int GetShortPathNameW(String pathName, System.Text.StringBuilder shortName, int cbShortName);

        static void Main(string[] args)
        {
            System.Text.StringBuilder new_path = new System.Text.StringBuilder(1500);
            int n = GetShortPathNameW("\\\\?\\C:\\\\temp\\test1.txt", new_path, 1024);

            if (n == 0)
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }
        }
    }
}

您显式调用Unicode版本
GetShortPathNameW
,但没有指定调用Unicode版本的正确参数

首先,将该方法重命名为
GetShortPathName
。这足以让它开始工作,而不需要任何其他更改。您的参数仍然是“ANSI”字符串,但这没关系,因为您正在调用“ANSI”实现

其次,您可以将
CharSet=CharSet.Unicode
添加到
DllImport
属性中,以指定需要Unicode实现。这还确保字符串作为Unicode字符串传递。这也将使一切按预期进行


现在,应该没有理由不调用函数的Unicode实现,但是如果不破坏向后兼容性,
DllImport
的默认值就无法更改,因此需要为每个函数指定它。

一个相当重要的问题是,无论
GetShortPathNameW
返回什么,都会引发异常。这只是显示问题的最短代码。这只是我的观点:它不会显示问题。如果
GetShortPathNameW
按照您所称的方式工作,您将得到一些完全不相关的异常,这很可能正是您现在得到的。一个简单的
if(n==0)
并注意为您引发的异常可以解决这个问题。谢谢,这很有效。是否需要带前缀的“\\?\”呢?我是按照msdn页面上的建议做的:当我添加这个时。@ScottLogan很难说。对于您现在正在处理的特定文件名,它应该不是必需的。一般来说,对于很长的路径名,可能需要这样做。然而,无条件地使用它可能是不可取的,因为
\\?\…
禁用了一些您可能习惯的东西,如文档所示。特别是,它禁用了相对路径的常见用法。