Welcome Guest Search | Active Topics | Members | Log In | Register

MakeRelativePath() Options · View
Ivo Beltchev
Posted: Sunday, October 21, 2007 8:18:25 AM


Rank: Guest
Groups: Guest

Joined: 9/17/2007
Posts: 11,670
Points: -1,200
Date parsed: 21/10/2007 08:18:25
Date: Sun, 21 Oct 2007 15:18:25 -0700

GetCurrentDirectory + PathRelativePathTo?

"Andrew Chalk" <achalk@magnacartasoftware.com> wrote in message =
news:uvYA9wCFIHA.1168@TK2MSFTNGP02.phx.gbl...
> Is their any built-in Win32 function that returns the relative path to =
a=20
> file given the applications current working directory?
>=20
> Many thanks=20
>=20
>
Andrew Chalk
Posted: Sunday, October 21, 2007 11:48:46 AM


Rank: Guest
Groups: Guest

Joined: 9/17/2007
Posts: 11,670
Points: -1,200
Date parsed: 21/10/2007 11:48:46
Date: Sun, 21 Oct 2007 16:48:46 -0500

Is their any built-in Win32 function that returns the relative path to a
file given the applications current working directory?

Many thanks


J de Boyne Pollard
Posted: Sunday, October 21, 2007 9:47:16 PM


Rank: Guest
Groups: Guest

Joined: 9/17/2007
Posts: 11,670
Points: -1,200
Date parsed: 21/10/2007 21:47:16
Date: Mon, 22 Oct 2007 04:47:16 -0700

VS> Current directory value can be differ in comparison to directory
VS> where the application is executing.

No, it cannot. *By definition*, the directory where the program is
executing is the current directory. You are conflating the current
directory (which was what M. Chalk asked about) with the path to the
executable program image file (which wasn't what M. Chalk asked about).

Ivo Beltchev
Posted: Monday, October 22, 2007 2:27:52 AM


Rank: Guest
Groups: Guest

Joined: 9/17/2007
Posts: 11,670
Points: -1,200
Date parsed: 22/10/2007 02:27:52
Date: Mon, 22 Oct 2007 09:27:52 -0700

My assumption was that "current working directory" in the original =
message is the same as the current directory. It may also mean the =
directory of the executable, in which case GetModuleFileName can be =
used. It may also mean the directory from which the exe is launched, =
which may differ from the current directory or the exe directory. Then =
the OP has to call GetCurrentDirectory as soon as the exe is launched =
before the directory changes.

I'm also assuming that the OP is intelligent enough to know that a =
relative path is not always possible, for example if the two paths are =
on different volumes or servers. Then PathRelativePathTo will return an =
error code and he'll need some workaround, like using a full path =
instead.

Ivo


"Vladimir Scherbina" <v_scherbina@online.mvps.org> wrote in message =
news:ey2wKQIFIHA.3400@TK2MSFTNGP03.phx.gbl...
> Current directory value can be differ in comparison to directory where =
the=20
> application is executing.
>=20
> Usually, applications set the curr dir to their home dir, this often =
can be=20
> seen in MS code. So, correct answer is: one need to analyze the path =
to=20
> executable by invoking GetModuleFileName and obtaining the working =
dir. But,=20
> in order to avoid overhead, it's better to use the first cmd line =
parameter,=20
> which is pointing to the path to executable.
>=20
> "Ivo Beltchev" <ivo _@_ adelphia.net> wrote in message=20
> news:vbudnaAwsqGvTYbanZ2dnUVZ_vKunZ2d@adelphia.com...
> GetCurrentDirectory + PathRelativePathTo?
>=20
> "Andrew Chalk" <achalk@magnacartasoftware.com> wrote in message=20
> news:uvYA9wCFIHA.1168@TK2MSFTNGP02.phx.gbl...
> > Is their any built-in Win32 function that returns the relative path =
to a
> > file given the applications current working directory?
> >
> > Many thanks
> >
> >=20
>=20
>
Andrew Chalk
Posted: Monday, October 22, 2007 4:00:06 AM


Rank: Guest
Groups: Guest

Joined: 9/17/2007
Posts: 11,670
Points: -1,200
Date parsed: 22/10/2007 04:00:06
Date: Mon, 22 Oct 2007 09:00:06 -0500

You have it right. Is there:

char * MakeRelativePath(CurrentDir, AbsolutePathOfTargetDir)

Given our current directory and the full path to a target directory, return
the relative path from the former to the latter.

Thanks

- A

"Tony Proctor" <tony_proctor@aimtechnology_NoMoreSPAM_.com> wrote in message
news:Oc2Qu8IFIHA.3360@TK2MSFTNGP04.phx.gbl...
> Not sure the other respondents have correctly understood your question
> Andrew. Can I just check?
>
> Do you mean you want to take a full path specification and convert it to a
> relative one - relative to some second, arbitrary full directory path?
>
> For instance, c:\Dir1\Dir2\x.y relative to c:\Dir1 is easy (Dir2\x.y, or
> .\Dir2\x.y) but do you want something that can cope with the general case
> (which may be up from the root as well as down from the root, or even on a
> different drive)?
>
> Tony Proctor
>
> "Andrew Chalk" <achalk@magnacartasoftware.com> wrote in message
> news:uvYA9wCFIHA.1168@TK2MSFTNGP02.phx.gbl...
>> Is their any built-in Win32 function that returns the relative path to a
>> file given the applications current working directory?
>>
>> Many thanks
>>
>>
>
>


Andrew Chalk
Posted: Monday, October 22, 2007 4:09:35 AM


Rank: Guest
Groups: Guest

Joined: 9/17/2007
Posts: 11,670
Points: -1,200
Date parsed: 22/10/2007 04:09:35
Date: Mon, 22 Oct 2007 09:09:35 -0500

That looks like it.

Many thanks.

"Ivo Beltchev" <ivo _@_ adelphia.net> wrote in message
news:vbudnaAwsqGvTYbanZ2dnUVZ_vKunZ2d@adelphia.com...
GetCurrentDirectory + PathRelativePathTo?

"Andrew Chalk" <achalk@magnacartasoftware.com> wrote in message
news:uvYA9wCFIHA.1168@TK2MSFTNGP02.phx.gbl...
> Is their any built-in Win32 function that returns the relative path to a
> file given the applications current working directory?
>
> Many thanks
>
>


Tony Proctor
Posted: Monday, October 22, 2007 11:37:31 AM


Rank: Guest
Groups: Guest

Joined: 9/17/2007
Posts: 11,670
Points: -1,200
Date parsed: 22/10/2007 11:37:31
Date: Mon, 22 Oct 2007 10:37:31 +0100

Not sure the other respondents have correctly understood your question
Andrew. Can I just check?

Do you mean you want to take a full path specification and convert it to a
relative one - relative to some second, arbitrary full directory path?

For instance, c:\Dir1\Dir2\x.y relative to c:\Dir1 is easy (Dir2\x.y, or
..\Dir2\x.y) but do you want something that can cope with the general case
(which may be up from the root as well as down from the root, or even on a
different drive)?

Tony Proctor

"Andrew Chalk" <achalk@magnacartasoftware.com> wrote in message
news:uvYA9wCFIHA.1168@TK2MSFTNGP02.phx.gbl...
> Is their any built-in Win32 function that returns the relative path to a
> file given the applications current working directory?
>
> Many thanks
>
>


Vladimir Scherbina
Posted: Monday, October 22, 2007 12:17:42 PM


Rank: Guest
Groups: Guest

Joined: 9/17/2007
Posts: 11,670
Points: -1,200
Date parsed: 22/10/2007 12:17:42
Date: Mon, 22 Oct 2007 10:17:42 +0200

Current directory value can be differ in comparison to directory where the
application is executing.

Usually, applications set the curr dir to their home dir, this often can be
seen in MS code. So, correct answer is: one need to analyze the path to
executable by invoking GetModuleFileName and obtaining the working dir. But,
in order to avoid overhead, it's better to use the first cmd line parameter,
which is pointing to the path to executable.

"Ivo Beltchev" <ivo _@_ adelphia.net> wrote in message
news:vbudnaAwsqGvTYbanZ2dnUVZ_vKunZ2d@adelphia.com...
GetCurrentDirectory + PathRelativePathTo?

"Andrew Chalk" <achalk@magnacartasoftware.com> wrote in message
news:uvYA9wCFIHA.1168@TK2MSFTNGP02.phx.gbl...
> Is their any built-in Win32 function that returns the relative path to a
> file given the applications current working directory?
>
> Many thanks
>
>


Chris Becke
Posted: Monday, October 22, 2007 3:52:11 PM


Rank: Guest
Groups: Guest

Joined: 9/17/2007
Posts: 11,670
Points: -1,200
Date parsed: 22/10/2007 15:52:11
Date: Mon, 22 Oct 2007 13:52:11 +0200


"Vladimir Scherbina" <v_scherbina@online.mvps.org> wrote in message
news:ey2wKQIFIHA.3400@TK2MSFTNGP03.phx.gbl...
> Current directory value can be differ in comparison to directory where the
> application is executing.
>
> Usually, applications set the curr dir to their home dir, this often can
> be seen in MS code. So, correct answer is: one need to analyze the path to
> executable by invoking GetModuleFileName and obtaining the working dir.
> But, in order to avoid overhead, it's better to use the first cmd line
> parameter, which is pointing to the path to executable.

If by the first cmd line parameter you mean the parameter arg[0], arg[0]
does not need to be a cannonical path.

At the core of the Win32 process launch mechanism is an API CreateProcess
that takes two parameters. One is a path to the exe file to launch, the
other is the command line, including the first parameter. As a result,
if/when both parameters are used, arg[0] can be anything at all, not even
slightly related to the exe executed.


Pops
Posted: Monday, October 22, 2007 10:39:15 PM


Rank: Guest
Groups: Guest

Joined: 9/17/2007
Posts: 11,670
Points: -1,200
Date parsed: 22/10/2007 22:39:15
Date: Tue, 23 Oct 2007 02:39:15 -0400

Andrew Chalk wrote:
> Is their any built-in Win32 function that returns the relative path to a
> file given the applications current working directory?
>
> Many thanks

Andrew, I quickly pulled some "path" related c/c++ functions from my
pathlib.cpp library, and put this test demo "Relative.cpp" example.

Hope this helps

--
HLS

// File: V:\local\wc5\common\relative.cpp
// comple: CL relative.cpp" /W3 /GX /MD /D "_AFXDLL"

#include <stdio.h>
#include <afx.h>

typedef struct _SPLITFILEPARTS {
char drive[_MAX_DRIVE]; // WIN32 defines this as 3
char dir[_MAX_DIR]; // WIN32 defines this as 256
char fname[_MAX_FNAME]; // WIN32 defines this as 256
char ext[_MAX_EXT]; // WIN32 defines this as 256
} SPLITFILEPARTS, *PSLITFILEPATHS;

char *ExtractFilePath(char *dest, const char *s,
const BOOL noDrive = FALSE);
char *ExtractFileName(char *dest, const char *s,
const BOOL noExt = FALSE);

BOOL ExtractFileParts(const char *s, SPLITFILEPARTS &sf)
{
ZeroMemory(&sf,sizeof(sf));
if (s == NULL) return FALSE;
_splitpath(s, sf.drive, sf.dir, sf.fname,sf.ext);
return TRUE;
}

char *ExtractFileName(char *dest, const char *s,
const BOOL noExt /* = FALSE */)
{
SPLITFILEPARTS sf;
if (!ExtractFileParts(s,sf)) return dest;
if (noExt) sf.ext[0] = 0;
_makepath(dest,"","",sf.fname,sf.ext);
return dest;
}

CString ExtractFileName(const char *s)
{
CString q;
char *p = q.GetBuffer(MAX_PATH);
ExtractFileName(p, s);
q.ReleaseBuffer();
return q;
}

char *ExtractFilePath(char *dest, const char *s,
const BOOL noDrive /* = FALSE */)
{
SPLITFILEPARTS sf;
if (!ExtractFileParts(s,sf)) return dest;
if (noDrive) sf.drive[0] = 0;
_makepath(dest,sf.drive,sf.dir,"","");
return dest;
}

CString ExtractFilePath(const char *s)
{
CString q;
char *p = q.GetBuffer(MAX_PATH);
ExtractFilePath(p, s);
q.ReleaseBuffer();
return q;
}

CString ExtractFileDrive(const char *s)
{
if (s == NULL) {
return "";
}
CString q;
char *p = q.GetBuffer(MAX_PATH);
SPLITFILEPARTS sf;
ExtractFileParts(s,sf);
_makepath(p, sf.drive,"","","");
q.ReleaseBuffer();
return q;
}


CString ExtractFilePathNoDrive(const char *s)
{
CString q;
char *p = q.GetBuffer(MAX_PATH);
ExtractFilePath(p,s,TRUE);
q.ReleaseBuffer();
return q;
}

void SplitDirs(char *Path, char *Dirs[], int &DirCount)
{

int i = 0;
int j = 0;
while (Path[i]) {
if ((Path[i] == '\\') || (Path[i] == '/')) {
Path[i] = 0;
Dirs[j] = &Path[i+1];
j++;
}
i++;
}
DirCount = j-1;
}

/*
* ExtractRelativePath()
* given BaseName and DestName, return relative path
* if BaseName empty, then relative path is compared against
* current directory
*
*/

CString ExtractRelativePath(const CString &BaseName,
const CString &DestName)
{
char BasePath[MAX_PATH];
char DestPath[MAX_PATH];

strcpy(BasePath,BaseName);
if (BaseName.IsEmpty()) {
GetCurrentDirectory(sizeof(BasePath),BasePath);
}

if (_stricmp(ExtractFileDrive(BasePath),
ExtractFileDrive(DestName))) {
return DestName;
}

strcpy(BasePath,ExtractFilePathNoDrive(BasePath));
strcpy(DestPath,ExtractFilePathNoDrive(DestName));

char *BaseDirs[130];
char *DestDirs[130];
int BaseDirCount = 0;
int DestDirCount = 0;

SplitDirs(BasePath, BaseDirs, BaseDirCount);
SplitDirs(DestPath, DestDirs, DestDirCount);

int i = 0;
while ((i < BaseDirCount) && (i < DestDirCount)) {
if (_stricmp(BaseDirs[i], DestDirs[i]) != 0) break;
i++;
}
CString Result = ".\\";
for (int j = i; j < BaseDirCount; j++)
Result += "..\\"; // Do not localize
for (int k = i; k < DestDirCount; k++) {
Result += CString(DestDirs[k]) + "\\"; // Do not localize
}
Result += ExtractFileName(DestName);
return Result;
}

//--------------------------------------------
// MAIN
//---------------------------------------------
void main(char argc, char *argv[])
{

CString base = ""; // assume current directory
CString dest = "v:\\local\\wc5\\common";
// expecting ".\\common"
printf("rel path: %s\n",ExtractRelativePath(base,dest));

}
Tony Proctor
Posted: Tuesday, October 23, 2007 9:50:02 AM


Rank: Guest
Groups: Guest

Joined: 9/17/2007
Posts: 11,670
Points: -1,200
Date parsed: 23/10/2007 09:50:02
Date: Tue, 23 Oct 2007 08:50:02 +0100

There is a PathRelativePathTo API in shlwapi.dll. I think it's already been
mentioned in this thread now though so I guess you don't need me to point it
:-)

I noticed you cross-posted to a vsnet group too. I'm afraid I don't know
what the non-API .Net equivalent is

Tony Proctor

"Andrew Chalk" <achalk@magnacartasoftware.com> wrote in message
news:eVDq%23PLFIHA.748@TK2MSFTNGP04.phx.gbl...
> You have it right. Is there:
>
> char * MakeRelativePath(CurrentDir, AbsolutePathOfTargetDir)
>
> Given our current directory and the full path to a target directory,
return
> the relative path from the former to the latter.
>
> Thanks
>
> - A
>
> "Tony Proctor" <tony_proctor@aimtechnology_NoMoreSPAM_.com> wrote in
message
> news:Oc2Qu8IFIHA.3360@TK2MSFTNGP04.phx.gbl...
> > Not sure the other respondents have correctly understood your question
> > Andrew. Can I just check?
> >
> > Do you mean you want to take a full path specification and convert it to
a
> > relative one - relative to some second, arbitrary full directory path?
> >
> > For instance, c:\Dir1\Dir2\x.y relative to c:\Dir1 is easy (Dir2\x.y, or
> > .\Dir2\x.y) but do you want something that can cope with the general
case
> > (which may be up from the root as well as down from the root, or even on
a
> > different drive)?
> >
> > Tony Proctor
> >
> > "Andrew Chalk" <achalk@magnacartasoftware.com> wrote in message
> > news:uvYA9wCFIHA.1168@TK2MSFTNGP02.phx.gbl...
> >> Is their any built-in Win32 function that returns the relative path to
a
> >> file given the applications current working directory?
> >>
> >> Many thanks
> >>
> >>
> >
> >
>
>


Andrew Chalk
Posted: Thursday, October 25, 2007 1:04:18 PM


Rank: Guest
Groups: Guest

Joined: 9/17/2007
Posts: 11,670
Points: -1,200
Date parsed: 25/10/2007 13:04:18
Date: Thu, 25 Oct 2007 18:04:18 -0500

Thanks!
"Pops" <dude@nospamnospamnospam.com> wrote in message
news:uqajB%23TFIHA.4544@TK2MSFTNGP06.phx.gbl...
> Andrew Chalk wrote:
>> Is their any built-in Win32 function that returns the relative path to a
>> file given the applications current working directory?
>>
>> Many thanks
>
> Andrew, I quickly pulled some "path" related c/c++ functions from my
> pathlib.cpp library, and put this test demo "Relative.cpp" example.
>
> Hope this helps
>
> --
> HLS
>
> // File: V:\local\wc5\common\relative.cpp
> // comple: CL relative.cpp" /W3 /GX /MD /D "_AFXDLL"
>
> #include <stdio.h>
> #include <afx.h>
>
> typedef struct _SPLITFILEPARTS {
> char drive[_MAX_DRIVE]; // WIN32 defines this as 3
> char dir[_MAX_DIR]; // WIN32 defines this as 256
> char fname[_MAX_FNAME]; // WIN32 defines this as 256
> char ext[_MAX_EXT]; // WIN32 defines this as 256
> } SPLITFILEPARTS, *PSLITFILEPATHS;
>
> char *ExtractFilePath(char *dest, const char *s,
> const BOOL noDrive = FALSE);
> char *ExtractFileName(char *dest, const char *s,
> const BOOL noExt = FALSE);
>
> BOOL ExtractFileParts(const char *s, SPLITFILEPARTS &sf)
> {
> ZeroMemory(&sf,sizeof(sf));
> if (s == NULL) return FALSE;
> _splitpath(s, sf.drive, sf.dir, sf.fname,sf.ext);
> return TRUE;
> }
>
> char *ExtractFileName(char *dest, const char *s,
> const BOOL noExt /* = FALSE */)
> {
> SPLITFILEPARTS sf;
> if (!ExtractFileParts(s,sf)) return dest;
> if (noExt) sf.ext[0] = 0;
> _makepath(dest,"","",sf.fname,sf.ext);
> return dest;
> }
>
> CString ExtractFileName(const char *s)
> {
> CString q;
> char *p = q.GetBuffer(MAX_PATH);
> ExtractFileName(p, s);
> q.ReleaseBuffer();
> return q;
> }
>
> char *ExtractFilePath(char *dest, const char *s,
> const BOOL noDrive /* = FALSE */)
> {
> SPLITFILEPARTS sf;
> if (!ExtractFileParts(s,sf)) return dest;
> if (noDrive) sf.drive[0] = 0;
> _makepath(dest,sf.drive,sf.dir,"","");
> return dest;
> }
>
> CString ExtractFilePath(const char *s)
> {
> CString q;
> char *p = q.GetBuffer(MAX_PATH);
> ExtractFilePath(p, s);
> q.ReleaseBuffer();
> return q;
> }
>
> CString ExtractFileDrive(const char *s)
> {
> if (s == NULL) {
> return "";
> }
> CString q;
> char *p = q.GetBuffer(MAX_PATH);
> SPLITFILEPARTS sf;
> ExtractFileParts(s,sf);
> _makepath(p, sf.drive,"","","");
> q.ReleaseBuffer();
> return q;
> }
>
>
> CString ExtractFilePathNoDrive(const char *s)
> {
> CString q;
> char *p = q.GetBuffer(MAX_PATH);
> ExtractFilePath(p,s,TRUE);
> q.ReleaseBuffer();
> return q;
> }
>
> void SplitDirs(char *Path, char *Dirs[], int &DirCount)
> {
>
> int i = 0;
> int j = 0;
> while (Path[i]) {
> if ((Path[i] == '\\') || (Path[i] == '/')) {
> Path[i] = 0;
> Dirs[j] = &Path[i+1];
> j++;
> }
> i++;
> }
> DirCount = j-1;
> }
>
> /*
> * ExtractRelativePath()
> * given BaseName and DestName, return relative path
> * if BaseName empty, then relative path is compared against
> * current directory
> *
> */
>
> CString ExtractRelativePath(const CString &BaseName,
> const CString &DestName)
> {
> char BasePath[MAX_PATH];
> char DestPath[MAX_PATH];
>
> strcpy(BasePath,BaseName);
> if (BaseName.IsEmpty()) {
> GetCurrentDirectory(sizeof(BasePath),BasePath);
> }
>
> if (_stricmp(ExtractFileDrive(BasePath),
> ExtractFileDrive(DestName))) {
> return DestName;
> }
>
> strcpy(BasePath,ExtractFilePathNoDrive(BasePath));
> strcpy(DestPath,ExtractFilePathNoDrive(DestName));
>
> char *BaseDirs[130];
> char *DestDirs[130];
> int BaseDirCount = 0;
> int DestDirCount = 0;
>
> SplitDirs(BasePath, BaseDirs, BaseDirCount);
> SplitDirs(DestPath, DestDirs, DestDirCount);
>
> int i = 0;
> while ((i < BaseDirCount) && (i < DestDirCount)) {
> if (_stricmp(BaseDirs[i], DestDirs[i]) != 0) break;
> i++;
> }
> CString Result = ".\\";
> for (int j = i; j < BaseDirCount; j++)
> Result += "..\\"; // Do not localize
> for (int k = i; k < DestDirCount; k++) {
> Result += CString(DestDirs[k]) + "\\"; // Do not localize
> }
> Result += ExtractFileName(DestName);
> return Result;
> }
>
> //--------------------------------------------
> // MAIN
> //---------------------------------------------
> void main(char argc, char *argv[])
> {
>
> CString base = ""; // assume current directory
> CString dest = "v:\\local\\wc5\\common";
> // expecting ".\\common"
> printf("rel path: %s\n",ExtractRelativePath(base,dest));
>
> }


Sten Westerback (MVP SDK 2005-6 :)
Posted: Tuesday, April 01, 2008 8:25:01 AM


Rank: Guest
Groups: Guest

Joined: 9/17/2007
Posts: 11,670
Points: -1,200
Date parsed: 01/04/2008 08:25:01
Date: Tue, 01 Apr 2008 08:25:01 GMT


"J de Boyne Pollard" <j.deboynepollard@tesco.net> wrote in message
news:1193053636.438958.87900@k35g2000prh.googlegroups.com...
> VS> Current directory value can be differ in comparison to directory
> VS> where the application is executing.
>
> No, it cannot. *By definition*, the directory where the program is
> executing is the current directory. You are conflating the current
> directory (which was what M. Chalk asked about) with the path to the
> executable program image file (which wasn't what M. Chalk asked about).

Incorrect. The Current Directory CAN BE the folder where the EXE is. But the
CreateProcess call can get specified any folder (for instance that specified
in a shortcut) and the application can use SetCurrentDirectory (or the CRT
wrapper chdir()) to change it at any time...

And btw, "programs", or rather threads in processes, run in Processor(s). :)

- Sten


Users browsing this topic
Guest


Forum Jump
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.

Main Forum RSS : RSS

YAFPro Theme Created by Jaben Cargman (Tiny Gecko)
Powered by Yet Another Forum.net version 1.9.1.1 (NET v2.0) - 9/10/2007
Copyright © 2003-2006 Yet Another Forum.net. All rights reserved.
This page was generated in 0.203 seconds.