1

How to convert this directory "c:\~~\engine\..\..\NewFolder" to absolute directory. I have some directory string containing "\..\". I don't know how to convert this to real path.

I'm on C++, Windows.

Paul Sanders
  • 24,133
  • 4
  • 26
  • 48
  • 2
    Start by splitting the string into a vector of strings. Then walk through that vector to build a new vector by using all the rules you would use when reading this as a human. For each subdirectory name, you will either add or remove one element from this new vector. Afterwards, recombine with directory separators. You should end up with `"..\NewFolder". If your question is actually about how to build an _absolute path_, then you will first need to obtain the current directory and prepend that to your relative directory. – paddy Nov 05 '21 at 08:38
  • 3
    Since C++17, you can use [`std::filesystem::canonical`](https://en.cppreference.com/w/cpp/filesystem/canonical) perhaps? – heap underrun Nov 05 '21 at 08:55
  • @paddy That's doing it the hard way! – Paul Sanders Nov 07 '21 at 15:28

1 Answers1

3

There's a function for this called PathCanonicalize() in the Win32 API which you might find useful.

Example usage:

TCHAR outbuf [32767];
PathCanonicalize (outbuf, my_path);

outbuf is as long as it is to handle long path names, which is a user-definable option in Windows 10 and later. You can, of course (and probably should) allocate this on the heap, and you should check the return code (the function returns TRUE if successful).


Update (thank you Cody, for making me seek this out):

Turns out there's a better way to do this. From Windows 8 onwards, you can use PathAllocCanonicalize instead. This has two advantages:

  • you don't need to preallocate the output buffer
  • it can handle path names longer than MAX_PATH

Here's a snippet showing how to use it:

TCHAR *path_out;
HRESULT hr = PathAllocCanonicalize (my_path, PATHCCH_ALLOW_LONG_PATHS, &path_out);
if (hr == S_OK)
{
    // do stuff with path_out
    CoTaskMemFree (path_out);
}

Be sure to call CoInitializeEx somewhere in your code before calling this function, otherwise it will always fail.

Paul Sanders
  • 24,133
  • 4
  • 26
  • 48
  • 1
    Are you sure that the `ShLwApi` functions actually support these long paths names? The SDK documentation suggests they're still limited to `MAX_PATH`, but of course you never know if that can be trusted. – Cody Gray - on strike Nov 07 '21 at 11:57
  • Good question @cody, and I think the answer is that it doesn't. But there's another API call that does - updated my answer. – Paul Sanders Nov 07 '21 at 15:25