I want to create a program that opens another .exe file in C++, I want the program to be able to run from any directory, so I will not know the full address of the file.
Eg-
The Program that I make will be present in a folder, which in turn has subfolders, which further contains javaportable.exe. I want the program to run the above mentioned .exe without getting the full path. Something like cd operator in normal DOS navigation. Also, if it is possible, I want to select another .exe, which will run through javaportable.exe, and is present in the previous folder.
First of all the standard C++ library does not provide any such functions to list the files of a directory. You can use boost libraries to get this done. Solution to this problem is not that easy. You will have to implement a lot of techniques to get this done. I can give you all the possible starting pointers.
To port this code to other OS you may need to add OS specific code using # preprocessor directives. Boost Liberay is already cross platform.
First of all you need to get the current path of the directory your program is present in:
For this you can use the following windows os specific code
#include <iostream>
#include <direct.h>
int main(){
char *path = NULL;
path = _getcwd(NULL, 0); // or _getcwd
if (path != NULL)
std::cout << path;
}
Here the path variable contains the address of the current directory. You can pass this path to the next function which will further use it to list the files and directories for you. For listing the directories you can use Boost Liberaries http://www.boost.org/
Next you will need to get all the files and folders present in current directory. Use Boost library for this
Use this sample code from boost
http://www.boost.org/doc/libs/1_37_0/libs/filesystem/example/simple_ls.cpp
Then make a class and store the address received and files names with path in its objects. You can store all the listed address in a object like dir[1].str[size], dir[2].str[size],...so on.
Now again pass all the folder addresses you received to boost function and get further filenames. All of the above will require many passes.
You can also get the list of files for specific file extension too:
#define BOOST_FILESYSTEM_VERSION 3
#define BOOST_FILESYSTEM_NO_DEPRECATED
#include <boost/filesystem.hpp>
namespace fs = ::boost::filesystem;
// return the filenames of all files that have the specified extension
// in the specified directory and all subdirectories
void get_all(const fs::path& root, const string& ext, vector<fs::path>& ret)
{
if(!fs::exists(root) || !fs::is_directory(root)) return;
fs::recursive_directory_iterator it(root);
fs::recursive_directory_iterator endit;
while(it != endit)
{
if(fs::is_regular_file(*it) && it->path().extension() == ext) ret.push_back(it->path().filename());
++it;
}
}
Finally compare the filenames with the one you want to run and execute it.
The problem can be solved by many other methods too but I think it will be good to start and you can always improve your code.
References:
How to get list of files with a specific extension in a given folder
http://www.boost.org/
How do I get a list of files in a directory in C++?
Hope this helps. If you need any further help feel free to ask!
Related
I already know how to set a relative working directory path and access resources inside of visual studio. However, when I build my solution and move the exe to a separate file I have to include all the resources in the same directory as the exe. I'd prefer to have a folder with said resources alongside the exe to keep things clean. Is there a macro I need to use? Is the working directory the right setting to change for this?
example
Sorry for this incredibly basic question, but I think I lack the vocabulary to accurately describe the issue.
For a Windows solution, GetModuleFileName to find the exact path of your EXE. Then a simple string manipulation to make a resource path string.
When you program starts, you can use this to ascertain the full path of your EXE.
std::string pathToExe(MAX_PATH, '\0');
GetModuleFileName(nullptr, szPathToExe.data(), MAX_PATH); // #include <windows.h> to get this function declared
On return, szPathToExe will be something like "C:\\Path\\To\\Your\\Program\\Circle.exe"
Then strip off the file name to get the absolute path
std::string resourceFolderPath = szPathToExe;
size_t pos = strPath.find_last_of("\\");
strPath = strPath.substr(0, pos+1); //+1 to include the backslash
Then append your resource folder name and optionally another trailing backslash.
resourceFolderPath += "res\\";
Then change all your I/O calls to open files relative to resourceFolderPath
You should probably add reasonable error checking to the above code such as validating the return code from GetModuleFileName and find_last_of calls.
This question is many time asked and I referred all, but I need bit different.
I am using macbook -> Clion (IDE) for C++
My program file location
/Users/Kandarp/ClionProjects/SimulationParser/main.cpp
When I use following function for get current directory it gives different file (I think actual path where file is compiled and execute)
string ExePath() {
char cwd[1024];
if (getcwd(cwd, sizeof(cwd)) != NULL) {
fprintf(stdout, "Current working dir: %s\n", cwd);
return cwd;
} else {
perror("getcwd() error");
return 0;
}}
it gives following answer:
/Users/Kandarp/Library/Caches/CLion2016.2/cmake/generated/SimulationParser-50b8dc0e/50b8dc0e/Debug
But I need path where my .cpp file reside.What I am doing wrong ?
Please help
You're doing nothing wrong.
getcwd() gives you the current directory of the executing process.
When you instruct whatever tool you're using to build your C++ code to run it, it simply runs the process from that directory.
There is nothing in the C++ library that tells the application the location of its source code.
If you need your application to know where its source code lives, you need to pass that either as an argument to main(), or put it into some configuration file, that your application reads, or any similar approach.
What you want to do is use the __FILE__ macro, and then use basic tokenization to extract the directory name.
Your method does not work since during execution, the current directory is that of the binary, not of the compilation unit.
I'm working on assignment for my university. I have a question on how to display all the files contain inside a particular directory. My working environment is on LINUX UBUNTU 14.04 G++ Compiler.
Let's take an example, I want to display/output all the files inside this DIRECTORY
/home/user/Desktop/TEST/FileSystem
File contains inside FOLDER FileSystem
-test.txt
-abc.txt
-item.txt
-records.txt
I'm not sure whether it can be done by using:
-Using Execute System Command, by calling standard library header.
#include <iostream>
#include <stdlib.h>
int main()
{
system("pwd"); // Directory: /home/user/Desktop/TEST/FileSystem
system("ls"); // Display every files contain in the FileSystem Folder
}
OUTPUT that I expected:
/FileSystem Folder contains:
-test.txt
-abc.txt
-item.txt
-records.txt
How can I code my source code so that I'm able to achieving this OUTPUT/Display that I expected. I have go through some internet sources by googling it. But I find out difficulty on understand it. That's why I have made a decision to post my question on here.
Thank You in advance to you guys for helping me to solve my coding problem.
You need to first open directory for which you need to list files after that you need to read directory.
Add #include for using apis.
#include <dirent.h>
/* open the directory "/home/" for reading. */
DIR* dir = opendir("/home/users");
entry = readdir(dir)); //files or directories in /home
//Add logic to verify entry is file or directory
Refer this thread http://www.cpp-home.com/tutorials/107_6.htm
the function
system("ls")
is just firing the command but you are missing what the output of the command ls is.
You need to capture it.
In this other thread it's explained how to do it.
in the directory containing my exe I have a folder called "saves".
I want to display the files this directory contains.
I used the code found here:
Listing directory contents using C and Windows
Now the tricky part.
if I use .\\saves\\ as my directory it tells me that the path could not be found.
However if I use ..\\release\\saves\\ it works fine. But that's stupid. I don't want to go to the parent folder and than go back. Especially regarding that I don't know what name the user gives to the directory containing the exe (in my case it's "release" but who knows what the user does :-D).
I read through this: http://msdn.microsoft.com/en-us/library/aa365247(v=vs.85).aspx#fully_qualified_vs._relative_paths but it didn't help very much.
I also tried saves\\ or .\saves\\ but it doesn't work either.
I hope somebody can tell me how to fix this.
You're actually doing nothing wrong in code -- you've been launching the project from Visual Studio, which sets the Working Directory to the parent of the Release/Debug folders.
Go to Project->Settings(Properties)->Configuration Properties->Debugging->Working Directory
You can also run the exe outside of VS and the relative paths will behave like you expect.
If it is relative from the path to the executable, and not from the path of the current working directory, you could use GetModuleFileName() to obtain the full path to the executable. Then, remove the name of the executable from the end of the path and build the paths using that:
std::string executable_directory_path()
{
std::vector<char> full_path_exe(MAX_PATH);
for (;;)
{
const DWORD result = GetModuleFileName(NULL,
&full_path_exe[0],
full_path_exe.size());
if (result == 0)
{
// Report failure to caller.
}
else if (full_path_exe.size() == result)
{
// Buffer too small: increase size.
full_path_exe.resize(full_path_exe.size() * 2);
}
else
{
// Success.
break;
}
}
// Remove executable name.
std::string result(full_path_exe.begin(), full_path_exe.end());
std::string::size_type i = result.find_last_of("\\/");
if (std::string::npos != i) result.erase(i);
return result;
}
I would use boost::filesystem
http://www.boost.org/doc/libs/1_53_0/libs/filesystem/doc/index.htm.
As a bonus you will get operating system independent code.
I think your mistake was using \\saves\\and forgeting to specify a search parameter/string
You should use:
saves\\*
this will search for any file or folder
My programs have been running properly for over a year. Today I copied the files onto a different system and compiled every program.
When I compile and run from Dev-c++ it writes data onto a text file like its supposed to, but when I click on the executable it creates, it does not write data onto the file. Everything else like input/output seems to work.
What procedure have I missed?
Ok i've given the program Full permision but it still does not write.
I'm quite puzzled, atleast if it didn't run when i compile it in the C++ environment i can keep checking my code, but only the .exe does not work, any other suggestions ?
#include <iostream>
#include <fstream>
using namespace std;
int main() {
ofstream bss2;
bss2.open("expat.txt",ios::app);
bss2 << 2 ;
bss2.close();
}
This is the sample code i tested out.
How do i find the Current working directory ?
Ok i changed a line to
bss2.open("c:\\expat2.txt",ios::app);
and now it works properly in the exe file.
but there's over 50 files and i prefer i didn't have to spell out the new path to each one, what workaround is there to set the directory to the one previously used ?
update 4 :
#define _POSIX_SOURCE
#include <unistd.h>
#undef _POSIX_SOURCE
#include <stdio.h>
main() {
char cwd[256];
int y;
if (chdir("/tmp") != 0)
perror("chdir() error()");
else {
if (getcwd(cwd, sizeof(cwd)) == NULL)
perror("getcwd() error");
else
printf("current working directory is: %s\n", cwd);
}
scanf(y);
}
Ok i used the getcwd() and this is the message it gives me
chdir() error(): No such file or directory
How do i set the directory now.
Sounds like your working directory isn't being set correctly when you double-click on the file. If you can access a log, use getcwd() and log what it returns.
I don't have Raymond Chen's psychic debugging powers yet, but I do know of a tool that may help you: Process Monitor. Use it to see precisely which files your application is trying to write to, and why it fails.
Maybe your looking at the wrong location. The program will write the file to the current working directory, which may be different between when you double click on the executable and run from Dev-C++.
The best and easiest way is to give the full path of the output file rather than just the filename. That way, you can be sure where the file went, and not have to search for it everywhere. If you are using Windows, the output file might be somewhere in system32. But I could be wrong.
As others have said, the working directory is likely incorrect.
If you create a shortcut to the .exe, you can set the working directory in the shortcut properties. Right-click on the shortcut, select "Properties", and change the "Start in" property.
Of course a better answer is to put the full path of the file into the filename string when you open it.
It might be that Windows uses backslash, so try "\tmp" instead of "/tmp".
Also if all your files are in the same directory, then you can use find & replace and replace open(" with open("c:\\your_directory_here\