How to open a file with a specific extension using Applescript - applescript-objc

I would like to know how do I open a file with a specific extension
Inside the downloads folder. I try this:
set downloads to "~/Downloads"
set fileExtension to ("pkg")
open every file of downloads whose name extension is fileExtension
I know I could use:
do shell script "open ~/Downloads/blabla.pkg"
and this would work fine but with every update the file changes its name and this would not be interesting to me.
thanks advance!

While do shell script can use a string for a path, AppleScript itself has limited file handling abilities, so you need to tell it to use something that does, such as the Finder or System Events. A file specifier (such as alias, file, or application scripting terms such as folder or disk item) also needs to be used to differentiate a file item from a regular string (such as a POSIX path). Depending on the application used, there may be other differences from the shell, such as tilde expansion, so the StandardAdditions scripting addition provides paths to common locations:
set fileExtension to ("pkg")
tell application "System Events"
repeat with anItem in (get every file of (path to downloads folder) whose name extension is fileExtension)
open anItem
end repeat
end tell
Also note that using the filter reference form “whose” only works with application objects, and not regular lists or records. AppleScriptObjC also has access to Cocoa methods, so you can use the NSWorkSpace or NSFileManager classes, although going that route tends to get a bit more verbose.

Related

std::filesystem::is_regular_file() vs ::exists()- what counts as a regular file

I am using Visual Studio 2017 C++ WITH MFC
I have a program in MFC that collects filepaths as strings and adds them to a zip file.
I want to add an error check, where I check if a file exists before trying to add it. If it exists, perfect, I add the file to the zip. If not, not a problem, I continue to the next filepath.
I came across std::filesystem (here) and I see two different functions that I think can work:
is_regular_file() (here) and exists() (here).
However, I am not sure which of the two to use. The file types I will be zipping vary from .txt to .zip, and a lot of arbitrary file types.
From my research, they appear to be similar, both returning a bool value.
What is the difference between the two functions and which is the better one to use?
Furthermore, from my understanding, the library is relatively new and might not be suitable for use in MFC. Is this true? And if so, what else could I use to check if given a file path, that file exists on the computer?
Thank you in advance ! :D
tl;dr: use std::filesystem::is_regular_file(), std::filesystem::is_symlink() and std::filesystem::is_directory().
There are several file types defined in std::filesystem:
Constant Meaning
none indicates that the file status has not been evaluated yet, or an error occurred when evaluating it
not_found indicates that the file was not found (this is not considered an error)
regular a regular file
directory a directory
symlink a symbolic link
block a block special file
character a character special file
fifo a FIFO (also known as pipe) file
socket a socket file
implementation-defined an additional implementation-defined constant for each additional file type supported by the implementation (e.g. MSVC STL defines junction for NTFS junctions)
unknown the file exists but its type could not be determined
So in first glance, std::filesystem::exists() would be what you want.
But you're adding files to a ZIP archive, and AFAICT, ZIP only supports regular files, symlinks, and directories, so that's what you should use.
You wouldn't archive sockets or NTFS junctions even if they existed and were given in command line.
To clarify:
A "regular file" is a file that has data that is (a) stored by the filesystem and (b) has no semantics assigned to it by the filesystem - i.e. the filesystem doesn't know how to read the file or act on it.
For example, a MS Word document is something that MS Word understand, but the filesystem only knows that it's a bunch of bytes.
A symlink, on the other hand, is something the filesystem stores, and knows how to act on (follow the link).
A block special file is something that is not actually stored by the filesystem, but rather just a piece of metadata that other parts of the OS act on.
A ZIP archive, or RAR, are files that the filesystem stores. But it doesn't know how to read them or act on them, so they are regular files.
In the old Windows Explorer, the "shortcuts" on your desktop were small files stored by the filesystem, but it was Explorer that knew how to read them - they weren't symbolic links, they were regular files. (Maybe that's still the case, I haven't checked recently.)

How to get real full path of a file or directory having one of its paths?

The same file system entry can be accessible in several paths.
real full path - /home/user/dir1/file1
path which contains parent dirs - /home/user/dir1/../dir1/file1
path with direct symlinks - /home/user/dir1/symlink_to_file1
path with indirect symlinks - /home/user/symlink_to_dir1/file1
...
I want two write a function which for given two paths will tell whether the file or directory specified by the second path is inside (including sub-directories) the directory specified by the first path.
I think the most obvious solution is to find real full paths of both file system entries then check whether the first real path is a prefix of the second. That is why the title of question is about finding real full paths.
NOTE: I want to write the function for both Windows and POSIX compatible systems.
NOTE: boost::filesystem cannot be used.
In Windows and Unix-land alike there is no single “real path”. In particular a file can have many different directory entries, called hardlinks, in Unix-land created via ln and in Windows 7 and later via mklink. But also, in Windows you can very simply define a local logical drive mapped to some directory, via the subst command, and drives mapped to file server directories via e.g. net use, and you can mount a drive as a directory, e.g. via the mountvol command.
However, the “real path” problem is just an imagined solution to the real problem, which is to establish whether a file or directory is inside a directory specified via a path.
For that, establish a system-specfic ID for the filesystem entity that you're searching for, and scan up the parent directory chain looking for that ID. Sorry, I misread the question. I can't think of any efficient way to do this, it sounds like brute force ID search through all possible directories, unless you can avail yourself of indexing information.
The question you need to know up front is this: How many ways are there to get to /path/to/filename? With symbolic links the answer is infinite (well, within the bound of the filesystem size). Any symbolic link anywhere on any portion of the filesystem could redirect to the file (or some portion of the path above the file). Even without considering hard links the search space must be the entire filesystem under /base/path/of/interest/ (which may be the entire filesystem).
Allowing symbolic links, and without further limitations, there is no non-brute-force method for establishing whether /path/to/filename is reachable within /base/path/of/interest/.

Xml file are saved in two different path

I created application that store some data to XML file. The issues is with the path of the XML saving. Am using TinyXML to save the data in vc++.
When I deploy this application, it installs in "C:\Program files(x86)\applicationname " and when I run the application the XML file is saving in
"C:\Users\UserName\AppData\Local\VirtualStore\Program Files (x86)\ApplicationName ".
I have made this application to work on system startup. So when I restart this application,
the xml file is stored in different path "C:\Users\UserName\AppData\Local\VirtualStore\windows\sysWOW64"
I want my XML to be stored in the path where I installed or should be stored in appdata, application name
What should I do to store XML file in one places where application is installed?
doc.SaveFile( "test.xml" ); // xml saving code in tinyxml library
Firstly, this has nothing to do with C++, as the C++ code is probably working. Same with XML and tinyxml and even visual-c++.
It seems that windows redirects those write accesses to a user-specific "VirtualStore\Program Files", but I'll leave it to you to research the actual semantics of that. On startup, when there is no user, this path obviously differs, since the former user is not logged in.
Now, in order to get a fixed path, you can use the function GetModuleFileName() to find out the location of your executable and use that path to locate Smartmeter.xml. However, the problem you are facing now is that programs installed under "Program Files" don't magically gain write access rights to their install directory. This is to protect one user from messing with data of another user.
I think that what you are doing is writing a program that runs in the background, which would be called a "service" under MS Windows. What is still unclear is what you want to achieve with this file and also what you are planning to do overall, and these are things that decide the future steps. In any case, take a look at the possibilities that services provide, maybe there is something that fits your needs.

Search a file with a zimage file extension in Qt

I am writing a program to upgrade a firmware using a flash drive. I need to upgrade the Kernel with the image present in the flash device. But I am not getting any idea of how to find a file with zimage file extension in a directory.
I am new to Qt and Linux. So I dont know whether it is possible to find the file with particular format. Can anyone help on this.
Thanks in advance.
There's no general way to access the OS search indexing services on the whole filesystem in Qt. So if that's what you want then an OS-specific solution like what #BЈовић offered would be necessary.
(Note: I actually tend to prefer it when a program makes me point explicitly to where something is, instead of searching the whole filesystem...but even better if it can notice when the necessary file is in the same directory as the executable.)
Anyway...if you know the directory you want to search in, then the QDir abstraction will let you set up a filter and enumerate filenames that match that filter in the directory:
QDir dir (zimagePath);
QStringList filters;
filters << "*.zimage";
foreach (QString file, dir.entryList(filters, QDir::Files)) {
// ...
}
You can read over the QDir docs for more ways of looking at it.
You can execute next script using system(), and parse the output :
#!/bin/bash
find / -name '*.zimage' | grep .zimage > /tmp/zimage_files.txt
Take a note that the above script is going to search all files and all paths, and put the output to /tmp/zimage_files.txt. If you need something different, you need to modify it a bit.

Opening a File with different text editors

Apparently this supposed to be possible. For example opening and operating on a file with NOTEPAD, or HxD. But aren't they all text files...how would one specify which text editor to open the file and operate on the file with using the WINDOWS API. It is certainly not in "CreateFile".
Hopefully I'm understanding your question... The easiest way to do this is to launch the desired editor and pass the filename as an argument, rather than "invoking" the file (which will launch the default program associated with the file type).
For example, notepad.exe mytextfile.txt or gvim.exe mytextfile.txt.
If the editor is not on your %PATH%, you'll need to use a full path file name.
What are you trying to do, exactly? You could:
Maintain a list of editors that you expect to be installed and have entries for in the system's PATH (bad idea)
Have an editor/editors that you want to use, query the Windows registry to find the installation path of the editors (using RegGetValue), and launch the editor with CreateProcess) (a little better idea)
Query the registry to get the default editor for a given file type and then launch that editor using CreateProcess. (best idea)
But it all depends on what your goal is really.
Edit based on requirements
So, just so we're on the same page, from C++, you want to:
Take a command line parameter to your C++ application (filename)
Open that file in an arbitrary editor
Detect when the user has made changes to that file
Operate on the file contents
Is that correct?
If so, you could:
Use Boost libs to compute a CRC for the current data in the file
Launch an editor using one of the methods I initially described
Stick in a tight loop and sleep so you don't chew up resources while the initially computed CRC matches one calculated every iteration of the loop
Of course, there are all kinds of issues that you'd have to deal with (that's just a super simple way of describing the algorithm I might use), such as:
What happens if the user doesn't change the file?
What happens if the file isn't found?
I'm sure that there are a number of different methods of doing this, but this is the easiest method that I can think of at the moment (while still being able to be fairly certain of the changes).
Disclaimer: I haven't implemented something like this, so I might be completely off base ;)
Are you looking for the ShellExecute() or ShellExecuteEx() APIs on Windows? They'll launch whatever program is registered for a file (generally based on the filename extention).