changing working directory dynamically in win32 apps

Get answers to all your basic programming questions. No Ogre questions, please!
User avatar
paddy
Greenskin
Posts: 136
Joined: Sun Aug 01, 2004 7:07 pm

changing working directory dynamically in win32 apps

Post by paddy »

I am trying to resolve an ogre app issue ( http://www.ogre3d.org/phpBB2/viewtopic.php?t=7531 ) but I think I need some rudementry C++ help to solve it, so I am asking these specifics here instead:

Basically, my application works nicely out of the directory it is in as the relative source to all files until I try to pass an argument to that application (by dragging a file on top of it) at which time the app no longer knows where the resource.cfg or any other relatively located file.

I can't hard code the paths since it needs to be able to run from different directories when on different computers, so my questions are:



1) How do I find, environment variable wise or such, the path to my application's exe?

2) how do I set the current working directory for the c++ file operations to use a path that I set?


I've searched around online for tutorials on this, but environment variables and working directories seem to match a whole lot of VC++ setup tutorials but not anything I can find on this task.
User avatar
tuan kuranes
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 2653
Joined: Wed Sep 24, 2003 8:07 am
Location: Haute Garonne, France
x 4

Post by tuan kuranes »

It's no C++ bu i'm doing this in ogreaddons mappsplitter and soon in paginglandscape manager to save modified heightmaps on their own directory :

Code: Select all

#include <sys/types.h>
#include <sys/stat.h>

#ifdef _WIN32
#   include <windows.h>
#   include <direct.h>
#   include <io.h>

#   define S_ISDIR(mode) (mode&S_IFDIR)
#   define STRUCT_STAT  struct _stat
#   define CHDIR        _chdir
#   define GETCWD       _getcwd
#   define MKDIR(A)     _mkdir(A)
#   define STAT(A,S)    _stat(A,S)
#else //_LINUX _APPLE

#   include <malloc.h>
#   include <unistd.h>
#   include <sys/param.h>

#   define MAX_PATH MAXPATHLEN
#   define STRUCT_STAT  struct stat
#   define CHDIR        chdir
#   define GETCWD       getcwd
#   define MKDIR(A)     mkdir(A, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)// set mode of directory to drwxr-xr-x.
#   define STAT(A,S)    stat(A,S)
#endif  //_LINUX _APPLE

static char* GetCurrDir()
{
    // GETCWD MALLOCS A BUFFER. REMEMBER TO FREE IT.
    return GETCWD(0,0);;
}

char * ChangeToDir (const char *Dirname)
{
    STRUCT_STAT st;

    if (STAT(Dirname, &st))
        {
        // doen't exist; must create it
        MKDIR (Dirname);
        }
    if (S_ISDIR(st.st_mode) == 0) 
        {
        // it's not a dir, must create a dir
        MKDIR (Dirname);
        }
    char *oldDirname = GetCurrDir ();
    CHDIR(Dirname);
    return oldDirname;
}


void RetablishDir(char *oldDirname)
{
    if (oldDirname != NULL) 
     {
        ChangeToDir (oldDirname);
        // FREE MALLOC'ED GETCWD BUFFER.
        free (oldDirname);
    }
}
then you use it as :

Code: Select all


char *olddir = ChangeToDir (const_cast< char * > (OutDirectory.c_str ()));

//do file operation here on the OutDirectory directory.

RetablishDir (olddir);

don't forget to RetablishDir dir before doing any ogre thing, as ogre would assume it's Current Path hasn't changed.
User avatar
paddy
Greenskin
Posts: 136
Joined: Sun Aug 01, 2004 7:07 pm

Post by paddy »

okay, that works great and I got that to compile, but it appears GetCurrDir() no longer points to my application's path at all as soon as I try to open my application by dropping a file on it.

if I open the program without a file dropped on the app, my current dir is:

C:\Files\...long path...\shipbuilder\Ship Builder\Bin\Release

otherwise it seems to get set to my user home path, of:

C:\Documents and Settings\design


I don't know why, but what is happening is something in windows is (at least from my point of view) messing up the current directory without doing its own 'RetablishDir' or such, so I am trying to force it to restablish the application's directory as the working directory before ogre starts to run.

clarification note: It does appear the working path states intact when I double click a file associated with my ogre program, and it passes the path to the application correctly. This means the only time the working path is getting messed up is when I drop a file onto my application to launch it.
User avatar
Banania
Gremlin
Posts: 150
Joined: Wed Oct 20, 2004 2:35 pm
Location: Paris, France

Post by Banania »

there is a win32 function getmodulefilename() that give you the complete name (with the path) of the current executable. you have to split the path to have only the directory, which can be done with the _split() function IIRC.

this is win32 only of course but it seems to be what you want.
Banania