Run an executable relative to program's path

I made an application launcher (Windows forms application)

When I click the button, I can get it to run cmd.exe and stuff, but if I put spaces in the directory, it cuts it off. I tried escaping the spaces "\ "

I also cannot get system("\\buttonclicked.exe"); to work. How do I make it relative?

And system(); is my last option, CreateProcess refuses to work.


All I want to do is run an executable that is a few folders away, and I cannot even get it to run an executable in the same folder for debug reasons. Please help! Google has been no help, unless I am running them out of system32.
Last edited on
_getcwd ( http://msdn.microsoft.com/en-us/library/sf98bd4y.aspx )
And strcat ( http://www.cplusplus.com/reference/clibrary/cstring/strcat/ )

Also with space-containing directories, don't input them as

C:\Documents and settings

but as

"C:\Documents and settings"

instead.
Last edited on
So should I be using system("path"); at this point, or should I be using CreateProcess? I want as little hassle as possible, hopefully even just a couple lines of code. I will post my working code once I get it working, incase any of you future Googlers out there are searching.

So far I can formulate something like system("_getcwd/program.exe"); , of course not actually putting the function in there, but the results of it.
Last edited on
CreateProcess()
GetmoduleFileName()
PathRemoveFileSpec()
PathQuoteSpaces()

This are the correct APis I'd use. Forget about _getcwd() and others, working directory is not the same as executable file itself directory.


This will work no matter if you run inside the IDE or not, as you already seem to have issues with getcwd():
and I cannot even get it to run an executable in the same folder for debug reasons.
Last edited on
I have made progress. CreateProcess WORKS! However, it is locked to the C:/ directory, even without explicitly writing "C:/" (ex. "thing.exe" looks in C:/thin.exe).

I need it to grab from the current directory, as-in executables that sit side-by-side with my program.

For the directory of CreateProcess, I have tried "..//thing.exe", ".//thing.exe", ..\\thing.exe"... None of these work. Is there any way to natively grab from the current directory without using _getcwd? _getcwd refuses to work.

Why will "..\\x.exe" not find x.exe if it is in the same directory?

1
2
3
4
5
6
7
8
9
10
11
12
STARTUPINFO si;
PROCESS_INFORMATION pi;
memset(&si,0,sizeof(si));
si.cb=sizeof(si);
LPWSTR  a = L"../cleanup.exe";

if(!CreateProcess(a,NULL,NULL,NULL,0,0,NULL,NULL,&si,&pi)) 
{ 
	MessageBox::Show("Error launching program! Check your directory and locations.", "Launcher", MessageBoxButtons::OK, MessageBoxIcon::Error);
	//free(buffer);
	return; 
}    


I get the error message when cleanup.exe is in the same directory.
Last edited on
Tyler111 said:
Is there any way to natively grab from the current directory without using _getcwd?

You're going to kick yourself for this, but the function is GetCurrentDirectory(): http://msdn.microsoft.com/en-us/library/windows/desktop/aa364934(v=vs.85).aspx

On another note, memset() is kind of like malloc(), I think what you wanted in Line 3 is the ZeroMemory() macro: http://msdn.microsoft.com/en-us/library/windows/desktop/aa366920(v=vs.85).aspx

Also when you pass the file name to CreateProcess() as the first parameter it doesn't use the search path so it shouldn't execute anything from system32. EDIT: Get rid of the "../" prefix, that isn't doing you any good. If the program you want to execute is one folder deeper then the directory you are running this from then you want to type "FOLDERNAME/cleanup.exe".

Since you mentioned search paths in your origional post you should take note that certain IDE's change the default search paths of your executable when it is run from within them, this is why I don't use Code::Blocks.
Last edited on
closed account (DSLq5Di1)
CreateProcess is a little overkill if you don't intend to use the process handle. ShellExecute does what you need and supports relative paths:- http://msdn.microsoft.com/en-us/library/windows/desktop/bb762153
I have been trying for 2 hours, ShellExecute gives strange errors, too:


1>learn.obj : error LNK2028: unresolved token (0A00002F) "extern "C" struct HINSTANCE__ * __stdcall ShellExecuteA(struct HWND__ *,char const *,char const *,char const *,char const *,int)" (?ShellExecuteA@@$$J224YGPAUHINSTANCE__@@PAUHWND__@@PBD111H@Z) referenced in function "private: void __clrcall learn::Form1::button1_Click_1(class System::Object ^,class System::EventArgs ^)" (?button1_Click_1@Form1@learn@@$$FA$AAMXP$AAVObject@System@@P$AAVEventArgs@4@@Z)
1>learn.obj : error LNK2019: unresolved external symbol "extern "C" struct HINSTANCE__ * __stdcall ShellExecuteA(struct HWND__ *,char const *,char const *,char const *,char const *,int)" (?ShellExecuteA@@$$J224YGPAUHINSTANCE__@@PAUHWND__@@PBD111H@Z) referenced in function "private: void __clrcall learn::Form1::button1_Click_1(class System::Object ^,class System::EventArgs ^)" (?button1_Click_1@Form1@learn@@$$FA$AAMXP$AAVObject@System@@P$AAVEventArgs@4@@Z)

Just a bunch of symbols. It would be helpful if the error was in english.


1
2
3
4

LPCSTR  a = "cleanup.exe";
ShellExecuteA(NULL, NULL, a, NULL, NULL, 0);

I have tried ShellExecuteEX, ShellExecute, ShellExecuteW, ShellExecuteA,
LPCSTR, LPWSTR, TEXT(), L""... all error to the same thing. Unresolved externals.


I cant even get it to work at all, let alone relative paths.


EDIT. Fixed that, I had to link lib32. My program compiles at least, but when I press the button, nothing happens:

ShellExecute(NULL, NULL, L"C:\\Windows\\System32\\cmd.exe", NULL, NULL, 0);

How exactly should I format this to link it to something like CMD? Lets not forget relative paths, too. It's hard to know what the program is getting wrong, because nothing it executing, not even the known programs and locations.
Last edited on
Check your task manager, are you sure cmd.exe isn't running at all? Or is it just not running on your desktop?
The program properly opened after changing the last parameter to show normally rather than just throwing "0". I also got it to run relative directory stuff by changing my program to run as an Administrator. It all works now, all I have to do is put it into a function:

1
2
3
4
5
6
7
8
9

void LaunchApp(string app)
{

if(!ShellExecute(NULL, NULL, app, NULL, NULL, SW_SHOW))
MessageBox::Show("Executable not found! Check folders.");

}


Only problem is, my function does not return 1 or 0 like my if statement expects, and I cannot pass a string that the function can work with (because I have to put L before it, or TEXT() around it.

Can I change the string once it is passed? This will be a widely used function, and it will be difficult using these same 2 lines in all 30 of my buttons.
Topic archived. No new replies allowed.