Get a directory path with console-like behaviour - c++

I am developing a non-GUI application for Linux. At some point I ask the user to input a directory path, which will be used to store files.
It there a way to have behaviour similar to the console (eg. when pressing TAB, the path is automatically filled for you, or available directory paths are printed)?
What is the usual solution for this kind of problem, in case what I am looking for doesn't exist?

The usual solution is to use readline's completion facility, just like the shell does.

What you are looking for is the readline library

Related

How I can I link dll library to my application? [duplicate]

On linux, we have LIBRARY_PATH and LD_LIBRARY_PATH environment variables in order for programs to search for libraries. Do we have similar thing on windows? Particularly Windows 7?
Also, I would like to know best practices for DLL use (where to put them, use envs or not, etc.), since I want to work on windows like everyone does, and not to sloth myself on workarounds :)
Edit: As explained by Bob, this answer describes the Alternate Search Order, which is not what most applications would see. The full rules are quite complex. I don't think I can summarize them here. Instead, read the Microsoft docs - https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order
My original answer was:
This MSDN article explains the default search order. I quote:
The directory specified by lpFileName.
The system directory. Use the GetSystemDirectory function to get the path of this directory.
The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.
The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
The current directory.
The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key. The App Paths key is not used when computing the DLL search path.
In (1), if you statically linked against the DLL's stub library, I think "the directory specified by lpFileName" is the process's exe's path.
Take a look at the help for the LoadLibrary and CreateProcess functions. These describe the paths used to locate DLLs, and how you can modify them.
It looks on currentDir first then WinDir and SystemDir also in your path
According to what #andrew has mentioned in his answer, the order of folders that are used on Windows to search a DLL may be different from one configuration to another. I think the simplest way to check this order on Windows is to use the Dependency Walker tool. After opening the tool, and pressing the "Configure Module Search Order" button on the toolbar, you will see a window like this:
This window shows you the current search order on your machine. The interesting part is that by pressing "Expand", you can see the whole folders in the search path one by one. You may also change the order if you want, to be used for loading an specific module.

How to specify a standard directory in a Qt project file

I have developed an application that I plan to deploy on Windows, Mac, and Linux. The program requires access to some files (scripts and the like) at run-time.
The installation process should install the files to a location that my application can later determine without user-intervention (or perhaps just a prompt allowing the user to change the location, if desired).
What is the best way to achieve this? I can't seem to find any way to:
1. Use a "standardized path" variable in the project file's INSTALLS statement. (e.g., my application could use QStandardPaths to initialize the location, but I can't figure out how to access this path from the INSTALLS statement)
2. Save the path to my project's QSettings (.plist, registry, whatever) for later retrieval
That leaves me with creating a custom project file and INSTALLS command for each environment, and then I still can't install to the user's directory because I don't know the user's name when I deploy the make command. It seems as if there must be a better way, but I can't seem to find any documentation for this. Am I just using the wrong keywords in my searches? Thanks in advance!
What standard directory? What type of getting that standard directory?
For instance, you can put such thing in your windows branch of .pro file:
win32 {
APPDATA_DIR = $$system(echo %APPDATA%) # should be %LOCALAPPDATA% as requested
message($$APPDATA_DIR)
}
Just unsure of what exact kind of standartized path you are talking about. QStandardPaths knows many. It makes sense to be more concrete to find the correspondence with concrete OS.
Also somewhat relative reply on mine, on how to check the correspondence with certain variable, etc: Qt .pro file - how to add conditioning on OSX version?
Maybe this class will help you
QStandardPaths documentation
But your problem is still little bit unclear for me.

File path of .exe File in windows 7

I am working in a C++ project. I need to obtain the path of a installed software. (Eg. skype.exe) Is there any way to find the path via C++ coding or via Widows command prompt
Depends what you are needing it for, and how generic you want it.
You can use GetEnvironmentVariable to get the PATH variable, and search these paths.
You can use the App Paths registry key, as Gabe says. See also...
Usually there are pretty clear application-specific ways to find the path via the registry. Either via the HKLM/Software key or Uninstall. Careful with localization and hard-coding application names...
If you are just trying to launch the app, ShellExecute doesn't need the full path, it works almost like the "run" dialog box in the start menu.
It's in the App Paths registry key. For skype.exe you would look in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\skype.exe
You can call the standard Win32 API RegQueryValue to read it.

How to check if path leads to executable file?

I try to create some kind of file browser. I want to know if file under path is executable in a cross-platform way.
How to do such thing with boost::filesystem?
Boost doesn't have stuff about permissions, because POSIX permissions are not "crossplatform".
Use the platform-specific APIs at your disposal as required. Sorry!
You can try QT. It is cross-platform. You do not have to care about the operating system differences while dealing with files. What you mean by "executable" is somehow unclear though. If you are talking about file permissions, OT can give this kind of information (Just look at QFile class documentation). If you want to learn whether you can actually run it or not, you have to have some kind of file extension convention. For example, .exe in Windows. I do not know, may be there is a way to look at the initial bits of the file and learn whether it is a binary or not, but I think you will not be able to find a library call for that. You have to implement some platform specific routines for this. If I am not mistaken, file browsers mostly look at the extension of the file to find out the type. For example, if you change the file extension of a pdf to exe than windows explorer sees this file as an executable. Clearly after the file type assumption, it can try to learn some other things about the file, such as icon of the executable. But initially it only looks at the extension. Otherwise, it would be very slow to browse directories containing large numbers of files.
I hope, I gave some relevant information here

I can't go to a directory with C++

I need to change working directory of my project, so that output files go to a certain folder, not where all the project files are.
I'm using
system("cd secretdir/");
system("ls");
However, what I get, is the list of files in current project directory, not the "secretdir" one.
I'm on Mac OS X 10.6/Qt Creator 4.7 64 bit
Thanks!
You have to change the current working directory
http://www.linuxquestions.org/questions/programming-9/how-to-change-current-working-directory-in-c-550031/
Also, you should consider saving your output files with full path names instead of changing the working directory.
Your current code will spawn a subshell that will change its current directory to ./secretdir, then proceed to exit() without doing anything else.
Only then will ls run in another subshell, whose current directory is, of course, completely independent of what you did during your previous call to system().
That's probably where your problem lies. Are you looking for the chdir() function?
chdir("secretdir");
// From now on, the current directory of the process is `./secretdir`.
system("ls"); // Will probably behave as expected.
edit See Falmarri's response as I glossed over the first sentence of your question.
You can also use chdir
the following is crufty
The first system spawns a new process that does the cd. The second system spawns a completely different process that doesn't know what happened previously.
One thing you could do is:
system("ls secretdir/");
I'd highly recommend checking out QDir, QFile, and QProcess objects in the QT Creator help or online documentation since you are using it. They have very detailed and easy to understand documentation and using the tools available to you in QT should be a primary reason for choosing that tool much of QT rivals boost in portability and usability in my limited experience.
Also there is a great community for QT related questions at QTForum worth bookmarking especially if QT Creator is your primary development environment.
Using system should be avoided as general rule of thumb it is inefficient and insecure in many cases.
EDIT: Sorry I too glossed over your first sentence and jumped to the code bits. You can modify the project settings via the Projects tab in QT Creator to add a Custom Process step to the build where you can specify a working directory and then do a copy command to wherever you would like your output to go. You also may be able to specify a build output option within your .pro file directly ... once again the help and documentation is your friend however.
The function on Mac OSX is chdir("./secretdir"), although since it's a POSIX API it actually works the same on many other platforms as well.
Using system() is not portable so try to avoid to use directly "cd" like that. My advice is to use Boost filesystem.
There is a Two-minutes Tutorial !
Do
system("cd secretdir/; ls");
Or better yet use boost's filesystem library. Maybe just opendir.