AdaskoTheBeAsT / Typewriter

Automatic TypeScript template generation from C# source files
http://frhagn.github.io/Typewriter
Apache License 2.0
62 stars 12 forks source link

Destination over 260 characters fails #37

Closed JBBianchi closed 7 months ago

JBBianchi commented 7 months ago

Where trying to write a file with a path longer than 260 character, an error is thrown (the path has been changed but the length is the saame):

15:53:16.000 ERROR: Error processing queue: Could not find a part of the path 'C:\Dev\SomeInnerPath\Github\Project\src\innerpath\another-subpath\A.Very.Long.Project.Name.Like.Dotnet.People.Like\packages\some-random-scope\some-package-name\src\lib\events\a-very-very-very-very-very-very-very-very-very-very-very-very-very-very-long-file-name.ts'.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   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, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
   at System.IO.StreamWriter.CreateFile(String path, Boolean append, Boolean checkHost)
   at System.IO.StreamWriter..ctor(String path, Boolean append, Encoding encoding, Int32 bufferSize, Boolean checkHost)
   at System.IO.File.InternalWriteAllText(String path, String contents, Encoding encoding, Boolean checkHost)
   at Typewriter.Generation.Template.SaveFile(File file, String output, Boolean& success)
   at Typewriter.Generation.Template.RenderFile(File file)
   at Typewriter.Generation.Controllers.GenerationController.<>c__DisplayClass5_1.<OnTemplateChanged>b__1()
   at Typewriter.Generation.Controllers.EventQueue.ProcessQueue()

Even though LongPathsEnabledis true in the registry: image

image

image

Or via gpedit: image

One thing I find odd is that it's not the System.IO.PathTooLongException that seems to be thrown but it's definitely related to the 260 char limitation.

I read things about the Switch.System.IO.UseLegacyPathHandling, Switch.System.IO.BlockLongPaths or <longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware> in the application manifest but I don't think I have access to those or if they even apply to a VS extension...

Maybe WriteFile could rely on something else than System.IO, like ZetaLongPaths or other workarounds ?

// OS: Windows 10/11 x64

AdaskoTheBeAsT commented 7 months ago

Indeed let me take a look

AdaskoTheBeAsT commented 7 months ago

https://github.com/AdaskoTheBeAsT/Typewriter/releases/tag/v2.20.0

JBBianchi commented 7 months ago

Now I have this error straight away:

10:58:10.124 ERROR: Error processing queue: The filename, directory name, or volume label syntax is incorrect
   at Typewriter.LongPaths.FileWriter.WriteAllText(String path, String contents)
   at Typewriter.Generation.Template.SaveFile(File file, String output, Boolean& success)
   at Typewriter.Generation.Template.RenderFile(File file)
   at Typewriter.Generation.Controllers.GenerationController.<>c__DisplayClass5_1.<OnTemplateChanged>b__1()
   at Typewriter.Generation.Controllers.EventQueue.ProcessQueue()
AdaskoTheBeAsT commented 7 months ago

I added small part which creates folder if it is missing - also it seems interop is not needed as System.IO is able to work with long paths when using that magic prefix - can you run test in solution "FileWriterTest" ? it should pass

JBBianchi commented 7 months ago

The test does indeed run successfully.

JBBianchi commented 7 months ago

I changed the path in the test to the actual failing one and then the test fails. I think it's because I use .. in the path.

For instance, by replacing the path in test with

var path = @"C:\Dev\..\Dev\SomeInnerPath\Github\Project\src\innerpath\another-subpath\A.Very.Long.Project.Name.Like.Dotnet.People.Like\packages\some-random-scope\some-package-name\src\lib\events\a-very-very-very-very-very-very-very-very-very-very-very-very-very-very-long-file-name.ts";            

Which is basically the same, then the test fails.

I think it can be fixed by calling GetFullPath

var path = @"C:\Dev\..\Dev\SomeInnerPath\Github\Project\src\innerpath\another-subpath\A.Very.Long.Project.Name.Like.Dotnet.People.Like\packages\some-random-scope\some-package-name\src\lib\events\a-very-very-very-very-very-very-very-very-very-very-very-very-very-very-long-file-name.ts";
path = System.IO.Path.GetFullPath(path);

Then the test is successful.

AdaskoTheBeAsT commented 7 months ago

ok thanks https://github.com/AdaskoTheBeAsT/Typewriter/releases/tag/v2.22.0

JBBianchi commented 7 months ago

It seems to work flawlessly now. Thanks a lot for your reactivity !