【问题标题】:UNC Path To Access The Unicode Windows API Not Working访问 Unicode Windows API 的 UNC 路径不起作用
【发布时间】:2014-11-25 23:32:34
【问题描述】:

我一直在尝试找出一个解决方案来处理超出常规 Windows API 范围的非常长的文件路径,例如 System.IO.PathToLongException Problem。我阅读了答案MS Blog On Long Paths 中描述的博客,但是当使用该路径格式时,我仍然会遇到路径过长的异常。我做错了吗?

代码:

using System;
using System.Collections.Generic;
using System.IO;
using System.Diagnostics;
using System.Linq;
using System.Text;

namespace CreateTestDirForLongPaths
{
class Program
{
    public static string MainFolder = @"L:\users\"insert username here"\desktop\LPTD";
    public static bool Finished = false;
    public static int FolderCounter = 0;
    public static string PLD = @"L:\users\"insert username here"\desktop\LPTD\0";
    public static string CName = Environment.MachineName.ToString();
    public static string ComputerNamePre = @"\\" + CName + "\\";
    static void Main(string[] args)
    {
        DirectoryInfo Source = new DirectoryInfo(MainFolder);
        CreateTree(Source);
        PLD = PLD.Substring(3, PLD.Length -4);
        string LD = ComputerNamePre + @"L$" + "\\" + PLD + "\\" + "Folder Beyond reach";
        try
        {
            Directory.CreateDirectory(LD);
        }
        catch(Exception e)
        {
            Console.WriteLine("End Error:" + "\n\n" + e.Message + "\n\n" + LD);
        }
        Console.WriteLine("\n\nFinished.");
        Console.ReadKey(true);
    }

    static void CreateTree(DirectoryInfo directory)
    {
        try
        {
            MakeSubDirs(directory);
        }
        catch (IOException)
        {
            Finished = true;
        }
    }

    static void MakeSubDirs(DirectoryInfo directory)
    {
        string CurrentDir = null;
        try
        {
            string NewDir = directory.FullName + "\\" + FolderCounter.ToString();
            CurrentDir = directory.FullName;
            FolderCounter = ++FolderCounter;
            PLD = PLD + "\\" + FolderCounter.ToString();
            Directory.CreateDirectory(NewDir);
            DirectoryInfo NextDir = new DirectoryInfo(NewDir);
            CreateTree(NextDir);
        }
        catch (IOException)
        {
            Finished = true;
            try
            {
                Process.Start(CurrentDir);
            }
            catch(Exception e)
            {
                Console.WriteLine("Start Error" + "\n\n" + e.Message + CurrentDir);
            }
        }
    }
}
}

注意事项: 上面的应用程序是一个控制台应用程序,用于创建常规 Windows API 无法访问的文件夹,而无需使用 API 的 Unicode 版本来测试以不同方式在文件共享上修改文件夹的另一个应用程序。当它尝试使用 UNC 路径格式创建文件夹时,我在代码的第 26 行得到了 PathToLongException。任何帮助将不胜感激。

问题总结: 我需要一种方法来处理超过常规 Windows API 中文件夹的正常 248 个字符限制和文件的 260 个字符限制的路径。

【问题讨论】:

  • 你能包括“错误线”吗?
  • @Leonel 发生错误的行还是错误本身?

标签: c# unicode


【解决方案1】:

你链接到的那篇博客文章强烈暗示 \?\ 的格式在 .NET 代码中不起作用,因为它说如果你想使用它,那么你必须自己求助于调用 Windows API ......它看起来不像你正在做的。

我过去使用的一种解决方法是使用名为 DefineDosDevice 的本机 Windows API 函数将驱动器号分配给您在遇到 PathToLongException 之前可以到达的最远文件夹,然后从那里使用该驱动器号进行导航到进一步的子文件夹,因为您现在有一个更短的路径(完成后显然删除此驱动器号)。这适用于本地路径和网络 UNC 路径。这是我对 vb.net 的 DllImport 定义:

<DllImport("kernel32.dll", EntryPoint:="DefineDosDeviceW", SetLastError:=True)> _
Public Shared Function DefineDosDevice(ByVal dwFlags As UInteger, <InAttribute(), MarshalAsAttribute(UnmanagedType.LPWStr)> ByVal lpDeviceName As String, <InAttribute(), MarshalAsAttribute(UnmanagedType.LPWStr)> ByVal lpTargetPath As String) As <MarshalAsAttribute(UnmanagedType.Bool)> Boolean
End Function

并使用它:

Public Shared Sub AssignDriveLetterToPath(ByVal DriveLetter As Char, ByVal Path As String)
    If Not ApiDefinitions.DefineDosDevice(0, DriveLetter & ":", Path) Then
        Throw New ComponentModel.Win32Exception
    End If
End Sub

Public Shared Sub RemoveAssignedDriveLetter(ByVal DriveLetter As Char, ByVal Path As String)
    If Not ApiDefinitions.DefineDosDevice(ApiDefinitions.DDD_EXACT_MATCH_ON_REMOVE Or ApiDefinitions.DDD_REMOVE_DEFINITION, DriveLetter & ":", Path) Then
        Throw New ComponentModel.Win32Exception
    End If
End Sub

【讨论】:

  • 我真的很喜欢这个主意。我必须做一些工作才能翻译成 C#,但我确实喜欢这个概念。我今天会做一些工作并回复你。
  • 这看起来至少对这个项目起到了作用。非常感谢您的帮助。
【解决方案2】:

看起来有人已经为您完成了艰苦的工作,并围绕 Windows API 制作了一个 .NET 包装器,让您可以使用长路径:https://gallery.technet.microsoft.com:443/DelimonWin32IO-Library-V40-7ff6b16c

【讨论】:

  • 不过,在使用该链接中的库时,我需要将此库与应用程序一起安装。这是一种实用的编程方法吗?(诚实的问题)
  • @CalebB 我看到你已经接受了我的另一个答案,但是在回答这个关于用你的程序部署库的问题时——是的,这是非常正常和实用的。只要创建该库的个人/公司愿意您将其与您的应用程序一起部署(即他们不需要任何版税或许可费)。您需要做的就是将库 DLL 文件安装到您的应用安装到的同一文件夹中
  • 太棒了!谢谢大家的帮助,我一定会开始在未来的项目中集成这个库或类似的库。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多