How to ensure there is trailing directory separator in paths?





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







41















I'm having an issue with AppDomain.CurrentDomain.BaseDirectory.



Sometimes the path ends with '' and other times it doesn't.
I can't find a reason for this.



It would be fine if I was using Path.Combine but I want to do Directory.GetParent and it yields different results.



Have you found this problem?



Can I do things differently to get the parent directory of the application?



My current hack is:



var baseDir = AppDomain.CurrentDomain.BaseDirectory;
if (!baseDir.EndsWith("\")) baseDir += "\";









share|improve this question































    41















    I'm having an issue with AppDomain.CurrentDomain.BaseDirectory.



    Sometimes the path ends with '' and other times it doesn't.
    I can't find a reason for this.



    It would be fine if I was using Path.Combine but I want to do Directory.GetParent and it yields different results.



    Have you found this problem?



    Can I do things differently to get the parent directory of the application?



    My current hack is:



    var baseDir = AppDomain.CurrentDomain.BaseDirectory;
    if (!baseDir.EndsWith("\")) baseDir += "\";









    share|improve this question



























      41












      41








      41


      6






      I'm having an issue with AppDomain.CurrentDomain.BaseDirectory.



      Sometimes the path ends with '' and other times it doesn't.
      I can't find a reason for this.



      It would be fine if I was using Path.Combine but I want to do Directory.GetParent and it yields different results.



      Have you found this problem?



      Can I do things differently to get the parent directory of the application?



      My current hack is:



      var baseDir = AppDomain.CurrentDomain.BaseDirectory;
      if (!baseDir.EndsWith("\")) baseDir += "\";









      share|improve this question
















      I'm having an issue with AppDomain.CurrentDomain.BaseDirectory.



      Sometimes the path ends with '' and other times it doesn't.
      I can't find a reason for this.



      It would be fine if I was using Path.Combine but I want to do Directory.GetParent and it yields different results.



      Have you found this problem?



      Can I do things differently to get the parent directory of the application?



      My current hack is:



      var baseDir = AppDomain.CurrentDomain.BaseDirectory;
      if (!baseDir.EndsWith("\")) baseDir += "\";






      c# .net path






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 10 '14 at 14:15









      participant

      1,92111635




      1,92111635










      asked Dec 5 '13 at 16:54









      pitermarxpitermarx

      4481615




      4481615
























          4 Answers
          4






          active

          oldest

          votes


















          37














          It's like that, just keep your hack.



          In plain Win32 there is an helper function PathAddBackslash for that. Just be consistent with directory separator: check Path.DirectorySeparatorChar and Path.AltDirectorySeparatorChar instead of hard-code .



          Something like this (please note there is not a serious error checking):



          string PathAddBackslash(string path)
          {
          // They're always one character but EndsWith is shorter than
          // array style access to last path character. Change this
          // if performance are a (measured) issue.
          string separator1 = Path.DirectorySeparatorChar.ToString();
          string separator2 = Path.AltDirectorySeparatorChar.ToString();

          // Trailing white spaces are always ignored but folders may have
          // leading spaces. It's unusual but it may happen. If it's an issue
          // then just replace TrimEnd() with Trim(). Tnx Paul Groke to point this out.
          path = path.TrimEnd();

          // Argument is always a directory name then if there is one
          // of allowed separators then I have nothing to do.
          if (path.EndsWith(separator1) || path.EndsWith(separator2))
          return path;

          // If there is the "alt" separator then I add a trailing one.
          // Note that URI format (file://drive:pathfilename.ext) is
          // not supported in most .NET I/O functions then we don't support it
          // here too. If you have to then simply revert this check:
          // if (path.Contains(separator1))
          // return path + separator1;
          //
          // return path + separator2;
          if (path.Contains(separator2))
          return path + separator2;

          // If there is not an "alt" separator I add a "normal" one.
          // It means path may be with normal one or it has not any separator
          // (for example if it's just a directory name). In this case I
          // default to normal as users expect.
          return path + separator1;
          }


          Why so much code? Primary because if user enter /windows/system32 you don't want to get /windows/system32 but /windows/system32/, devil is in the details...



          To put everything together in a nicer self-explicative form:



          string PathAddBackslash(string path)
          {
          if (path == null)
          throw new ArgumentNullException(nameof(path));

          path = path.TrimEnd();

          if (PathEndsWithDirectorySeparator())
          return path;

          return path + GetDirectorySeparatorUsedInPath();

          bool PathEndsWithDirectorySeparator()
          {
          if (path.Length == 0)
          return false;

          char lastChar = path[path.Length - 1];
          return lastChar == Path.DirectorySeparatorChar
          || lastChar == Path.AltDirectorySeparatorChar;
          }

          char GetDirectorySeparatorUsedInPath()
          {
          if (path.Contains(Path.AltDirectorySeparatorChar))
          return Path.AltDirectorySeparatorChar;

          return Path.DirectorySeparatorChar;
          }
          }


          URI format file:// is not handled even if it may seem so. The right thing is again to do what the other .NET I/O functions do: do not handle this format (and possibly throw an exception).



          As alternative you're always able to import Win32 function:



          [DllImport("shlwapi.dll", 
          EntryPoint = "PathAddBackslashW",
          SetLastError = True,
          CharSet = CharSet.Unicode)]
          static extern IntPtr PathAddBackslash(
          [MarshalAs(UnmanagedType.LPTStr)]StringBuilder lpszPath);





          share|improve this answer


























          • I'm not sure I would use the alternative. Although its interesting, a developer would not be sure about what the code is doing.

            – pitermarx
            Dec 17 '13 at 17:12








          • 4





            @pitermarx actually we're not sure even about what FileCopy does! A system function IMO is always a good choice, at least it'll handle any change for you (and it'll always respect its contract: to add a trailing backslash). Well not always they're perfect solution, of course...

            – Adriano Repetti
            Dec 17 '13 at 17:34













          • Should EndsWidth be EndsWith ..also, had to remove const from your sample..

            – Bostwick
            Jul 8 '14 at 14:10











          • @Bostwick you're right. Fixed, thank you!

            – Adriano Repetti
            Jul 8 '14 at 14:23











          • @AdrianoRepetti: Windows allows leading spaces in file/directory names, so the Trim() call does no good. (It probably also allows trailing spaces, but at least cmd.exe doesn't seem to support them, and I haven't done further testing, so I cannot be sure.) Personally I'd just completely remove the Trim call. After all it's not the functions responsibility to "fix" broken paths. Also I would change the "which one to add" logic to just replicate the last seperator in the string (I've seen file:// paths that use backslaches in the rest of the string).

            – Paul Groke
            Jan 7 '16 at 16:14



















          51














          You can easily ensure the behaviour you desire by using TrimEnd:



          var baseDir = AppDomain.CurrentDomain.BaseDirectory.TrimEnd('\') + "\";


          To be optimally efficient (by avoiding extra allocations), check that the string doesn't end with a before making changes, since you won't always need to:



          var baseDir = AppDomain.CurrentDomain.BaseDirectory;
          if (!baseDir.EndsWith("\"))
          {
          baseDir += "\";
          }





          share|improve this answer





















          • 21





            To make it cross platform you could replace the \ with Path.DirectorySeparatorChar

            – Rots
            Feb 9 '14 at 22:49








          • 5





            @Rots: The TrimEnd call should include AltDirectorySeparatorChar as well

            – Paul Groke
            Jan 7 '16 at 16:06



















          4














          In order to get cross platform support one can use this snippet:



          using System.IO;

          // Your input string.
          string baseDir = AppDomain.CurrentDomain.BaseDirectory;

          // Get the absolut path from it (in case ones input is a relative path).
          string fullPath = Path.GetFullPath(baseDir);

          // Check for ending slashes, remove them (if any)
          // and add a cross platform slash at the end.
          string result = fullPath
          .TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)
          + Path.DirectorySeparatorChar;


          As a method:



          private static string GetFullPathWithEndingSlashes(string input)
          {
          string fullPath = Path.GetFullPath(input);

          return fullPath
          .TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)
          + Path.DirectorySeparatorChar;
          }


          Or as an extension method:



          public static string GetFullPathWithEndingSlashes(this string input)
          {
          return Path.GetFullPath(input)
          .TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)
          + Path.DirectorySeparatorChar;
          }





          share|improve this answer































            3














            I often use



            path = Path.Combine(path, "x");
            path = path.Substring(0, path.Length - 1);


            Or, if I needed this more than once or twice in the same project, I'd probably use a helper function like this:



            string EnsureTerminatingDirectorySeparator(string path)
            {
            if (path == null)
            throw new ArgumentNullException("path");

            int length = path.Length;
            if (length == 0)
            return "." + Path.DirectorySeparatorChar;

            char lastChar = path[length - 1];
            if (lastChar == Path.DirectorySeparatorChar || lastChar == Path.AltDirectorySeparatorChar)
            return path;

            int lastSep = path.LastIndexOfAny(new char { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar });
            if (lastSep >= 0)
            return path + path[lastSep];
            else
            return path + Path.DirectorySeparatorChar;
            }





            share|improve this answer


























              Your Answer






              StackExchange.ifUsing("editor", function () {
              StackExchange.using("externalEditor", function () {
              StackExchange.using("snippets", function () {
              StackExchange.snippets.init();
              });
              });
              }, "code-snippets");

              StackExchange.ready(function() {
              var channelOptions = {
              tags: "".split(" "),
              id: "1"
              };
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function() {
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled) {
              StackExchange.using("snippets", function() {
              createEditor();
              });
              }
              else {
              createEditor();
              }
              });

              function createEditor() {
              StackExchange.prepareEditor({
              heartbeatType: 'answer',
              autoActivateHeartbeat: false,
              convertImagesToLinks: true,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              imageUploader: {
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              },
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              });


              }
              });














              draft saved

              draft discarded


















              StackExchange.ready(
              function () {
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f20405965%2fhow-to-ensure-there-is-trailing-directory-separator-in-paths%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              4 Answers
              4






              active

              oldest

              votes








              4 Answers
              4






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              37














              It's like that, just keep your hack.



              In plain Win32 there is an helper function PathAddBackslash for that. Just be consistent with directory separator: check Path.DirectorySeparatorChar and Path.AltDirectorySeparatorChar instead of hard-code .



              Something like this (please note there is not a serious error checking):



              string PathAddBackslash(string path)
              {
              // They're always one character but EndsWith is shorter than
              // array style access to last path character. Change this
              // if performance are a (measured) issue.
              string separator1 = Path.DirectorySeparatorChar.ToString();
              string separator2 = Path.AltDirectorySeparatorChar.ToString();

              // Trailing white spaces are always ignored but folders may have
              // leading spaces. It's unusual but it may happen. If it's an issue
              // then just replace TrimEnd() with Trim(). Tnx Paul Groke to point this out.
              path = path.TrimEnd();

              // Argument is always a directory name then if there is one
              // of allowed separators then I have nothing to do.
              if (path.EndsWith(separator1) || path.EndsWith(separator2))
              return path;

              // If there is the "alt" separator then I add a trailing one.
              // Note that URI format (file://drive:pathfilename.ext) is
              // not supported in most .NET I/O functions then we don't support it
              // here too. If you have to then simply revert this check:
              // if (path.Contains(separator1))
              // return path + separator1;
              //
              // return path + separator2;
              if (path.Contains(separator2))
              return path + separator2;

              // If there is not an "alt" separator I add a "normal" one.
              // It means path may be with normal one or it has not any separator
              // (for example if it's just a directory name). In this case I
              // default to normal as users expect.
              return path + separator1;
              }


              Why so much code? Primary because if user enter /windows/system32 you don't want to get /windows/system32 but /windows/system32/, devil is in the details...



              To put everything together in a nicer self-explicative form:



              string PathAddBackslash(string path)
              {
              if (path == null)
              throw new ArgumentNullException(nameof(path));

              path = path.TrimEnd();

              if (PathEndsWithDirectorySeparator())
              return path;

              return path + GetDirectorySeparatorUsedInPath();

              bool PathEndsWithDirectorySeparator()
              {
              if (path.Length == 0)
              return false;

              char lastChar = path[path.Length - 1];
              return lastChar == Path.DirectorySeparatorChar
              || lastChar == Path.AltDirectorySeparatorChar;
              }

              char GetDirectorySeparatorUsedInPath()
              {
              if (path.Contains(Path.AltDirectorySeparatorChar))
              return Path.AltDirectorySeparatorChar;

              return Path.DirectorySeparatorChar;
              }
              }


              URI format file:// is not handled even if it may seem so. The right thing is again to do what the other .NET I/O functions do: do not handle this format (and possibly throw an exception).



              As alternative you're always able to import Win32 function:



              [DllImport("shlwapi.dll", 
              EntryPoint = "PathAddBackslashW",
              SetLastError = True,
              CharSet = CharSet.Unicode)]
              static extern IntPtr PathAddBackslash(
              [MarshalAs(UnmanagedType.LPTStr)]StringBuilder lpszPath);





              share|improve this answer


























              • I'm not sure I would use the alternative. Although its interesting, a developer would not be sure about what the code is doing.

                – pitermarx
                Dec 17 '13 at 17:12








              • 4





                @pitermarx actually we're not sure even about what FileCopy does! A system function IMO is always a good choice, at least it'll handle any change for you (and it'll always respect its contract: to add a trailing backslash). Well not always they're perfect solution, of course...

                – Adriano Repetti
                Dec 17 '13 at 17:34













              • Should EndsWidth be EndsWith ..also, had to remove const from your sample..

                – Bostwick
                Jul 8 '14 at 14:10











              • @Bostwick you're right. Fixed, thank you!

                – Adriano Repetti
                Jul 8 '14 at 14:23











              • @AdrianoRepetti: Windows allows leading spaces in file/directory names, so the Trim() call does no good. (It probably also allows trailing spaces, but at least cmd.exe doesn't seem to support them, and I haven't done further testing, so I cannot be sure.) Personally I'd just completely remove the Trim call. After all it's not the functions responsibility to "fix" broken paths. Also I would change the "which one to add" logic to just replicate the last seperator in the string (I've seen file:// paths that use backslaches in the rest of the string).

                – Paul Groke
                Jan 7 '16 at 16:14
















              37














              It's like that, just keep your hack.



              In plain Win32 there is an helper function PathAddBackslash for that. Just be consistent with directory separator: check Path.DirectorySeparatorChar and Path.AltDirectorySeparatorChar instead of hard-code .



              Something like this (please note there is not a serious error checking):



              string PathAddBackslash(string path)
              {
              // They're always one character but EndsWith is shorter than
              // array style access to last path character. Change this
              // if performance are a (measured) issue.
              string separator1 = Path.DirectorySeparatorChar.ToString();
              string separator2 = Path.AltDirectorySeparatorChar.ToString();

              // Trailing white spaces are always ignored but folders may have
              // leading spaces. It's unusual but it may happen. If it's an issue
              // then just replace TrimEnd() with Trim(). Tnx Paul Groke to point this out.
              path = path.TrimEnd();

              // Argument is always a directory name then if there is one
              // of allowed separators then I have nothing to do.
              if (path.EndsWith(separator1) || path.EndsWith(separator2))
              return path;

              // If there is the "alt" separator then I add a trailing one.
              // Note that URI format (file://drive:pathfilename.ext) is
              // not supported in most .NET I/O functions then we don't support it
              // here too. If you have to then simply revert this check:
              // if (path.Contains(separator1))
              // return path + separator1;
              //
              // return path + separator2;
              if (path.Contains(separator2))
              return path + separator2;

              // If there is not an "alt" separator I add a "normal" one.
              // It means path may be with normal one or it has not any separator
              // (for example if it's just a directory name). In this case I
              // default to normal as users expect.
              return path + separator1;
              }


              Why so much code? Primary because if user enter /windows/system32 you don't want to get /windows/system32 but /windows/system32/, devil is in the details...



              To put everything together in a nicer self-explicative form:



              string PathAddBackslash(string path)
              {
              if (path == null)
              throw new ArgumentNullException(nameof(path));

              path = path.TrimEnd();

              if (PathEndsWithDirectorySeparator())
              return path;

              return path + GetDirectorySeparatorUsedInPath();

              bool PathEndsWithDirectorySeparator()
              {
              if (path.Length == 0)
              return false;

              char lastChar = path[path.Length - 1];
              return lastChar == Path.DirectorySeparatorChar
              || lastChar == Path.AltDirectorySeparatorChar;
              }

              char GetDirectorySeparatorUsedInPath()
              {
              if (path.Contains(Path.AltDirectorySeparatorChar))
              return Path.AltDirectorySeparatorChar;

              return Path.DirectorySeparatorChar;
              }
              }


              URI format file:// is not handled even if it may seem so. The right thing is again to do what the other .NET I/O functions do: do not handle this format (and possibly throw an exception).



              As alternative you're always able to import Win32 function:



              [DllImport("shlwapi.dll", 
              EntryPoint = "PathAddBackslashW",
              SetLastError = True,
              CharSet = CharSet.Unicode)]
              static extern IntPtr PathAddBackslash(
              [MarshalAs(UnmanagedType.LPTStr)]StringBuilder lpszPath);





              share|improve this answer


























              • I'm not sure I would use the alternative. Although its interesting, a developer would not be sure about what the code is doing.

                – pitermarx
                Dec 17 '13 at 17:12








              • 4





                @pitermarx actually we're not sure even about what FileCopy does! A system function IMO is always a good choice, at least it'll handle any change for you (and it'll always respect its contract: to add a trailing backslash). Well not always they're perfect solution, of course...

                – Adriano Repetti
                Dec 17 '13 at 17:34













              • Should EndsWidth be EndsWith ..also, had to remove const from your sample..

                – Bostwick
                Jul 8 '14 at 14:10











              • @Bostwick you're right. Fixed, thank you!

                – Adriano Repetti
                Jul 8 '14 at 14:23











              • @AdrianoRepetti: Windows allows leading spaces in file/directory names, so the Trim() call does no good. (It probably also allows trailing spaces, but at least cmd.exe doesn't seem to support them, and I haven't done further testing, so I cannot be sure.) Personally I'd just completely remove the Trim call. After all it's not the functions responsibility to "fix" broken paths. Also I would change the "which one to add" logic to just replicate the last seperator in the string (I've seen file:// paths that use backslaches in the rest of the string).

                – Paul Groke
                Jan 7 '16 at 16:14














              37












              37








              37







              It's like that, just keep your hack.



              In plain Win32 there is an helper function PathAddBackslash for that. Just be consistent with directory separator: check Path.DirectorySeparatorChar and Path.AltDirectorySeparatorChar instead of hard-code .



              Something like this (please note there is not a serious error checking):



              string PathAddBackslash(string path)
              {
              // They're always one character but EndsWith is shorter than
              // array style access to last path character. Change this
              // if performance are a (measured) issue.
              string separator1 = Path.DirectorySeparatorChar.ToString();
              string separator2 = Path.AltDirectorySeparatorChar.ToString();

              // Trailing white spaces are always ignored but folders may have
              // leading spaces. It's unusual but it may happen. If it's an issue
              // then just replace TrimEnd() with Trim(). Tnx Paul Groke to point this out.
              path = path.TrimEnd();

              // Argument is always a directory name then if there is one
              // of allowed separators then I have nothing to do.
              if (path.EndsWith(separator1) || path.EndsWith(separator2))
              return path;

              // If there is the "alt" separator then I add a trailing one.
              // Note that URI format (file://drive:pathfilename.ext) is
              // not supported in most .NET I/O functions then we don't support it
              // here too. If you have to then simply revert this check:
              // if (path.Contains(separator1))
              // return path + separator1;
              //
              // return path + separator2;
              if (path.Contains(separator2))
              return path + separator2;

              // If there is not an "alt" separator I add a "normal" one.
              // It means path may be with normal one or it has not any separator
              // (for example if it's just a directory name). In this case I
              // default to normal as users expect.
              return path + separator1;
              }


              Why so much code? Primary because if user enter /windows/system32 you don't want to get /windows/system32 but /windows/system32/, devil is in the details...



              To put everything together in a nicer self-explicative form:



              string PathAddBackslash(string path)
              {
              if (path == null)
              throw new ArgumentNullException(nameof(path));

              path = path.TrimEnd();

              if (PathEndsWithDirectorySeparator())
              return path;

              return path + GetDirectorySeparatorUsedInPath();

              bool PathEndsWithDirectorySeparator()
              {
              if (path.Length == 0)
              return false;

              char lastChar = path[path.Length - 1];
              return lastChar == Path.DirectorySeparatorChar
              || lastChar == Path.AltDirectorySeparatorChar;
              }

              char GetDirectorySeparatorUsedInPath()
              {
              if (path.Contains(Path.AltDirectorySeparatorChar))
              return Path.AltDirectorySeparatorChar;

              return Path.DirectorySeparatorChar;
              }
              }


              URI format file:// is not handled even if it may seem so. The right thing is again to do what the other .NET I/O functions do: do not handle this format (and possibly throw an exception).



              As alternative you're always able to import Win32 function:



              [DllImport("shlwapi.dll", 
              EntryPoint = "PathAddBackslashW",
              SetLastError = True,
              CharSet = CharSet.Unicode)]
              static extern IntPtr PathAddBackslash(
              [MarshalAs(UnmanagedType.LPTStr)]StringBuilder lpszPath);





              share|improve this answer















              It's like that, just keep your hack.



              In plain Win32 there is an helper function PathAddBackslash for that. Just be consistent with directory separator: check Path.DirectorySeparatorChar and Path.AltDirectorySeparatorChar instead of hard-code .



              Something like this (please note there is not a serious error checking):



              string PathAddBackslash(string path)
              {
              // They're always one character but EndsWith is shorter than
              // array style access to last path character. Change this
              // if performance are a (measured) issue.
              string separator1 = Path.DirectorySeparatorChar.ToString();
              string separator2 = Path.AltDirectorySeparatorChar.ToString();

              // Trailing white spaces are always ignored but folders may have
              // leading spaces. It's unusual but it may happen. If it's an issue
              // then just replace TrimEnd() with Trim(). Tnx Paul Groke to point this out.
              path = path.TrimEnd();

              // Argument is always a directory name then if there is one
              // of allowed separators then I have nothing to do.
              if (path.EndsWith(separator1) || path.EndsWith(separator2))
              return path;

              // If there is the "alt" separator then I add a trailing one.
              // Note that URI format (file://drive:pathfilename.ext) is
              // not supported in most .NET I/O functions then we don't support it
              // here too. If you have to then simply revert this check:
              // if (path.Contains(separator1))
              // return path + separator1;
              //
              // return path + separator2;
              if (path.Contains(separator2))
              return path + separator2;

              // If there is not an "alt" separator I add a "normal" one.
              // It means path may be with normal one or it has not any separator
              // (for example if it's just a directory name). In this case I
              // default to normal as users expect.
              return path + separator1;
              }


              Why so much code? Primary because if user enter /windows/system32 you don't want to get /windows/system32 but /windows/system32/, devil is in the details...



              To put everything together in a nicer self-explicative form:



              string PathAddBackslash(string path)
              {
              if (path == null)
              throw new ArgumentNullException(nameof(path));

              path = path.TrimEnd();

              if (PathEndsWithDirectorySeparator())
              return path;

              return path + GetDirectorySeparatorUsedInPath();

              bool PathEndsWithDirectorySeparator()
              {
              if (path.Length == 0)
              return false;

              char lastChar = path[path.Length - 1];
              return lastChar == Path.DirectorySeparatorChar
              || lastChar == Path.AltDirectorySeparatorChar;
              }

              char GetDirectorySeparatorUsedInPath()
              {
              if (path.Contains(Path.AltDirectorySeparatorChar))
              return Path.AltDirectorySeparatorChar;

              return Path.DirectorySeparatorChar;
              }
              }


              URI format file:// is not handled even if it may seem so. The right thing is again to do what the other .NET I/O functions do: do not handle this format (and possibly throw an exception).



              As alternative you're always able to import Win32 function:



              [DllImport("shlwapi.dll", 
              EntryPoint = "PathAddBackslashW",
              SetLastError = True,
              CharSet = CharSet.Unicode)]
              static extern IntPtr PathAddBackslash(
              [MarshalAs(UnmanagedType.LPTStr)]StringBuilder lpszPath);






              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Aug 6 '18 at 8:55

























              answered Dec 5 '13 at 16:59









              Adriano RepettiAdriano Repetti

              51.2k14109162




              51.2k14109162













              • I'm not sure I would use the alternative. Although its interesting, a developer would not be sure about what the code is doing.

                – pitermarx
                Dec 17 '13 at 17:12








              • 4





                @pitermarx actually we're not sure even about what FileCopy does! A system function IMO is always a good choice, at least it'll handle any change for you (and it'll always respect its contract: to add a trailing backslash). Well not always they're perfect solution, of course...

                – Adriano Repetti
                Dec 17 '13 at 17:34













              • Should EndsWidth be EndsWith ..also, had to remove const from your sample..

                – Bostwick
                Jul 8 '14 at 14:10











              • @Bostwick you're right. Fixed, thank you!

                – Adriano Repetti
                Jul 8 '14 at 14:23











              • @AdrianoRepetti: Windows allows leading spaces in file/directory names, so the Trim() call does no good. (It probably also allows trailing spaces, but at least cmd.exe doesn't seem to support them, and I haven't done further testing, so I cannot be sure.) Personally I'd just completely remove the Trim call. After all it's not the functions responsibility to "fix" broken paths. Also I would change the "which one to add" logic to just replicate the last seperator in the string (I've seen file:// paths that use backslaches in the rest of the string).

                – Paul Groke
                Jan 7 '16 at 16:14



















              • I'm not sure I would use the alternative. Although its interesting, a developer would not be sure about what the code is doing.

                – pitermarx
                Dec 17 '13 at 17:12








              • 4





                @pitermarx actually we're not sure even about what FileCopy does! A system function IMO is always a good choice, at least it'll handle any change for you (and it'll always respect its contract: to add a trailing backslash). Well not always they're perfect solution, of course...

                – Adriano Repetti
                Dec 17 '13 at 17:34













              • Should EndsWidth be EndsWith ..also, had to remove const from your sample..

                – Bostwick
                Jul 8 '14 at 14:10











              • @Bostwick you're right. Fixed, thank you!

                – Adriano Repetti
                Jul 8 '14 at 14:23











              • @AdrianoRepetti: Windows allows leading spaces in file/directory names, so the Trim() call does no good. (It probably also allows trailing spaces, but at least cmd.exe doesn't seem to support them, and I haven't done further testing, so I cannot be sure.) Personally I'd just completely remove the Trim call. After all it's not the functions responsibility to "fix" broken paths. Also I would change the "which one to add" logic to just replicate the last seperator in the string (I've seen file:// paths that use backslaches in the rest of the string).

                – Paul Groke
                Jan 7 '16 at 16:14

















              I'm not sure I would use the alternative. Although its interesting, a developer would not be sure about what the code is doing.

              – pitermarx
              Dec 17 '13 at 17:12







              I'm not sure I would use the alternative. Although its interesting, a developer would not be sure about what the code is doing.

              – pitermarx
              Dec 17 '13 at 17:12






              4




              4





              @pitermarx actually we're not sure even about what FileCopy does! A system function IMO is always a good choice, at least it'll handle any change for you (and it'll always respect its contract: to add a trailing backslash). Well not always they're perfect solution, of course...

              – Adriano Repetti
              Dec 17 '13 at 17:34







              @pitermarx actually we're not sure even about what FileCopy does! A system function IMO is always a good choice, at least it'll handle any change for you (and it'll always respect its contract: to add a trailing backslash). Well not always they're perfect solution, of course...

              – Adriano Repetti
              Dec 17 '13 at 17:34















              Should EndsWidth be EndsWith ..also, had to remove const from your sample..

              – Bostwick
              Jul 8 '14 at 14:10





              Should EndsWidth be EndsWith ..also, had to remove const from your sample..

              – Bostwick
              Jul 8 '14 at 14:10













              @Bostwick you're right. Fixed, thank you!

              – Adriano Repetti
              Jul 8 '14 at 14:23





              @Bostwick you're right. Fixed, thank you!

              – Adriano Repetti
              Jul 8 '14 at 14:23













              @AdrianoRepetti: Windows allows leading spaces in file/directory names, so the Trim() call does no good. (It probably also allows trailing spaces, but at least cmd.exe doesn't seem to support them, and I haven't done further testing, so I cannot be sure.) Personally I'd just completely remove the Trim call. After all it's not the functions responsibility to "fix" broken paths. Also I would change the "which one to add" logic to just replicate the last seperator in the string (I've seen file:// paths that use backslaches in the rest of the string).

              – Paul Groke
              Jan 7 '16 at 16:14





              @AdrianoRepetti: Windows allows leading spaces in file/directory names, so the Trim() call does no good. (It probably also allows trailing spaces, but at least cmd.exe doesn't seem to support them, and I haven't done further testing, so I cannot be sure.) Personally I'd just completely remove the Trim call. After all it's not the functions responsibility to "fix" broken paths. Also I would change the "which one to add" logic to just replicate the last seperator in the string (I've seen file:// paths that use backslaches in the rest of the string).

              – Paul Groke
              Jan 7 '16 at 16:14













              51














              You can easily ensure the behaviour you desire by using TrimEnd:



              var baseDir = AppDomain.CurrentDomain.BaseDirectory.TrimEnd('\') + "\";


              To be optimally efficient (by avoiding extra allocations), check that the string doesn't end with a before making changes, since you won't always need to:



              var baseDir = AppDomain.CurrentDomain.BaseDirectory;
              if (!baseDir.EndsWith("\"))
              {
              baseDir += "\";
              }





              share|improve this answer





















              • 21





                To make it cross platform you could replace the \ with Path.DirectorySeparatorChar

                – Rots
                Feb 9 '14 at 22:49








              • 5





                @Rots: The TrimEnd call should include AltDirectorySeparatorChar as well

                – Paul Groke
                Jan 7 '16 at 16:06
















              51














              You can easily ensure the behaviour you desire by using TrimEnd:



              var baseDir = AppDomain.CurrentDomain.BaseDirectory.TrimEnd('\') + "\";


              To be optimally efficient (by avoiding extra allocations), check that the string doesn't end with a before making changes, since you won't always need to:



              var baseDir = AppDomain.CurrentDomain.BaseDirectory;
              if (!baseDir.EndsWith("\"))
              {
              baseDir += "\";
              }





              share|improve this answer





















              • 21





                To make it cross platform you could replace the \ with Path.DirectorySeparatorChar

                – Rots
                Feb 9 '14 at 22:49








              • 5





                @Rots: The TrimEnd call should include AltDirectorySeparatorChar as well

                – Paul Groke
                Jan 7 '16 at 16:06














              51












              51








              51







              You can easily ensure the behaviour you desire by using TrimEnd:



              var baseDir = AppDomain.CurrentDomain.BaseDirectory.TrimEnd('\') + "\";


              To be optimally efficient (by avoiding extra allocations), check that the string doesn't end with a before making changes, since you won't always need to:



              var baseDir = AppDomain.CurrentDomain.BaseDirectory;
              if (!baseDir.EndsWith("\"))
              {
              baseDir += "\";
              }





              share|improve this answer















              You can easily ensure the behaviour you desire by using TrimEnd:



              var baseDir = AppDomain.CurrentDomain.BaseDirectory.TrimEnd('\') + "\";


              To be optimally efficient (by avoiding extra allocations), check that the string doesn't end with a before making changes, since you won't always need to:



              var baseDir = AppDomain.CurrentDomain.BaseDirectory;
              if (!baseDir.EndsWith("\"))
              {
              baseDir += "\";
              }






              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Jul 6 '16 at 18:13

























              answered Dec 5 '13 at 17:35









              HaneyHaney

              21.6k64159




              21.6k64159








              • 21





                To make it cross platform you could replace the \ with Path.DirectorySeparatorChar

                – Rots
                Feb 9 '14 at 22:49








              • 5





                @Rots: The TrimEnd call should include AltDirectorySeparatorChar as well

                – Paul Groke
                Jan 7 '16 at 16:06














              • 21





                To make it cross platform you could replace the \ with Path.DirectorySeparatorChar

                – Rots
                Feb 9 '14 at 22:49








              • 5





                @Rots: The TrimEnd call should include AltDirectorySeparatorChar as well

                – Paul Groke
                Jan 7 '16 at 16:06








              21




              21





              To make it cross platform you could replace the \ with Path.DirectorySeparatorChar

              – Rots
              Feb 9 '14 at 22:49







              To make it cross platform you could replace the \ with Path.DirectorySeparatorChar

              – Rots
              Feb 9 '14 at 22:49






              5




              5





              @Rots: The TrimEnd call should include AltDirectorySeparatorChar as well

              – Paul Groke
              Jan 7 '16 at 16:06





              @Rots: The TrimEnd call should include AltDirectorySeparatorChar as well

              – Paul Groke
              Jan 7 '16 at 16:06











              4














              In order to get cross platform support one can use this snippet:



              using System.IO;

              // Your input string.
              string baseDir = AppDomain.CurrentDomain.BaseDirectory;

              // Get the absolut path from it (in case ones input is a relative path).
              string fullPath = Path.GetFullPath(baseDir);

              // Check for ending slashes, remove them (if any)
              // and add a cross platform slash at the end.
              string result = fullPath
              .TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)
              + Path.DirectorySeparatorChar;


              As a method:



              private static string GetFullPathWithEndingSlashes(string input)
              {
              string fullPath = Path.GetFullPath(input);

              return fullPath
              .TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)
              + Path.DirectorySeparatorChar;
              }


              Or as an extension method:



              public static string GetFullPathWithEndingSlashes(this string input)
              {
              return Path.GetFullPath(input)
              .TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)
              + Path.DirectorySeparatorChar;
              }





              share|improve this answer




























                4














                In order to get cross platform support one can use this snippet:



                using System.IO;

                // Your input string.
                string baseDir = AppDomain.CurrentDomain.BaseDirectory;

                // Get the absolut path from it (in case ones input is a relative path).
                string fullPath = Path.GetFullPath(baseDir);

                // Check for ending slashes, remove them (if any)
                // and add a cross platform slash at the end.
                string result = fullPath
                .TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)
                + Path.DirectorySeparatorChar;


                As a method:



                private static string GetFullPathWithEndingSlashes(string input)
                {
                string fullPath = Path.GetFullPath(input);

                return fullPath
                .TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)
                + Path.DirectorySeparatorChar;
                }


                Or as an extension method:



                public static string GetFullPathWithEndingSlashes(this string input)
                {
                return Path.GetFullPath(input)
                .TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)
                + Path.DirectorySeparatorChar;
                }





                share|improve this answer


























                  4












                  4








                  4







                  In order to get cross platform support one can use this snippet:



                  using System.IO;

                  // Your input string.
                  string baseDir = AppDomain.CurrentDomain.BaseDirectory;

                  // Get the absolut path from it (in case ones input is a relative path).
                  string fullPath = Path.GetFullPath(baseDir);

                  // Check for ending slashes, remove them (if any)
                  // and add a cross platform slash at the end.
                  string result = fullPath
                  .TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)
                  + Path.DirectorySeparatorChar;


                  As a method:



                  private static string GetFullPathWithEndingSlashes(string input)
                  {
                  string fullPath = Path.GetFullPath(input);

                  return fullPath
                  .TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)
                  + Path.DirectorySeparatorChar;
                  }


                  Or as an extension method:



                  public static string GetFullPathWithEndingSlashes(this string input)
                  {
                  return Path.GetFullPath(input)
                  .TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)
                  + Path.DirectorySeparatorChar;
                  }





                  share|improve this answer













                  In order to get cross platform support one can use this snippet:



                  using System.IO;

                  // Your input string.
                  string baseDir = AppDomain.CurrentDomain.BaseDirectory;

                  // Get the absolut path from it (in case ones input is a relative path).
                  string fullPath = Path.GetFullPath(baseDir);

                  // Check for ending slashes, remove them (if any)
                  // and add a cross platform slash at the end.
                  string result = fullPath
                  .TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)
                  + Path.DirectorySeparatorChar;


                  As a method:



                  private static string GetFullPathWithEndingSlashes(string input)
                  {
                  string fullPath = Path.GetFullPath(input);

                  return fullPath
                  .TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)
                  + Path.DirectorySeparatorChar;
                  }


                  Or as an extension method:



                  public static string GetFullPathWithEndingSlashes(this string input)
                  {
                  return Path.GetFullPath(input)
                  .TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)
                  + Path.DirectorySeparatorChar;
                  }






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Sep 8 '17 at 9:34









                  BaccataBaccata

                  1771311




                  1771311























                      3














                      I often use



                      path = Path.Combine(path, "x");
                      path = path.Substring(0, path.Length - 1);


                      Or, if I needed this more than once or twice in the same project, I'd probably use a helper function like this:



                      string EnsureTerminatingDirectorySeparator(string path)
                      {
                      if (path == null)
                      throw new ArgumentNullException("path");

                      int length = path.Length;
                      if (length == 0)
                      return "." + Path.DirectorySeparatorChar;

                      char lastChar = path[length - 1];
                      if (lastChar == Path.DirectorySeparatorChar || lastChar == Path.AltDirectorySeparatorChar)
                      return path;

                      int lastSep = path.LastIndexOfAny(new char { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar });
                      if (lastSep >= 0)
                      return path + path[lastSep];
                      else
                      return path + Path.DirectorySeparatorChar;
                      }





                      share|improve this answer






























                        3














                        I often use



                        path = Path.Combine(path, "x");
                        path = path.Substring(0, path.Length - 1);


                        Or, if I needed this more than once or twice in the same project, I'd probably use a helper function like this:



                        string EnsureTerminatingDirectorySeparator(string path)
                        {
                        if (path == null)
                        throw new ArgumentNullException("path");

                        int length = path.Length;
                        if (length == 0)
                        return "." + Path.DirectorySeparatorChar;

                        char lastChar = path[length - 1];
                        if (lastChar == Path.DirectorySeparatorChar || lastChar == Path.AltDirectorySeparatorChar)
                        return path;

                        int lastSep = path.LastIndexOfAny(new char { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar });
                        if (lastSep >= 0)
                        return path + path[lastSep];
                        else
                        return path + Path.DirectorySeparatorChar;
                        }





                        share|improve this answer




























                          3












                          3








                          3







                          I often use



                          path = Path.Combine(path, "x");
                          path = path.Substring(0, path.Length - 1);


                          Or, if I needed this more than once or twice in the same project, I'd probably use a helper function like this:



                          string EnsureTerminatingDirectorySeparator(string path)
                          {
                          if (path == null)
                          throw new ArgumentNullException("path");

                          int length = path.Length;
                          if (length == 0)
                          return "." + Path.DirectorySeparatorChar;

                          char lastChar = path[length - 1];
                          if (lastChar == Path.DirectorySeparatorChar || lastChar == Path.AltDirectorySeparatorChar)
                          return path;

                          int lastSep = path.LastIndexOfAny(new char { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar });
                          if (lastSep >= 0)
                          return path + path[lastSep];
                          else
                          return path + Path.DirectorySeparatorChar;
                          }





                          share|improve this answer















                          I often use



                          path = Path.Combine(path, "x");
                          path = path.Substring(0, path.Length - 1);


                          Or, if I needed this more than once or twice in the same project, I'd probably use a helper function like this:



                          string EnsureTerminatingDirectorySeparator(string path)
                          {
                          if (path == null)
                          throw new ArgumentNullException("path");

                          int length = path.Length;
                          if (length == 0)
                          return "." + Path.DirectorySeparatorChar;

                          char lastChar = path[length - 1];
                          if (lastChar == Path.DirectorySeparatorChar || lastChar == Path.AltDirectorySeparatorChar)
                          return path;

                          int lastSep = path.LastIndexOfAny(new char { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar });
                          if (lastSep >= 0)
                          return path + path[lastSep];
                          else
                          return path + Path.DirectorySeparatorChar;
                          }






                          share|improve this answer














                          share|improve this answer



                          share|improve this answer








                          edited Jan 8 '16 at 2:36

























                          answered Jan 7 '16 at 16:03









                          Paul GrokePaul Groke

                          4,82812328




                          4,82812328






























                              draft saved

                              draft discarded




















































                              Thanks for contributing an answer to Stack Overflow!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f20405965%2fhow-to-ensure-there-is-trailing-directory-separator-in-paths%23new-answer', 'question_page');
                              }
                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              Popular posts from this blog

                              MongoDB - Not Authorized To Execute Command

                              How to fix TextFormField cause rebuild widget in Flutter

                              Npm cannot find a required file even through it is in the searched directory