question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

.NET Framework 4.6.2 Long Paths: Illegal Characters in path exception

See original GitHub issue

Environment

  • Pythonnet version: 2.5.2
  • Python version: 3.8.10
  • Operating System: Windows 10
  • .NET Runtime: 4.6.2

Details

  • .NET Framework 4.6.2 supports long paths by default. When calling an assembly that a targets .NET Framework 4.6.2, long path support is disabled and causes an Illegal characters in path exception when using a FileStream constructor:
System.ArgumentException: Illegal characters in path.
   at System.Security.Permissions.FileIOPermission.EmulateFileIOPermissionChecks(String fullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)

Workaround: For now, the workaround is to create a python.exe.config application config file with the following:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <startup>
    <supportedRuntime version=".NETFramework,Version=v4.6.2"/>
  </startup>
  <runtime>
    <AppContextSwitchOverrides value="Switch.System.IO.UseLegacyPathHandling=false;Switch.System.IO.BlockLongPaths=false" />
  </runtime> 
</configuration>

This, however, creates a global solution which is not desired. An alternate workaround is to explicitly update the AppContext variables in the Python script before any code is executed (credit to https://stackoverflow.com/questions/53193280/long-path-workaround-not-working-on-some-installs):

type = Type.GetType("System.AppContext")
if type:
    AppContext.SetSwitch("Switch.System.IO.UseLegacyPathHandling", False)
    AppContext.SetSwitch("Switch.System.IO.BlockLongPaths", False)

    switchType = Type.GetType("System.AppContextSwitches")
    if switchType:
        # We also have to reach into System.AppContextSwitches and manually update the cached private versions of these properties (don't ask me why):

        legacyField = switchType.GetField("_useLegacyPathHandling", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic)
        if legacyField:
            legacyField.SetValue(None, -1) # <- caching uses 0 to indicate no value, -1 for false, 1 for true.

        blockingField = switchType.GetField("_blockLongPaths", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic)
        if blockingField:
            blockingField.SetValue(None, -1) # <- caching uses 0 to indicate no value, -1 for false, 1 for true.

Again, not an ideal solution because this uses reflection to set values of private variables by name.

Ideally, the CLR loader would load the proper AppContext defaults based on the version of target framework like is shown here:

https://referencesource.microsoft.com/#mscorlib/system/AppContext/AppContextDefaultValues.Defaults.cs,60

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:16 (7 by maintainers)

github_iconTop GitHub Comments

1reaction
zhawkins-viasatcommented, Mar 1, 2023

The config file is important but is not what was being asked here. Unfortunately, the answers from the contributors devolved and started to be insulting so the discussion could not be continued in a respectful and logical manner. Configs should absolutely be honored and using them is still relevant. However, in absence of a config file, the defaults for the framework version under which the dll was compiled should be honored. It shouldn’t require a specific config file in order to enable settings that were already implicit in the version of the framework that was being used.

1reaction
lostmsucommented, Aug 15, 2022

Lol, your point has no proof here. I just told you that the script should set the target framework, because the script is the entry point, and that’s how it works in .NET. Additionally, see Python’s motto.

Read more comments on GitHub >

github_iconTop Results From Across the Web

visual studio 2013 - .Net 4.6.2 C# Long Path Handling
Net 4.6.2 C# Long Path Handling - Ilegal Character exception thrown ... the release config build is throwing a "Illegal characters in path....
Read more >
PathTooLongException Class (System.IO)
The exception that is thrown when a path or fully qualified file name is longer than the system-defined maximum length.
Read more >
Handle exception with long paths in Powershell
\ in the path variable, it failes saying that there are Illegal characters in path even if I add -LiteralPath. Any help would...
Read more >
Get-ChildItem and Get-ACL not working with local paths ...
Sadly I am experiencing some issues with paths longer than 260 characters. I am trying all these commands locally on the server so...
Read more >
Destination Path Too Long Fix (when Moving/Copying a File)
Most standard applications, including Windows Explorer (File Explorer), do not work correctly with long path files exceeding 256 characters.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found