JnLlnd
JnLlnd

Reputation: 195

Combine absolute path with a relative path with AHK

I'm looking for an AHK function that expand a relative path into an absolute path based on a given base absolute path.

For example:

Base absolute path: C:\Windows\
Relative path: ..\Temp\
Result: C:\temp\

The function could be called like this:

absPath := PathCombine("c:\Windows\", "..\Temp\") ; returns C:\Temp
absPath := PathCombine("c:\Windows\System32\", ".\..\..\Temp\") ; returns C:\Temp
absPath := PathCombine("c:", "\Temp\") ; returns C:\Temp
absPath := PathCombine("c:\Whathever", "C:\Temp") ; returns C:\Temp
absPath := PathCombine("c:", ".\Temp\") ; returns C:\[current folder on c:]\Temp

The function must support multiple relative path . or .. and \ (like ..\..\ or \Temp). It must also keep unchanged a relative path that would already be absolute. Ideally, it would also support the last example above and consider the current folder on the drive c: in something like c: + .\temp.

I found this code here:

PathCombine(dir, file) {
    VarSetCapacity(dest, 260, 1) ; MAX_PATH
    DllCall("Shlwapi.dll\PathCombineA", "UInt", &dest, "UInt", &dir, "UInt", &file)
    Return, dest
}

... but it does not support Unicode (64-bit). I tried to double the capacity for dest but no success. Also, this code was developed under Win XP (2012). I wonder if Shlwapi.dll is still recommended under Win 7+?

There are other tentatives here based on string manipulation but, based on the thread, I'm not sure if this can be as reliable as a DLL call to a Windows function.

OK. Enough said. Could someone help me make Shlwapi.dll work in Unicode or point me to another/newer technique?

Thanks for your help.

Upvotes: 2

Views: 1702

Answers (1)

JnLlnd
JnLlnd

Reputation: 195

Got it! To make a DllCall work, there are two things to look at:

  1. Double the "dest" text variable capacity.
  2. Replace "Shlwapi.dll\PathCombineA" with "Shlwapi.dll\PathCombineW" (or even by "Shlwapi.dll\PathCombine" and let the AHK engine add the "A" or "W" to the function name as required).

If no function can be found by the given name, an A (ANSI) or W (Unicode) suffix is automatically appended based on which version of AutoHotkey is running the script.

(source: http://ahkscript.org/docs/commands/DllCall.htm)

So, the function adapted to both ANSI and Unicode is:

base := A_WinDir . "\System32\"
rel := "..\Media\Tada.wav"
MsgBox, % PathCombine(base, rel)
return

PathCombine(abs, rel) {
    VarSetCapacity(dest, (A_IsUnicode ? 2 : 1) * 260, 1) ; MAX_PATH
    DllCall("Shlwapi.dll\PathCombine", "UInt", &dest, "UInt", &abs, "UInt", &rel)
    Return, dest
}

RTFM, they said... ;-)

Upvotes: 5

Related Questions