Allowing a Macintosh application to write files - macos

We market an application that runs on multiple platforms, including Macintosh. On the Macintosh the software gets packaged into a .dmg file, and when installed everything goes into the /Applications hierarchy.
Some of the files in our application's hierarchy are samples that users are supposed to be able to modify in place or copy to different files in the same directory. The problem is the permissions that seem to get applied within the /Applications hierarchy prevent our application from doing such operations.
So I either need to change the install so the directories and files in question within /Applications allow modification, or I need to segregate the sample files to a different location on the disk where they can be modified.
I've tried making sure the permissions on the files allow writing at the time the .dmg file is pulled together, but then when the product is installed the permissions get changed to more restrictive ones that don't allow file modification or copying.
I've been able to modify the packaging so the sample files get installed to a different location, but so far I haven't been able to find a suitable area on the Macintosh disk to put them so modification is allowed. I haven't been able to figure out how to tell the packaging that these sample files should be installed into the installer's home directory.
Anyone have any suggestions? I'm afraid I'm a bit of an Apple novice. The procedure to build the .dmg file employs a Makefile that invokes commands like pkgbuild and productbuild. The productbuild command uses a --distribution qualifier that references a .xml file. There don't seem to be any scripts invoked.

Related

Windows equivalent of a MacOS.app with a contents directory

This may sound like I'm just looking for a .exe file, but I'm not all that familiar with windows. I have been using pyinstaller to turn my apps into binaries. My app relies on a lot data directories and third party binaries that I package within the same directory as the executable binary. For Mac, this makes things easy because the user only has to click on MyApp.app inside the applications directory which is like a link to MyApp.app/Contents/MacOs/MyApp. This way MyApp never has to be touched and is all bundled together with the data directories (also loaded inside of MyApp.app/Contents/MacOs/).
However, I can't really find a windows equivalent. While Pyinstaller can create a directory with my data directories and executable inside of it, if the user ever moves the .exe file inside the directory, the app will never work (because it loses its relative location to the data directories). Is there such a thing that can package this directory like on MacOS so the user just has to click on a single .exe file that links to the .exe inside the directory packaged within it? That way we can just pass around one directory. Like a Mac.app?
Win32 apps store data within the executable file as resources, which allows the single file solution, but they can't be accessed using normal file APIs, there are a separate set of functions for resource handling. (This implies that resources aren't so useful for things that absolutely have to be files, like images of helper executables.)
Win32 also has alternate data streams, which are more similar to what you're used to with .app packages, separating a local identifier from the actual filename by $DATA:. But those only work on NTFS, get lost by many file management applications, never have been very popular, and are now effectively deprecated by Microsoft (by preventing access from Windows Store apps).

Deploy multiple apps with "shared private" Qt frameworks on OS X

I have a set of applications that work together. It should be possible to start each of these applications individually by the user (i.e. one application provides a monitoring feature, another a configuration feature etc), therefore I would like them to show up in the Applications folder as different applications (possibly within a directory).
The applications are based on Qt5, so I would like to package Qt along with the applications privately to ensure that Qt is present and available. On the other hand I would like to make sure that I only include a single copy of Qt to avoid bloating the system.
I am using a package installer, due to the inclusion of a LaunchDaemon as well.
How do I place the Qt frameworks needed in order to avoid having multiple copies?
Here's the naive way:
/Applications/
MyCompany/
Foo.app/
Contents/
Info.plist (must use its own plist to specify some properties)
MacOS/
foo
Frameworks/
Qt-Goes-Here??
Bar.app/
Contents/
Info.plist
MacOS/
bar
Frameworks/
Qt-Goes-Here?? - Or can this be a link to the other location?
Since I am not a Mac-guru, any input (including informing me that I am trying something stupid) is very welcome!
There are two possibilities here, the first is
/Library
and the second
/Library/Application Support
If you look there, you'll find folders with contents for various applications. You should be able to create a folder there and add the Qt Framework, then update your applications to point to that using install_name_tool
The docs state the following for /Library: -
The Library directory is the top-level directory for storing private
app-related data and preferences. There are several Library
directories scattered throughout the system but you should always use
the one located inside the current home directory. Do not store files
directly at the top-level of the Library directory. Instead, store
them in one of the specific subdirectories described in this table. In
OS X v10.7 and later, the Finder hides the Library directory in the
user’s home folder by default. Therefore, you should never store files
in this directory that you want the user to access. To get the path to
this directory use the NSLibraryDirectory search path key with the
NSUserDomainMask domain.
For /Library/Application Support: -
The Application Support directory is where your app stores any type of
file that supports the app but is not required for the app to run,
such as document templates or configuration files. The files should be
app-specific but should never store user data. This directory is
located inside the Library directory. Never store files at the top
level of this directory: Always put them in a subdirectory named for
your app or company. If the resources apply to all users on the
system, such as document templates, place them in /Library/Application
Support. To get the path to this directory use the
NSApplicationSupportDirectory search path key with the
NSLocalDomainMask domain. If the resources are user-specific, such as
workspace configuration files, place them in the current user’s
~/Library/Application Support directory. To get the path to this
directory use the NSApplicationSupportDirectory search path key with
the NSUserDomainMask domain.
The full documentation can be found here.

How to make WIX create files to Program Files folder in the installation? I have "Access defined"

I am creating a WIX installer project. During one managed customized action, I need to create a file (other than the deployed files specified in the components of WIX) in the installation folder, which by default is the Program Files folder. I am experiencing the "Access denied" problem in Windows 7. After some searching, I found out that people say it is not advisable to create files into Program Files folder. Instead, try to create files into for example AppData folder. For example, see this link:
C# Access denied to path in a Windows Application
But my question is, the generated file is crucial to our SW, so it must reside in the installation folder. Isn't it the target of SW installation, I mean, to create file in most of the cases Program Files folder? Does it mean the only files should be added into installation folder, during the installation, are the deployed files (basically the targets of XCopy)?
My file can't be made deploy-able in the WIX, i.e, it can't be made ready before the installation. So what's the proper way or best practice to handle such situation: a file must be generated during the installation, into the installation folder. It is not some log file that I can put somewhere else. I tried to create a Permission element in WIX for the INSTALLADIR, although it seems to be against the rule mentioned in the link, but it still failed. Thanks!
UPDATE:
Based one MichaelUrman's commen, some more information. The generated file is needed after the SW is installed and necessary during normal launch of the SW. And I think it needs to be modified during normal use after the installation. And as I mentioned my a comment to #caveman_dick answer, my CA is actually in commit phase, I don't know whether there is any difference between it and normal deferred CA
Set the custom action to Execute="deferred", that will run the command elevated and should give it the required permissions to create the file.
Since you need to update that file from the main application, and I'm assuming your application does not require elevated privileges, you have three options.
The first is the worst: without a manifest, your executable's attempts to write to the Program Files folder will typically result in it being redirected to the Virtual Store (see File Virtualization). It sounds like this isn't happening in your case, so you can't use it.
The second option is to modify the application to store this in an appropriate location such as the ProgramData folder, or Common Documents, or (if appropriate) a per-user location under LocalAppData. This is typically the best approach, but has the highest development costs.
Finally the third option is to create the file and change its permissions (or in some cases to change the permissions on the folder containing the file), allowing limited users to modify this file. See LockPermissions or MsiLockPermissionsEx for the Windows Installer way to approach this. Change the permissions on as few files or folders, as restricted as possible, to keep the system as safe as possible if you go with this option.

Application permission issues on OS X, when distributing application

we are making an Application for OS X, however, when the .app is copied on another MAC, we have problems with reading and writing files
on one MAC, everything works great from the start...
the other one will not write certain files and another 2mac will not write certain different files
if i go to show application contents and wants to edit the file by myself, i get a writing permission denied
how to distribute an MAC application so there are no such issues? so all files can be read and write by the current user
does there have to be some authorization or code sign, or smth. different in this form, in addition to normal code?
thank you
It sounds like your application tries to write files within its own application bundle. The correct solution here is: DON'T DO THAT! The only time your application bundle should be written to is when it's installed or updated.
Files that the application needs to write to should be stored in the user's home folder, generally under ~/Library. See this note in Apple's dev docs.
Preference and settings files in ~/Library/Preferences/<appbundleid>.plist; use NSUserDefaults.
Data the app manages for the user in ~/Library/Application Support/<appname> (the docs say to use the bundleid, but everyone -- Apple included -- uses the app name instead).
Cache files in ~/Library/Caches/<appbundleid>.
Temp files, use NSTemporaryDirectory
If you need to share settings & files between users, that should generally go in /Library/Application Support/<appname>, except that you really shouldn't be doing that at all.
In the past I've always used PackageMaker to create installers. An installation package can authenticate with root privileges so you can set permissions after the install. I don't have it in front of me right now but if you look around you should be able to see a Post-Installer script line. Write a shell script that manually sets the permissions of each file you have in question and then have the package execute that script after the install is finished.
You can find PackageMaker at /Developer/Applications/Utilities/PackageMaker

How to design software for Linux in relation to Windows?

I have an application that I've written for Windows which I am porting to Linux (Ubuntu to be specific). The problem is that I have always just used Linux, never really developed for it. More specifically, I dont understand the fundamental layout of the system. For example, where should I install my software? I want it to be accessible to all users, but I need write permission to the area to edit my data files. Furthermore, how can I determine in a programmatic way, where the software was installed (not simply where its being called from)? In windows, I use the registry to locate my configuration file which has all of the relevant information, but there is no registry in Linux. Thanks!
The Filesystem Hierarchy Standard (misnamed -- it is not a standard) will be very helpful to you; it clearly describes administrator preferences for where data should live.
Since you're first packaging your software, I'd like to recommend doing very little. Debian, Ubuntu, Red Hat, SuSE, Mandriva, Arch, Annvix, Openwall, PLD, etc., all have their own little idiosyncrasies about how software should be best packaged.
Building
Your best bet is to provide a source tarball that builds and hope users or packagers for those distributions pick it up and package it for you. Users will probably be fine with downloading a tarball, unpacking, compiling, and installing.
For building your software, make(1) is the usual standard. Other tools exists, but this one is available everywhere, and pretty reasonable. (Even if the syntax is cranky.) Users will expect to be able to run: make ; make install or ./configure ; make ; make install to build and install your software into /usr/local by default. (./configure is part of the autotools toolchain; especially nice for providing ./configure --prefix=/opt/foo to allow users to change where the software gets installed with one command line parameter. I'd try to avoid the autotools as far as you can, but at some point, it is easier to write portable software with them than without them.)
Packaging
If you really do want to provide one-stop-packaging, then the Debian Policy Manual will provide the canonical rules for how to package your software. The Debian New Maintainers Guide will provide a kinder, gentler, walkthrough of the tools unique to building packages for Debian and Debian-derived systems.
Ubuntu's Packaging Guide may have details specific to Ubuntu. (I haven't read it yet.)
Configuration
When it comes to your application's configuration file, typically a file is stored in /etc/<foo> where <foo> represents the program / package. See /etc/resolv.conf for details on name resolution, /etc/fstab for a list of devices that contain filesystems and where to mount them, /etc/sudoers for the sudo(8) configuration, /etc/apt/ for the apt(8) package management system, etc.
Sometimes applications also provide per-user configuration; those config files are often stored in ~/.foorc or ~/.foo/, in case an entire directory is more useful than a file. (See ~/.vim/, ~/.mozilla/, ~/.profile, etc.)
If you also wanted to provide a -c <filename> command line option to tell your program to use a non-standard configuration file, that sometimes comes in real handy. (Especially if your users can run foo -c /dev/null to start up with completely default configuration.)
Data files
Users will store their data in their home directory. You don't need to do anything about this; just be sure to start your directory navigation boxes with getenv("HOME") or load your configuration files via sprintf(config_dir, "%s/%s/config", getenv("HOME"), ".application"); or something similar. (They won't have permissions to write anywhere but their home directory and /tmp/ at most sites.)
Sometimes all the data can be stored in a hidden file or directory; ssh(1) for example, keeps all its data in ~/.ssh/. Typically, users want the default kry name from ssh-keygen(1) so ssh-agent(1) can find the key with the minimum of fuss. (It uses ~/.ssh/id_rsa by default.) The shotwell(1) photo manager provides a managed experience, similar to iPhoto.app from Apple. It lets users choose a starting directory, but otherwise organizes files and directories within as it sees fit.
If your application is a general purpose program, you'll probably let your users select their own filenames. If they want to store data directly to a memory stick mounted in /dev or /media or a remote filesystem mounted into /automount/blah, their home directories, a /srv/ directory for content served on the machine, or /tmp/, let them. It's up to users to pick reasonable filenames and directories for their data. It is up to users to have proper permissions already. (Don't try to provide mechanisms for users to write in locations they don't have privileges.)
Application file installation and ownership
There are two common ways to install an application on a Linux system:
The administrator installs it once, for everyone. This is usual. The programs are owned by root or bin or adm or some similar account. The programs run as whichever user executes them, so they get the user's privileges for creating and reading files. If they are packaged with distribution packaging files, executables will typically live in /usr/bin/, libraries in /usr/lib/, and non-object-files (images, schemas, etc.) will live in /usr/share/. (/bin/ and /lib/ are for applications needed at early boot or for rescue environments. /usr might be common to all machines in a network, mounted read-only late in the boot up process.) (See the FHS for full details.)
If the programs are unpackaged, then /usr/local/ will be the starting point: /usr/local/bin/, /usr/local/lib/, /usr/local/share/, etc. Some administrators prefer /opt/.
Users install applications into their home directory. This is less common, but many users will have a ~/bin/ directory where they store shell scripts or programs they write, or link in programs from a ~/Local/<foo>/ directory. (There is nothing magic about that name. It was just the first thing I thought of years ago. Others choose other names.) This is where ./configure --prefix=~/Local/blah pays for itself.)
In Linux, everything is text i.e. ASCII.
Configuration is stored in configuration files which normally have .conf extension and stored in /etc folder.
The executable of your application normally resides in /usr/bin folder. The data files of your application can go to /usr/lib or folder in /usr/ folder.
It is important to consider which language you are writing your application in. In C/C++ a custom makefile is used to do installation which copies these files in respective folders. The location of installation can be tracked by tracking the .conf file and storing the location while generation using bash script.
You should really know bash scripting in order to automate this everything.

Resources