Run, % RefinePath("Joe USB3:\Music\Song.mp3"); use drive name (label) instead of letter - useful for USB sticks.Run, % RefinePath("\Documents\Info.txt"); "A_ScriptDrive" effect - start with a backslash to refer to the same drive where the script isRun, % RefinePath("..\..\App.exe"); go 2 levels up relative to the current folder (A_ScriptDir by default) and run an App located there; and more functionalities...

@Chef: Ooops, thanks for report, I updated the code. Try again, it should work fine now. Btw, when you use variable, you have to add it to the variables collection first - see the documentation. See also changes below; res\folder is no longer valid - you have to use backslash at beginning; \res\folder.@evilC:Yes, it returns absolute path (if it is possible to retrieve it). It doesn't tame things like ..\folder\..\folder\..\folder yet. Currently it only supports double dots segments at the beginning of the path like ..\..\..\folder@Coco:Nice

* * *

RefinePath() updated to v1.01

fixed - bugs

improved - the code doesn't use FileExist() any more - that was the wrong approach

changed - to refer to A_ScriptDir, you have to start with backslash. Example: RefinePath("\SubFolder\button.png"). In previous version, that first backslash was optional.

changed - RefinePath.MapDrives() method is not automatically called any more. For details see documentation.

Here is my attempt of this issue. I tried to resolve the multi level dot parts. Dot or nothing in front of path means relative to current working dir. Backslash means scripts directory. I did not test fully here, just wrote it today (got bored and I like to play with strings). Off course you can borrow any structure to enhance your script. This is only a basic idea how it could be done without checking much or all the other integrated enhancements like variables. Performance wise, I think its not fast, but that does not matter to me. And I am doing it in old fashion, as I was absent for years. Feel free to modify and republish any part.

And if someone copies the script, so please don't remove the license header.

#Include resolvePath.ahk#NoEnv; Recommended for performance and compatibility with future AutoHotkey releases.SendMode Input ; Recommended for new scripts due to its superior speed and reliability.SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.

Redistribution and use in source and binary forms, with or withoutmodification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ANDANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIEDWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AREDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FORANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED ANDON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

The views and conclusions contained in the software and documentation are thoseof the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project.*/resolvePath(p_Path){; Set variables to default. r_Path :="" Path :="" PathDrive :=""; Check, if the path is absolute. Otherwise, use base directory. Path :=Trim(p_Path)SplitPath, Path,,,,, PathDrive; Makes it full path if it does not contain a drive.if(PathDrive =""){; Backslash indicates scripts own directory as the base.; No slash or single dot and backslash means current working directory.if(SubStr(Path,1,1)="\"){ Path :=A_ScriptDir. Path}elseif(SubStr(Path,1,2)=".\"){; Dot means current working directory. Strip that dot and build full path. Path :=A_WorkingDir.SubStr(Path,2)}else{; In all other cases it is the current working directory. Path :=A_WorkingDir."\". Path}}; Resolve every part and build step wise. r_Path :=""Loop, Parse, Path, \{SplitPath,A_LoopField, Nameif(Name =".."){; Deletes last part of current path. r_Path :=RegExReplace(r_Path,"DUS)\\[^\\]*\\$","\","",1)}elseif(Name ="."){; Just ignores, as dot means current path. r_Path := r_Path}else{; Regular part will be added with trailing backslash. r_Path .=A_LoopField."\"}}; After all, last trailing slash will be stripped away.if(SubStr(r_Path,0,1)="\"){StringTrimRight, r_Path, r_Path,1}return r_Path}