UNC路径访问Unicode Windows API不起作用

时间:2014-11-25 23:32:35

标签: c# unicode

我一直在尝试找出一个解决方案,用于处理超常常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来说是不可及的,而不使用Unicode版本的API来测试另一个在文件共享上以不同方式修改文件夹的应用程序。当我尝试使用UNC路径格式创建文件夹时,我在代码的第26行得到PathToLongException。任何帮助将不胜感激。

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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

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