From 7cb711c4e18c0b8b2272e0347bf09038c7781e53 Mon Sep 17 00:00:00 2001 From: Drew Noakes Date: Thu, 2 Mar 2023 12:08:42 +1100 Subject: [PATCH] Write file reference with correct capitalisation When dragging a file from Solution Explorer into the Managed Resources editor, the file path is written to the `.resx` file in lower case. This is because the "drop data" provided by Solution Explorer contains a lower-case path (both for SDK-style and legacy projects). To fix this, we walk the path, using `Path.EnumerateFileSystemEntries` to produce a correctly cased path for the file being dragged. Unfortunately there's no better way I could find to achieve this. I tried quite a few different approaches and this seemed like the least rubbish. The approach used in `GetFileNameInActualCase` elsewhere in the resource editor only handles the file name, not any directories above it. --- .../ResourceEditor/ResourceEditorView.vb | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.VisualStudio.Editors/ResourceEditor/ResourceEditorView.vb b/src/Microsoft.VisualStudio.Editors/ResourceEditor/ResourceEditorView.vb index 77e0aabb88c..319f5888f11 100644 --- a/src/Microsoft.VisualStudio.Editors/ResourceEditor/ResourceEditorView.vb +++ b/src/Microsoft.VisualStudio.Editors/ResourceEditor/ResourceEditorView.vb @@ -3053,7 +3053,7 @@ Namespace Microsoft.VisualStudio.Editors.ResourceEditor With Info .Guid = SplitInfo(0) .ProjectFile = SplitInfo(1) - .FilePath = SplitInfo(2) + .FilePath = GetExactPath(SplitInfo(2)) End With Files(i) = Info Next @@ -3069,6 +3069,30 @@ Namespace Microsoft.VisualStudio.Editors.ResourceEditor Return Files End Function + ' Converts the provided path to use the same capitalization as the file system. Files dragged + ' from Solution Explorer produce drop data having a lower-case path, which we then write to + ' in the .resx file. Windows has a case-insensitive file system, but users on other operation + ' systems (such as Linux) can hit run-time errors when the case doesn't match. This avoids that. + Private Shared Function GetExactPath(path As String) As String + If path Is Nothing OrElse (Not File.Exists(path) AndAlso Not Directory.Exists(path)) Then + Return path + End If + + Try + Dim root = System.IO.Path.GetPathRoot(path) + Dim parts = path.Substring(root.Length).Split(System.IO.Path.DirectorySeparatorChar, System.IO.Path.AltDirectorySeparatorChar) + + For Each part As String In parts + root = Directory.EnumerateFileSystemEntries(root, part).First() + Next + + Return root + Catch + ' If we hit any issues, just return the path unchanged + Return path + End Try + End Function + #End Region #End Region