0

Is it possible to change the directory in the calling CMD console from inside a C++ program on Windows?

I know there are many ways to change the working directory in the scope of a program, e.g. using _chdir(), but I would like directory change to be preserved when the program has exited.

I would like the behavior to be something like:

C:\Some\Path>MyProgram.exe

C:\Some\Other\Path>

(similar to calling cd inside the console)

One solution could be to wrap the program in a .bat file and then use output of the program as input to the cd command. However, I would like if that was not necessary.

Jakob
  • 11
  • 1
  • 4
  • is [this](https://stackoverflow.com/questions/3485166/change-the-current-working-directory-in-c) what you are looking for? –  Aug 26 '20 at 11:05
  • 1
    I don't think you can change the current directory of a parent process – Alan Birtles Aug 26 '20 at 11:08
  • 1
    @AryanParekh your suggestion will only change the working directory for the called program, not the parent process. – Jakob Aug 26 '20 at 11:18
  • What happens if you use `CALL "MyProgram.exe"`? – lit Aug 26 '20 at 13:11
  • @lit Nothing happens, the working directory for the program is changed, not the working directory inside command prompt – Jakob Aug 27 '20 at 05:46

1 Answers1

0

Well, I have not checked but I'm pretty sure that you could execute SetCurrentDirectoryW in the parent process using CreateRemoteThread.

The SetCurrentDirectory matches the lpStartAddress signature, so it should be possible to just allocate the z-terminated string with new directory path in the parent process memory space and pass this string as lpParameter to CreateRemoteThread. The trick is to get the address of SetCurrentDirectory in the parent process. You should enumerate parent process modules, and calculate the proper offset of the SetCurrentDirectory function using base address of Kernel32.dll.

To allocate the string you should use VirtualAllocEx and write the value to allocated memory with WriteProcessMemory. When the remote thread finished you should release memory with VirtualFreeEx.

Are you sure the batch is not easier solution?

Maximus
  • 10,751
  • 8
  • 47
  • 65
  • I am not sure the cmd.exe window will be aware of the change to display it. You may have to inject a command to update as well. – drescherjm Aug 26 '20 at 12:10
  • I'm pretty sure that cmd.exe doesn't maintain CWD in some trickery way, so it should update prompt after the executable (which did the trick with CD) finishes. – Maximus Aug 26 '20 at 12:42
  • I know the question is tagged as CMD, but seeing as the OP used the confused phrasing "CMD console" when CMD is a shell, not a console or terminal, it should be stressed that this technique doesn't necessarily apply to other shells that one can use in a console or terminal. In particular it doesn't apply to PowerShell, which has a higher-level concept of the working 'directory' in terms of drive providers (e.g. Registry) and -- last I checked -- ignores the process-level filesystem working directory. – Eryk Sun Aug 26 '20 at 19:37
  • In the question there was a note `wrap the program in a .bat file`. That confirms for me cmd.exe nature. But yes, the solution will not work for powershell or bash, because of completely different CD maintaining. – Maximus Aug 27 '20 at 08:29