4

I'm trying to find a workaround for the Windows character limitation that doesn't allow a file to be copied if its name is >= 260 characters. According to this MSDN article, if \\?\ is prepended to the file name, this will circumvent the filename length restriction.

I tried this test:

string source = "\\\\?\\C:\\Users\\xxxx\\Documents\\Visual Studio 2013\\Projects\\PDFConverterTester\\PDFConverterTester_BatchGUI\\bin\\Debug\\folder1\\a.txt";
string dest= "\\\\?\\C:\\Users\\xxxx\\Documents\\Visual Studio 2013\\Projects\\PDFConverterTester\\PDFConverterTester_BatchGUI\\bin\\Debug\\folder2\\a.txt";            
System.IO.File.Copy(source, dest);

But this threw an exception:

Illegal characters in path.

Should I be applying this prefix in a different way?

Edit: My company's IT policy will not allow me to install any new software without a lengthy review process, meaning that I can't update to 4.6.2. so I'm trying to figure out how to resolve this with Windows API calls from my existing .NET 4.5 installation of Visual Studio.

Solomon Rutzky
  • 46,688
  • 9
  • 128
  • 171
sigil
  • 9,370
  • 40
  • 119
  • 199

1 Answers1

5

To enable long path support you either need to be targetting .Net Framework 4.6.2 (or newer) or you need to tell your app that it can support long filenames. To do that, add this to your app.config:

<runtime>
  <AppContextSwitchOverrides value="Switch.System.IO.UseLegacyPathHandling=false;Switch.System.IO.BlockLongPaths=false" />
</runtime>

Further reading can be done here.

DavidG
  • 113,891
  • 12
  • 217
  • 223
  • 1
    According to [Jeremy Kuhne's blog](https://blogs.msdn.microsoft.com/jeremykuhne/2016/06/21/more-on-new-net-path-handling/) on it, you need either, not both. If you target .NET Framework 4.6.2, then those switches already get set to false. You only need to explicitly set them to false if they were implicitly set to true, because you were targeting an older .NET Framework version. And that's also what the [reference source](https://github.com/Microsoft/referencesource/blob/master/mscorlib/system/AppContext/AppContextDefaultValues.Defaults.cs) indicates: see the `if (version <= 40601)` block. –  Dec 27 '16 at 00:54
  • @hvd Funnily, I was just running through that now and deciding whether to update this answer. – DavidG Dec 27 '16 at 00:55
  • 2
    Note that the blog post you link to in your answer is about transparently handling long file paths, i.e. *without* the application having to prepend ```\\?\```. That's probably better but requires OS support (an up-to-date Windows 10 with non-standard settings). The one I linked to covers not rejecting ```\\?\``` paths, requiring application workarounds for long paths but making it work on a lot more systems. –  Dec 27 '16 at 01:05
  • My company's IT policy will not allow me to install any new software without a lengthy review process, meaning that I can't update to 4.6.2. so I'm trying to figure out how to resolve this with Windows API calls from my existing .NET 4.5 installation of Visual Studio. I'll update my question with this information. – sigil Dec 28 '16 at 23:55