How to create a .desktop file application launcher on Linux? - c++

I've developed an application in Qt which uses a launch script, myapp.sh. I've created a .desktop file which launches this script, and set:
Command: $PWD/myapp.sh
Work path: $PWD
However, $PWD prints my home directory when I launch the .desktop file, resulting in attempting to launch ~/myapp.sh rather than ~/Development/build-directory/bin/myapp.sh (that directory being where the .desktop file resides). Why isn't it correctly setting the working directory to where the .desktop file is actually located and how can I get around this without having to specify an absolute path in the .desktop file?

$PWD holds the current working directory of the shell, which has nothing to do with the location of the .desktop file.. One way you can do this is with:
Exec=$(dirname %k)/myapp.sh
From the spec, %k is "The location of the desktop file as either a URI (if for example gotten from the vfolder system) or a local filename or empty if no location is known." So this is myapp.sh in the same directory.

Related

why std::filesystem::current_path() returns different variables when im in editor and using .exe

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.

ofstream writing to my documents when launched remotely with shell from vba from access

I have a vba scrip that launches a .exe this .exe is a program that writes to a file. These files are both in the same directory, and they're both using current directory as inputs and outputs for the read/write/launch.
The .exe writes to the current directory fine, but when I launch it through shell in vba it writes to my documents.
I genuinely have no idea why it's doing it, all I know is it shouldn't be.
Assuming that the MSAccess database that contains the VBA code is in the same directory that contains the EXE file, you can change the current directory to be that by adding the following line to the VBA code:
ChDir Left(CurrentDB.Name, InstrRev(CurrentDB.Name, "\") - 1)
That should be done somewhere prior to the Shell statement.
If the database is not in the same directory as the EXE, you might have to hardcode the path. If, for instance, your Shell command is currently something like
Shell "C:\abc\def\xyz.exe"
then you could use
ChDir "C:\abc\def"
Shell "xyz.exe" ' No *need* to include path information anymore
' because it is now in "current" directory
The best solution though, if you have access to the code for the EXE, is to change the EXE to read/write from files which are located in the same directory as the EXE itself rather than from the "current" directory.

Where are files placed when a path does not include a path or drive letter?

When I indicate a file to create and write to via ofstream without a path or drive letter, i.e. "testfile.txt" where is it placed when NOT run in an IDE (when run in VS, the file is placed in the project working directory) and run from a shortcut (I needed to indicate command line arguments)? It does not place it in the same location as the executable when run from a shortcut.
Your shortcut has a "Start in" property, which is the directory where your files will be placed by default (i.e. if you don't specify a path). The main exception is that in Vista, if the directory is in \Program Files\ the actual writes will be redirected to your profile directory.
If you start the program from the command prompt, the default directory is the working directory (i.e. your CMD.EXE prompt when you started your program). This isn't necessarily where your program is located. If your program is on the %PATH% or if you specified a full path to your executable, CMD can run your executable even if is stored outside your current working directory.

Open txt file with default program

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

Relative path problem for a deployed win32 application

I have written a c++ program and deployed it in say c:\my_app, and my executable's path is c:\my_app\my_app.exe. Say, my_app needs many files such as the_file.txt, which is located in c:\my_app\the_file.txt.
In my executable, I open the txt file as, xx.open("the_file.txt");
Moreover, I have associated my program with let's say .myp extension.
When I'm on Desktop, and want to open a file named example.myp, my program can not see the_file.txt. Because, it (somehow) assumes that it's currently working on Desktop.
Is there any easy way to handle this problem by changing shell command for open in HKEY_CLASSES_ROOT? The naive solution would be to change all file open operations with something like %my_app_location/the_file.txt". I don't want to do that.
Always use a full path name to open a file. In other words, don't open "foo.txt", open "c:\bar\foo.txt". To find the install directory of your EXE use GetModuleFileName(), passing NULL for the module handle.
These days you shouldn't add files to c:\my_app....
Instead use the ProgramData Folder and full paths.
Use SHGetSpecialFolderPathA with CSIDL_COMMON_APPDATA to get the ProgramData folder and the create your program directory and add your files.
You should set current directory for your app's folder with SetCurrentDirectory function. After that you can open file by name without full path