0

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. 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. 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. I get the PathToLongException on Line 26 of the code when it tries to create the folder using the UNC Path format. 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.

Community
  • 1
  • 1
CalebB
  • 597
  • 3
  • 17

2 Answers2

1

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.

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). This works for both local paths and network UNC paths. Here's my DllImport definition for vb.net:

<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
Chris128
  • 51
  • 1
  • 4
  • I really like that idea. I'll have to do some work to translate over to C# but I do like the concept. I'll do some work on that today and get back to you. – CalebB Nov 26 '14 at 14:34
  • It's looking like that did the trick at least for this project. Thank you very much for your help. – CalebB Nov 26 '14 at 17:59
0

It looks like someone has already done the hard work for you and made a .NET wrapper around the Windows APIs that let you use long paths: https://gallery.technet.microsoft.com:443/DelimonWin32IO-Library-V40-7ff6b16c

Chris128
  • 51
  • 1
  • 4
  • I would need to install this library along with the application when using the library in that link though. Is that a practical method in programming?(Honest question) – CalebB Nov 26 '14 at 14:26
  • @CalebB I see you have already accepted my other answer, but in response to this question about deploying libraries with your program - yes that is very normal and practical. As long as the person/company that made the library is happy for you to deploy it with your application (i.e. they don't require any royalties or license fees for this). All you need to do is have the library DLL file installed to the same folder your app is installed to – Chris128 Nov 26 '14 at 23:05
  • Awesome! Thank you for all the help, I'll definitely start working on integrating this library or similar ones in future projects. – CalebB Nov 29 '14 at 18:45