简体   繁体   English

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

[英]UNC Path To Access The Unicode Windows API Not Working

I have been trying to figure out a solution for working with really long file paths that are beyond the scope of the regular Windows API Like System.IO.PathToLongException Problem . 我一直在试图找到一种解决方案,用于处理超出常规Windows API(例如System.IO.PathToLongException Problem)问题的超长文件路径。 I read the blog described in the answer MS Blog On Long Paths , but when using that path format I'm still getting the exception for paths that are to long. 我阅读了答案MS Blog On Long Paths中描述的博客 ,但是当使用该路径格式时, 对于长路径 ,我仍然会遇到例外。 Am I doing something wrong? 难道我做错了什么?

Code: 码:

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);
            }
        }
    }
}
}

Notes: The Application above is a console app for creating a folder that's just out of reach for the regular Windows API without using the Unicode version of the API for testing another app that modifies folders in different ways on a fileshare. 注意:上面的应用程序是一个控制台应用程序,用于创建常规Windows API无法访问的文件夹,而无需使用API​​的Unicode版本来测试另一应用程序,该应用程序以不同方式在文件共享上修改文件夹。 I get the PathToLongException on Line 26 of the code when it tries to create the folder using the UNC Path format. 当它尝试使用UNC路径格式创建文件夹时,在代码的第26行上出现PathToLongException。 Any help would be greatly appreciated. 任何帮助将不胜感激。

Summary Of Problem: I need a way to work with paths exceeding the normal 248 character limit for folders and 260 for files in the regular Windows API. 问题摘要:我需要一种方法来处理路径,这些路径超出了常规Windows API中的文件夹的普通248个字符限制和文件的260个限制。

Well that blog post you linked to strongly implies that that format of \\?\\ doesn't work in .NET code as it says that if you want to use that then you'll have to resort to calling the Windows APIs yourself... which it doesn't look like you are doing. 好吧,您链接到的那篇博客文章强烈暗示\\?\\的格式在.NET代码中不起作用,因为它表示,如果要使用该格式,则必须求助于自己调用Windows API。看起来不像您在做。

One workaround that I have used in the past is to use the native Windows API function called DefineDosDevice to assign a drive letter to the furthest folder you can reach before you hit the PathToLongException, then use that drive letter from there on to navigate to further sub folders as you now have a much shorter path (and obviously remove this drive letter when you are done). 我过去使用的一种变通方法是使用称为DefineDosDevice的本机Windows API函数,将驱动器号分配给您在到达PathToLongException之前可以访问的最远文件夹,然后从那里使用该驱动器号导航到进一步的子项。文件夹,因为您现在的路径要短得多(完成后显然会删除此驱动器号)。 This works for both local paths and network UNC paths. 这适用于本地路径和网络UNC路径。 Here's my DllImport definition for vb.net: 这是我对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

and to use it: 并使用它:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM