ATTENTION: You are viewing a page formatted for mobile devices; to view the full web page, click HERE.

Other Software > Developer's Corner

Is it possible to change to working directory within the running programm?

(1/2) > >>

crono:
Hi all,

I have to write a tool which starts and runs on the shell (cmd.exe). It does some logic, takes some input from the user and finishes. Right before it finishes it should change the directory from which it was called. I have no clue if this is even possible. I tried to get the parent process and alter it this way, which results in crashes... 


C:\Home>my_tool.exe 
   ...doing some stuff...
   ...doing some stuff...
   ...doing some stuff...
   ...some user input....
   ...doing some stuff...
   ...finishing...
D:\Data\Documents>


Any Idea how to do this?

f0dder:
What you want to do is change the working directory of the calling program, yes?

I dunno if this is possible to do in any clean way. Thing is, Current Working Directory is managed per-thread, not per-process. So the solution hack I'm thinking of would require finding your parent process (requires undocumented calls, iirc), locating the "correct thread", injecting code in the parent process to SetCurrentDirectory where you want, temporarily redirect the "correct thread" to this injected code, and then back to where it originally was.

Perhaps there's a cleaner way. A less hackish method would probably be running your tool from a batch file, and having the batch file CHDIR to the new folder.

crono:
What you want to do is change the working directory of the calling program, yes?

--- End quote ---
Yes, this is what I would like to do.

I dunno if this is possible to do in any clean way.

--- End quote ---
I fear it is not :(, at least not in a clean way...

Thing is, Current Working Directory is managed per-thread, not per-process. So the solution hack I'm thinking of would require finding your parent process (requires undocumented calls, iirc)

--- End quote ---
I tried something in that way. It is very very very slow  :down:

--- Code: C# ---string pName = Process.GetCurrentProcess().ProcessName.ToString();Process[] pList = Process.GetProcessesByName(pName);// Getting the Process IDPerformanceCounter PID = new PerformanceCounter("Process", "ID Process", pName); // Getting the Parent Process IDPerformanceCounter PPID = new PerformanceCounter("Process", "Creating Process ID", pName); // Getting the PrecessProcess p = Process.GetProcessById(int.Parse(PPID.NextValue().ToString())); //trying to change the Dir... - which results in a Crash...p.StandardInput.WriteLine("CD {0}",path);

A less hackish method would probably be running your tool from a batch file, and having the batch file CHDIR to the new folder.
--- End quote ---
This is a really good Idea and would be perfect if the Directory after finishing would be always the same (it is not), but how can I redirect only the last program Output to the Batchfile instead of all Output. The tool needs some (interactive) Userinput, so I can't capture all of the output...?

Thanks for the input f0dder :)


//edit: Idea:
The Batch have to look like this:

--- Code: C ---call my_tool.exe call my_temp.bat
The my_temp.bat have to be created by my_tool.exe on the fly before finishing... I believe this will work...

--- Code: C ---cd _DIR_

f0dder:
Well, your code to get parent id does look extraordinarily slow - the performance counter API is pretty slow to deal with, especially the first call you make in a program. It'd probably be faster to use toolhelp32 and enumerate the processes until you find your own pid, and then check the th32ParentProcessID member... or use the undocumented NtQueryInformationProcess() function, which is pretty much instantaneous.

But even with the parent process PID, there isn't much you can do, without resorting to the hackhackhack I outlined in the previous post :)

Doing the multiple-batchfile approach is probably the cleanest.

hwtan:
Alternative solution: write to the keyboard buffer.


--- Code: C++ ---#include <Windows.h> void writeKeyboardBuffer(const char* str){        INPUT in;         in.type = INPUT_KEYBOARD;        in.ki.dwFlags = 0;        in.ki.time = 0;        in.ki.wScan = 0;        in.ki.dwExtraInfo = 0;         for (const char* ptr = str; *ptr != '\0'; ++ptr)        {                               SHORT key = VkKeyScan(*ptr);                if (key & 0x0100)                {                        in.ki.dwFlags = 0;                        in.ki.wVk = VK_SHIFT;                        SendInput(1, &in, sizeof(INPUT));                       }                 in.ki.dwFlags = 0;                in.ki.wVk = key & 0xFF;                SendInput(1, &in, sizeof(INPUT));                        if (key & 0x0100)                {                        in.ki.dwFlags = KEYEVENTF_KEYUP;                        in.ki.wVk = VK_SHIFT;                        SendInput(1, &in, sizeof(INPUT));                       }                 in.ki.dwFlags = KEYEVENTF_KEYUP;                in.ki.wVk = key & 0xFF;                SendInput(1, &in, sizeof(INPUT));               }} int main(int argc, char* argv[]){        const char* cmd = "cd D:\\TEMP\r";        writeKeyboardBuffer(cmd);}

Navigation

[0] Message Index

[#] Next page

Go to full version