How to have a C++ program run a cmd command [duplicate] - c++

I'm trying to use the system() function in a C program.
For example, I tried to create a directory on my desktop, using the system() function.My code:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
system("cd c:\\Users\\USER\\Desktop");
system("mkdir test");
return 0;
}
When I run this code, a directory is created, but not on my desktop. It is created in my project directory.
Why is this happens?
Can I use the cd command in the system() function? If not, is there an replacement to the cd command that will work with system()?
I'm using Windows OS. I'm trying to use system() from a C program as I use cmd program.
I know that I can create the directory using WinAPI without any problem. I don't want to use WinAPI, my question is how can I make it work using system().

The changed directory only lasts for the duration of the system command. The command starts a separate program, which inherits its current directory from your program, but when that program exits its current directory dies with it.
You can use && to join the commands together, and it will work:
system("cd /D C:\\Users\\USER\\Desktop && mkdir test");
I also added the /D switch, or the CD command would not change drive letter if it were called from a different drive.
However, mkdir is perfectly capable of accepting a full path, so you could simply do:
system("mkdir C:\\Users\\USER\\Desktop\\test");

When you say system("some shell command");, the program spawns a shell to run the command. The shell has its own idea of the current directory, separate from your program's. The shell cds to the directory just as you asked it to, and then dies, leaving your process's CWD unaffected.
You could simply say _chdir("c:\\Users\\User\\Desktop"); to set the current directory before running the "mkdir" command. The shell that spawns to run it will then inherit your program's current directory and make the folder in the right place.
(For that matter, you could say _mkdir("test") as well, and stop using system unnecessarily. You should only reach for system when you're trying to do something that's worth running an external program / shell for.)

You have to perform both the commands on a single line like this,
system("cd c:\\Users\\USER\\Desktop && mkdir test");

Related

How to install ninja-build for C++

https://github.com/ninja-build/ninja/releases
I have downloaded the ninja-win.zip folder and extracted it. When I open it, there is a single .exe file in the entire folder. When I double click it a cmd window flashes for a split second. I have also tried running it as administrator, but the same thing happens. What I don't understand is, what am I expected to do with this .exe file?
You must open a terminal (cmd.exe on Windows) and type something like ninja -f /path/to/buld/file. You may also wish to modify the PATH environment variable so that Windows knows where to find the Ninja executable, depending on your setup.
You can simple download ninja.exe file from this Link
https://github.com/ninja-build/ninja/releases
After that you just have to add the path to your ninja.exe file to your windows environment variables and then you can use ninja commands from anywhere in windows.
1. Open cmd in your Project Directory
2. There are guides on the internet on where to save the Ninja.exe so that it'll be callable in Cmd without specifying directory. Either follow them or:
i, Specify Directory when Calling Ninja. Putting "ninja" in Cmd actually calls Ninja.exe and is the same as something like "C:\users\user1\downloads\Ninja". or:
ii, Save Ninja.exe in the same directory as Project.
3. proceed with rest of the command.
Therefore the Final Command would be:
"C:\users\user\downloads\Ninja.exe" -f "D:\Projects\Project1"

How do I run a command line tool from a different directory in C++

I am trying to build a C++ application that makes a bunch of command line calls on the Windows command prompt using the system() function. The C++ runs in directory BSP below. BSP contains a sub-folder BSP/XST/Files. One of the commands the application makes, needs to call a command line tool (Xilinx Synthesis tools) that needs to run in the Files directory.
BSP
|---XST
|---|---Files
Doing it manually on the command prompt I would do something similar to:
>>cd XST
>>cd Files
>>xst -h
Is there a way to call a tool in the sub-directory from the BSP directory?
I looked at this question here, but it does not work. I'm guessing because they are talking about an executable that is stored within the sub-directory whereas I am calling a command line tool (i.e. uses environment variables).
To simplify: Is there a command/option to run a command line tool in a sub-folder on the Windows command prompt? I can just emulate the statement via my C++.
As suggested by #CodyGray in the comments, my idea was to use SetCurrentDirectory. If your program is located in the BST directory and you want to run xst in the sub-folder XST\Files relative to it, then it makes sense to also use GetModuleFileName. Use this function to retrieve the path to your program and then replace the file name by your sub-folder. Finally change directory to the modified path:
#include <string>
using namespace std;
int main()
{
// Get the path to your program.
char moduleFilePath[MAX_PATH];
GetModuleFileName(NULL, moduleFilePath, MAX_PATH);
// Find the backslash in front of the name of your program.
string::size_type pos = string(moduleFilePath).rfind("\\");
// Replace the program name by your sub-folder.
string subFolderPath = string(moduleFilePath).substr(0, pos) + "\\XST\\Files";
// Change into the sub-folder relative to your program.
SetCurrentDirectory(subFolderPath.c_str());
// Execute some program in your sub-folder.
system("type test.txt");
return 0;
}
As I don't have xst, I put a text file test.txt into the sub-folder for testing purposes. The file just contains Test test test, so the program above prints out the following:
Test test test
But as suggested by #MikeVine, CreateProcess might be a smarter solution.

Making c++ app use directory of file, not pwd

I am trying to run an application, app. I do this by running ./app in the directory of app. This application has a dependency, graphics/file.bmp. Everything works when I run ./app in that directory.
If I instead run from the parent folder, it can't find graphics/file.bmp when I run ./app_directory/app
What is the cleanest way to resolve this? I would like to cd into the directory of the file no matter where I am running the program from. I am on OSX and would be thrilled by a solution that works across all unix machines.
You can do this on the first line of main():
chdir(dirname(argv[0]));
dirname() removes the last path component from the input ("a/b/c" turns into "a/b") and if there is only one path component then it returns ".". Passing this return value directly into chdir() will change the working directory to the directory containing the binary.
You could try writing a bash script that you could run from any directory and it will cd into the directory that successfully runs the program, but this won't actually change the working directory at which your terminal is sitting. In case you don't know how to do that: make a file called build (or whatever you want) and place it in the parent folder. In that file put the following code:
cd app_directory
./app
After you create the script run chmod u+x <script-name>, which will make it an executable. Once this is done you can just run ./<script-name> and it should run your program just fine.

Using tree Command in C++ on C://

I want to use the Windows CMD tree command in my C++ console application. My code:
system("cd c:/");
system("tree");
The problem is that the command tree will execute on the folder path where the program is running and not on C://. Is there a way to fix this?
Why not :
system("tree c:\");
?
TREE [drive:][path] [/F] [/A]
/F Display the names of the files in each folder.
/A Use ASCII instead of extended characters.
You can use SetCurrentDirectory from windows.h. This page has a demonstration:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa363806%28v=vs.85%29.aspx
Your problem is that the system("cd c:/") is executed in a shell, and then the shell exits. [It's also wrong, because you use the wrong kind of slash, it should be "cd c:\\" - the double backslash is needed to make one backslash in the output, assuming we're talking about a Windows system].
There are a couple of different ways to do this:
Use chdir() (or SetCurrentDirectory) function call to change the main processes current working directory, and then call system("..."). This is the simplest solution.
Generate all your commands into a batch file, then pass the batch file to system.
Open a command shell with something like _popen() and pass commands into the pipe that you get from that.
Manually create pipes and connect them to the standard in and standard out of a process that runs the command prompt.
Just for programs in Windows, include "windows.h", then
SetCurrentDirectory("c:/");
system("pwd");
While I'm still curious why would you want to do this, you can try to run all commands in one system() call:
system("cd c: && c: && tree");
Second c: is needed to change drive letter, in case if you're not currently on drive c: (because cd doesn't do it).

Convert .bat to .exe without depending on cmd.exe

I have a bat to execute all files in a folder every 15 seconds. I need to make it .exe to run it as a hidden application.
I have converted it to .exe with bat to exe converter and other programs, and I see that in all of them, when I execute the .exe, for example, Load.exe, automatically start a cmd.exe at the same time. If I kill Load.exe it still continues to run, until I kill cmd.exe.
So, can I make an .exe from a .bat without depending on a cmd.exe?
Short but correct answer: no, you can not.
I don't know if it depends on CMD or not (probably it doesn't), but you can use C++ function system to execute each line of your .bat file.
Do it something like :
#include <stdlib.h>
int main()
{
system("<batch command goes here>");
return 0;
}
Simultaneously, you can add each line of .bat file to system function and execute it as a CPP/C program.