According to the documentation for the OPENFILENAME structure, the following algorithm is used to select the initial directory:
Windows 7:
If lpstrInitialDir has the same value as was passed the first time the application used an Open or Save As dialog box, the path most recently selected by the user is used as the initial directory.
Otherwise, if lpstrFile contains a path, that path is the initial directory.
Otherwise, if lpstrInitialDir is not NULL, it specifies the initial directory.
If lpstrInitialDir is NULL and the current directory contains any files of the specified filter types, the initial directory is the current directory.
Otherwise, the initial directory is the personal files directory of the current user.
Otherwise, the initial directory is the Desktop folder.
I'm using the following code to construct a file dialog:
CFileDialog dlgFile(bOpenFileDialog);
dlgFile.m_ofn.lpstrInitialDir = strSourcePath;
dlgFile.m_ofn.lpstrFile = fileName.GetBuffer(_MAX_PATH);
However, it ALWAYS opens the same default folder in strSourcePath. Does anyone know why? It should only use this directory the first time, and subsequent file opens should remember the last folder (bullet point 1. in the algorithm). I'm using VS2012 on Windows 7.
Here is the fix:
dlgFile.m_ofn.lpstrInitialDir = strSourcePath.GetBuffer(_MAX_PATH);
Don't forget to call strSourcePath.ReleaseBuffer(); when you done.
If you are using lpstrFile to specify filename, then you may need to prepend initial directory path to the filename.
Related
I have my project where i am using filesystem to retrieve directory of assets.
When i am lunching my program in editor(im using Visual Studio 2019) everything is fine and this code return value of working direcotry of project.
std::string currentPath = std::filesystem::current_path().string();
But when i am lunching app from .exe file this line of code returns path that leads to .exe file.
The same directory called $TargetPath in properties in VS.
So my question is why is that happening and how can i resolve this problem.Becouse of that i cannot automatically load assets when lounching app from .exe file
Because it gives the current working directory, which is set by the environment calling your program (unless your program explicitly changes it).
So, it does what it's designed to do, gives the current working directory:
Returns the absolute path of the current working directory,
So my question is why is that happening
It happens because you've configured the editor to set the working directory to one path, while you're running the program with another working directory outside the editor.
how can i resolve this problem.Becouse of that i cannot automatically load assets when lounching app from .exe file
Here is an approach:
Store the assets in a path that is relative to the exe.
Get path to the exe.
On POSIX, you can use argv[0] from arguments of main
On Windows, the documentation recommends GetModuleFileNameW
Get canonical absolute form of that path (make sure that working directory hasn't been changed before this step if the path to exe is relative).
Get the directory that contains the exe from that canonical path.
Join that directory path with the asset's relative path to get an absolute path to the asset
Load the asset using the absolute path.
I have a c++ project that I would like to send to someone in executable form. The issue is the program must read from a .txt that I created (specific deliminators). Currently my program reads from a file path that is specific to my computer,
parseFile("/Users/David/Desktop/FinalProject/Store.txt");
How could I package the .txt file and the executable file together, where the exec. reads specifically from the that .txt on anyone's machine?
Note: I am using Xcode
Change your programs to receive 'file path' as a parameter. Write a note(ReadMe) with the program to specify the file format and added a sample data file with the package
tl;dr: if you just put the text file in the same folder with your executable, you can open it with parseFile("Store.txt");
In most runtime implementations, there is a notion of a "working directory." When you open up an executable via the graphical shell (by double clicking it or something to that effect) the working directory is the same as the directory the executable is in.
Now, if you try to open a file in your program via a path that isn't fully qualified, then the path that gets used will be relative to the working directory.
A fully qualified path is a discrete path that points to a single entity in your filesystem. "/Users/David/Desktop/FinalProject/Store.txt" is one such example, as it starts at root (/ on *nix, DriveLetter:\ on Windows) and says exactly which directories you need to traverse to get to your file.
A path that is not fully qualified (which basically means that it doesn't start at the root of your filesystem) can be used to perform relative file addressing. Most runtimes will assume that any path that is not fully qualified is meant to be relative to the working directory, which basically means that the path that actually gets opened is the result of concatenating your provided path to the end of the working directory.
As an example, if you opened your binary, which is stored as /Users/David/Desktop/FinalProject/a.exe, then the working directory would be set to /Users/David/Desktop/FinalProject/. If your program then tried to open "Store.txt", the runtime would see that you're trying to open a path that isn't fully qualified, so it would assume you meant to open a file relative to the working directory, which would then be /Users/David/Desktop/FinalProject/ + Store.txt, which would be /Users/David/Desktop/FinalProject/Store.txt.
The nice thing about this is that if you move your binary, the working directory moves too. if you move a.exe along with Store.txt to /Users/David/Desktop/FinalProject(copy)/, then when you open /Users/David/Desktop/FinalProject(copy)/a.exe, the working directory will be /Users/David/Desktop/FinalProject(copy)/ now, and now when you call parseFile("Store.txt"), it will instead open up /Users/David/Desktop/FinalProject(copy)/Store.txt. This holds true when moving to other computers, too.
It's worth noting that if your binary is run from a command line utility, the working directory will often be the directory the command line shell is in, rather than the executable's directory. It is, however, a part of the C standard that the first command line parameter to main() should be the name of the executable, and most implementations supply you with the fully qualified path. With some minimal parsing, you can use that to determine what path to use as a base for addressing files.
In my program, I have a button that I want to open a text file in a relative directory. I'm using QDesktopServices like this:
QDesktopServices::openUrl(QUrl::fromLocalFile("file:///stuff/block_settings.txt"));
When the button is pressed, nothing happens.
The file is in a folder named "stuff" that resides in the same location as my .exe. It is the same directory used for all my other tasks.
What am I doing wrong?
Thanks.
The file is in a folder named "stuff" that resides in the same location as my .exe. It is the same directory used for all my other tasks. What am I doing wrong?
Seems like your full path is an overcomplication. I would suggest to use this intead:
QString QCoreApplication::applicationDirPath() [static]
Returns the directory that contains the application executable.
For example, if you have installed Qt in the C:\Qt directory, and you run the regexp example, this function will return "C:/Qt/examples/tools/regexp".
On Mac OS X this will point to the directory actually containing the executable, which may be inside of an application bundle (if the application is bundled).
Warning: On Linux, this function will try to get the path from the /proc file system. If that fails, it assumes that argv[0] contains the absolute file name of the executable. The function also assumes that the current directory has not been changed by the application.
So, you would be writing this code:
QDesktopServices::openUrl(QString("%1/stuff/block_settings.txt")
.arg(QCoreApplication::applicationDirPath()));
I fixed the issue. Changed to:
QDesktopServices::openUrl(QUrl("file:stuff\\block_settings.txt"));
Not sure how that works because I don't see that configuration on any tutorial anywhere but w/e
I'm trying to load files, and previously I was using hardcoded file locations, (like "c:\location\file.txt") but now that a few friends are also using the file, I'd like to allow them to put the executable wherever they want.
my current code looks like:
ifstream myfile;
myfile.open("c:\\client\\settings.cfg");
I'm trying to change it so that the user puts their executable into whatever folder they want, and then they create a folder and put their settings file into it and the exe will load that with their settings.
ifstream myfile;
myfile.open("\\settings\\settings.cfg");
I have some basic error handling in place, and now the program always errors out saying that it can't find the file.
The file structure looks like this:
[ART]
asset.png
[SETTINGS]
settings.cfg
client.exe
This seems like a really simple thing to do, but I can't find any way to do it. Every example and tutorial about reading and writing to files deals only with files in the executable's directory, or hardcoded into c:\folder...
Could anyone point me to how I do this?
The search path for most systems starts with the current working directory and then to a PATH environment variable. So, all you need to do is specify the file/folder without the absolute path markings and it will use the path relative to the working directory:
ifstream myfile;
myfile.open("settings\\settings.cfg");
// ^^ Note the lack of \\ to start the file path
Paths beginning with \ are always relative to the current drive's root directory. If the current drive is C:, then \settings\settings.cfg means C:\settings\settings.cfg.
Note that you can use / in order to avoid escaping everything. So you can use: settings/settings.cfg. This will be relative to the user's current directory. Note however, that this doesn't necessarily correspond to the directory where the executable resides. If you need the directory of the executable, then you need to use a Windows API function to get it:
#include <Windows.h>
// ...
HMODULE module = GetModuleHandleW(NULL);
WCHAR path[MAX_PATH];
GetModuleFileNameW(module, path, MAX_PATH);
Now if you want to open settings/settings.cfg relative to the directory of the executable, create a path that starts with path and append /settings/settings.cfg to it.
i found C++ libraries could be included this way:
#include "..\example.h"
#include ".\another_example.h"
what is the dots used for?
They are to indicate the included file paths' are relative to the including file's actual path.
. points to the including file's actual directory
.. points to the including file's actual directories' parent diretory
Double dots stand for the parent directory of the currently entered path.
Single dot stands for the currently entered path on the left side of a dot and is used to show that you want a relative path.
A relative path is a path relative to the working directory of the
user or application, so the full absolute path will not have to be
given.
If you start your path with / (on *nix systems) or DRIVELETTER: (on Windows, e.g. D:) then the path is absolute. If you don't - the path is relative. If path is relative - it automatically prepends the directory of your file to the path entered.
Example:
"dir/././../dir/.." is the directory which contains the original file. The reductions are:
dir/././../dir/.. -> dir/./../dir/.. -> dir/../dir/.. -> /dir/.. -> . -> working directory. We removed ./ because it's alias to the current directory. We removed /dir/.. because we enter a directory with dir and get back with ..
One of the most often used features of ./ (but in the context of a shell, e.g. bash) - it forces to use a relative path instead of calling an executable program in the $PATH variable. For example if you type ls in terminal on *nix it will list the files in the working directory. If you type ./ls it will run executable with the name ls
in the current working directory and execute whatever this program does.
You can read more about path separators in this article on wikipedia
One dot is your current directory and two dots is your parent directory.
Two dots means one directory higher than the current one. For example, if you are in the directory C:\some\directory", "..\" would be "C:\some".
A single dot refers to the current directory. So using the previous example, ".\" would mean "C:\some\directory".
one dot . is for file's directory
2 dots .. are for file's parent directory.