I have built a C++ cross-platform application and am struggling with how to get it to work correctly on macOS.
So far, I'm able to run the application manually with the command open /Applications/myApp.app --args /path/to/myFile.ply.
I have associated all ply files with my application but when I double click on it in the finder, the file path is not in argv argument list.
How can I get the double-clicked file path in my application?
You'll need an event loop, normally done using the NSApplicationMain function. Then you need to receive an Apple Event telling what file(s) to open. It will be much easier if you are willing to use some Objective-C or Swift, rather than pure C++. In Objective-C, you'd make an object that conforms to the NSApplicationDelegate protocol and that implements a method application:openURLs: or application:openFile:.
#JWWalker has explained how to solve your problem by altering your code to cope with the macOS GUI environment. Here is a different approach which avoids messing with your C++. Pick the one that suits you needs best.
If your cross-platform application is designed to run from the shell prompt you might want to run it within the macOS Terminal app. You can do this using a small AppleScript application which accepts the file paths passed by the Finder and invokes the Terminal app to run your C++ code.
To do this open Script Editor, you will find it inside Utilities in Applications. Enter the following:
on open passedItems
set convertedPaths to ""
# convert passed macOS paths to posix paths
repeat with nextItem in passedItems
set posixPath to the POSIX path of nextItem # convert macOS alias to posix path
set convertedPaths to convertedPaths & " '" & posixPath & "'" # place in quotes to protect any spaces
end repeat
tell application "Terminal" # open (if required) and activate Terminal
activate
do script "echo " & convertedPaths # just run echo - use the path to your C++ binary instead
end tell
end open
If you can program in C++ you can probably figure that out, if not search for AppleScript and all will become clear.
Now save this as an application, for this demo it was saved in /tmp/bridge (aka /private/tmp/bridge on macOS) as "Bridge.app".
Now create some test files with a suitable extension, e..g something like:
$ cd /tmp/bridge
$ touch a.bridgeDemo 'b c.bridgeDemo'
From Terminal you can open /tmp/bridge in a Finder window using:
$ open /tmp/bridge
In the Finder select any of your test files, do a Get Info and set the file to open with Bridge and then hit Change All...
Now try it: select the test files in the Finder and open them. You should see Terminal open/activate and show you something like:
$ echo '/private/tmp/bridge/a.bridgeDemo' '/private/tmp/bridge/b c.bridgeDemo'
/private/tmp/bridge/a.bridgeDemo /private/tmp/bridge/b c.bridgeDemo
$
Now edit the AppleScript to run your compiled C++ instead of echo and save it in a suitable location. HTH
Related
How would I get the full path to a specific file (on a system running OSX) once the file name is given by the user on a console application?
Any links or help would be great thanks.
You need to write a filesystem walker. C++ filesystem library will be of use. Start from your initial directory and start iterating. You can use DFS/BFS or your own custom algorithm
Another choice would be to simply see find commands source on Linux/Mac.
Edit 1: If you do not want to write a program then use terminal and fire following:
find / -name <whatever your filename is>
So I have started to use Sublime Text 3 recently with my Ubuntu OS. I wanted to test it out so wrote a simple piece of c++ code. But when I try to build it does nothing, I have checked online and still nothing I even installed a build system (https://github.com/shikharkunal99/Sublime-Build-System) and still whenever I go to build it just opens open a black section at the bottom (see picture)
Install g++ to run c++ code
apt-get install g++
Then I will tell you a personal trick that I used. it is:
find | grep "part of your filename"
Replace "part of your filename" section with the name of the file or a part of the name of the file.
Suppose, the file name is Here.c. I type "Here" in place of part of your filename.
Then the final step, type
./a.out
Output is ready in front of you.
This post will help you in setting up Sublime Text 3 in a way that leads to a good workflow specifically for C++ programming environment (Ubuntu, GNU C++ Compiler) :
Note: Only the following step is essential for running c++ programs.
1. Create a Build System in Sublime Editor :
Sublime Text provides build systems to allow users to run external programs.
Go to Tools -> Build System -> New Build System.
Paste the following code in the file
{
"cmd": ["g++ -Wall -Wextra -O2 -pthread -H -std=c++17 \"${file}\" -o runfile && ./runfile <input.in> output.out"],
//above line works fine if input.in and output.out files are present in same directory in which .cpp file is present else add complete address of these files for using them as common input output files in your system.
"shell":true,
"working_dir":"$file_path",
"selector":"source.c,source.c++,source.cpp",
"variants": [
{
"name": "Variant Run",
"cmd" : ["gnome-terminal -- bash -c \"g++ $file_name ;echo ------------Output-------------; ./a.out;echo;echo; echo Press ENTER to continue; read line;exit; exec bash\""
],
}
]
}
Save the file (By default the file is placed in "~/.config/sublime-text-3/Packages/User" dir) something like "C++17.sublime-build" to differentiate it from the other build system files.
Create input.in and output.out text files in your working directory. This can be used for piping input from the input.in file, and output to the output.out file.
Note in the first line it uses the -std=c++17 flag to enable the latest features of C++17. If you don't want this or want to use C++14, replace this with the -std=c++14 flag.
Refer to https://linux.die.net/man/1/g++ for different compiler flags.
See Also https://discuss.codechef.com/t/are-any-compiler-flags-set-on-the-online-judge/1866
2. Setup window layout :
Create three new c++ file, file.cpp. Select View > Layout > Columns : 3. This will create three columns in the workspace. Select View > Groups > Max Columns : 2.
Write a hello world program & save inputs if any in the input.in file, and test its working. Use Shift+Ctrl+B and Select C++17 to build and execute the file (If selected C++17 - Variant Run it will execute the program in a separate terminal window like a normal program would).
The windows will look like this when you are done.
Layout Preview
3. Precompile headers :
Generally useful in competitive programming, we can speed up compilation time by precompiling all the header files as mentioned here, i.e. by precompiling the bits/stdc++.h header file.
For this, first, navigate to the stdc++.h file. This will be located at a directory similar to ~/usr/include/x86_64-linux-gnu/c++/9/bits Open terminal window here.
Run the command sudo g++ -std=c++17 stdc++.h, to compile the header. Take care to use the same flags you used in your build system. Check to make sure that the stdc++.h.gch file was created in that directory.
4. Sublime Text features :
Snippets & Completion
Read up on the documentation of snippets and completions at the official guide.
5. Other Features :
Read https://scotch.io/bar-talk/best-of-sublime-text-3-features-plugins-and-settings
This program works perfectly fine for me using Build 3120, and I expect it will work fine with previous builds. First, you need to select Tools → Build System → C++ Single File (Tools → Build System → Automatic should also work, but I prefer to be explicit). Then, either hit CtrlShiftB or select Tools → Build With… and select C++ Single File - Run. This will compile your .cpp file to an executable in the same directory as the source file, then run it.
Well I also got various issues with this thing finally I got an amazing thing in the package control pallet.Follow the instructions:
1.Open up the Package control Pallet
2.Search for C++ Builder
3.You will see C++ Builder-Mingyang Yang
4.click it and then wait for a couple of seconds
5.finally go to tools->build system->select C++ Builder-Mingyang Yang
6.finally tap the Shift+Ctrl+B and then select C++ Builder-Mingyang Yang Build and Run
7.finally here you go you can not only build this but also use the console for input
Note:This will execute only when there is gcc compiler included in the terminal otherwise at first install gcc by the command apt-get install gcc then you can use c++
I am writing a simple C++ helpertool for a popular game (League of Legends), targeted at windows users.
I wish to allow the user to auto restart games which crash. This can be done by starting 'leagueoflegends.exe'. I want to autodetect the location of the executable and this is where I have issues.
The exe is located at:
*GAME_FOLDER*\RADS\solutions\lol_game_client_sln\releases\x.x.x.xx\leagueoflegends.exe
I use a registry entry to get the game folder, ie: C:\leagueoflegends\
However there is a folder that changed with every update in the form of x.x.x.xx where the x are digits (numbers) reflecting the versions. There is always 1 folder in the releases folder.
I figured I need to use REGEXP but I didn't have much luck.
This is the regexp I made:
^[0-9]\.[0-9]\.[0-9]\.[0-9][0-9]$
This is what I used to get the name of the dir using cmd
dir /B | findstr /R " ^[0-9]\.[0-9]\.[0-9]\.[0-9][0-9]$"
However I cant seem to be able to run the executable no matter what I do. Its not like linux where I can manipulate filters and pipes. Any help with a one liner to run the exe or methods of obtaining the folder name (without using a system call?) would be appreciated. Once I can get the folder name in a variable then it becomes easy.
Thanks in advance!
I was wondering how to open a file other than notepad... Our prof gave us an example:
s = "notepad.exe test.txt";
system(s.c_str());
That will open a file type of "notepad.exe" and the file name of "test.txt"
Main Question:
Now, I was wondering if there was a way to open other type of files, such as Microsoft Excel, Microsoft Word, Visual Studio, or 7zip.
My attempt opened something in a new cmd.exe (because of the START keyword):
fileNeededtoBeOpened = "START \"New Microsoft Office Excel Worksheet.xlsx\"";
system(fileNeededtoBeOpened.c_str());
(This code is slightly different from my original, where I'm trying to open a file from a vector...) but all I really need to know is instead of "notepad.exe" or "START" is there a different command to open different file types that aren't .txt
Also, a side note, I was reading on the internet that it wasn't safe to use system() to open files, is this correct?
I found the answer by myself... for those who are curious, here an the answers:
To open a text file: system(notepad)
To open an excel file: system(start excel)
To open a word doc file: system(start winword)
To open a 7z file: system(start 7zFM)
To open a visual studio file: system(start devenv)
I think you're confused.
System executes a command as you would on the command line (type cmd into the run prompt under start menu to get that).
So, when you type notepad.exe test.txt it's saying:
Open the program notepad.exe which is on the system path (so the
command line can find it to execute that program), and pass the
parameter test.txt to it.
Notepad itself decides what to do with test.txt, in this case it opens it.
So, you can tell it to run any command (program/executable) and pass any parameters to it in reality. If excel's on your system path, you can probably just type excel.exe to open it from your system command. Otherwise, find the location excel is installed in, and refer to it with the whole path to excel.exe and it will work fine.
For example, on my computer, executing "C:\Program Files\Microsoft Office\Office12\EXCEL.EXE" would open excel from the command line. I can pass further parameters to it by having more information (like filenames) after the Excel.exe" portion, just as you did in your notepad example. Using your system command should have equivilent behavior when that line is executed.
If you are only targeting Windows systems you can use the ShellExecuteEx function (part of the Win32 API). You can just pass a filename to it and it will launch what ever program is registered to handle that file type (just as if you opened the file from windows explorer). Documentation is available on MSDN:
http://msdn.microsoft.com/en-us/library/windows/desktop/bb762154(v=vs.85).aspx
There is some examples on Launching Applications (ShellExecute, ShellExecuteEx, SHELLEXECUTEINFO) MSDN article and lots more elsewhere around the internet.
AS the other guys mentioned , the System function only executes a cmd command, .. notepad.exe is in the system's path by default so it works directly
but for example for me if I want to open a zip file on my desktop , I'd type something like
"C:\Program Files\7-Zip\7zFM.exe" Desktop\zipfile.zip
that's when I'm currently at the my user's directory [by default] , or
"C:\Program Files\7-Zip\7zFM.exe" C:\Users\JiMMaR\Desktop\zipfile.zip
[where JiMMaR is my user name on windows 7]
note that this certain command works only on windows , if you are using another OS this won't work as it is
try doing a
fileNeededtoBeOpened = "\"C:\Program Files\7-Zip\7zFM.exe\" C:\Users\YOUR_USER_NAME\Desktop\zipfile.zip";
and see if that executes or not
edit:
if you cannot escape the space , then try this one
fileNeededtoBeOpened = "C:\Program~1\7-Zip\7zFM.exe C:\Users\YOUR_USER_NAME\Desktop\zipfile.zip";
Ok, firstly - system - is a function that starts a separate process to your program. Much the same as in a command window when you type the command. The command lines you provide will be dependent on the applications you want to launch.
Now, I was wondering if there was a way to open other type of files,
such as Microsoft Excel, Microsoft Word, Visual Studio, or 7zip.
Yes I would be pretty shocked if there wasn't a command line parameter you could specify to load a document in these apps at start up. (Ok not shocked, but it is pretty standard)
Does this have anything to do with c++ - not really - you need to look at references for the applications you mention and see what the command lines parameters are for them. Then craft a string and system(...) to your hearts content.
I'm teaching myself some Django tonight using the local dev package at instantdjango.com
I made it through half the tutorial, building a basic map with points on it, then closed out of the console for a bit. I just fired it back up and now when I try to use notepad++ to edit files, console tells me it doesn't recognize the command. What happened?
When I as working through the first half, I was able to type: "notepad++ filename.ext" and I'd get a text editor that would pop up.
Now when I type that, it doesn't recognize the command.
How do I get back the ability to use the text editor and how did I lose it?
In a windows terminal, you can launch notepad++ with the following:
start notepad++ <filename>
Note that the filename is optional.
Most likely the directory in which the Notepad++ executable resides is not in your system's PATH. For information about fixing this please see How to set the path in Windows 2000 / Windows XP.
If you are using gitbash or cygwin, you can create an alias
alias np='start notepad++'
And use
np myfile.txt
This is what I have done, in this way you dont have to type notepad++
Create np.bat file with this set of commands
#echo off
start "" "C:\Program Files (x86)\Notepad++\notepad++.exe" %*
place np.bat file in c:\Windows
open the command prompt and type np or np myfile.txt and enter.
One way is to make a change to this registry key:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\Notepad++.exe]
You can download a zipped .reg file from Donn Felker that lets you open a file with just an n shortcut.
I edited the .reg before running it and to make sure the path to Notepad++ is correct (e.g. C:\Program Files (x86)) and I also changed the shortcut to n instead of n.
Then double click to add to your registry.