我一直在尝试找出一个解决方案,用于处理超常常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文件的路径。
答案 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