I'm new to building application on Mac. I have global data that I need to share between users and not sure where to store this data on Mac to avoid permissions issues when reading and writing files.
On Windows I have stored it in /ProgramData/ in the past.
Changeable goes in /Library/Application Support/application-name however note you will need to ask for an admin username and password.
If the data is never change or only at install then it can be held inside the Application bundle.
Read all about this in the Apple docs
Related
I have a macOS application should be registered for all users on that physical machine. I'm currently using nsuserdefaults to store the registration info, but this prevents other users of the machine from using the software, because nsuserdefaults is user-specific.
I've looked into using the CFPreferences API:
CFPreferencesSetValue(key,
value,
kCFPreferencesCurrentApplication,
kCFPreferencesAnyUser,
kCFPreferencesCurrentHost);
But that requires root privileges, which I do not want to require for my application.
What is the best way to store registration info for all users of a machine, without requiring root privileges?
What I do is to create a folder in /Library/Application Support that anyone can write to in the postinstall script in my installer package. Then the application can do whatever it likes in that folder and in fact, like you, I use it primarily to store registration information.
The folder should be named as your application's bundle ID and your installer package needs to be set to run as root so that postinstall can create the folder in the first place.
If you don't yet have an installer package, you will have to make one. For this, I recommend Packages. Avoid Apple's Package Maker tool - it's terrible.
I'm developing a Windows Universal App, I need to share a database for all the users' account existing on pc.
Is it possible? What's the best solution?
Thanks
In Universal Apps the app data is stored in an app data store. When an app is installed, the system gives it its own per-user data stores for settings and files. So what you are asking is not possible using the native app data APIs.
Also note:
The system preserves the contents of these data stores when the user
installs an update to your app and removes the contents of these data
stores completely and cleanly when your app is uninstalled.
Source: Store and retrieve settings and other app data
I have a windows application getting ported for Mac.In windows i store encrypted data in the registry.But when it comes to Mac im unfamiliar.
The application is licensed per PC.So all Users using the Machine will be able to use it.So in windows im storing the key in HKEY\LOCAL MACHINE
How does user access rights work in Mac? Where do i need to store the data?
This type of data is usually stored in a file in Application Support directory. If you want to store one file for all users you should choose /Library/Application Support system directory.
The directory is not user-writable, so you will have to run installer with root privileges. This directory can't be used by sandboxed apps.
You should create a subfolder in this directory and store your file inside.
For more information see The Mac Application Environment, especially Table 1-1, "Key directories for Mac apps", and File System Basics.
Edit:
Usually OS X apps don't need any installation. They are self-contained bundles that can be run from any location. Usually you keep them in Applications folder (drag it there). System wide /Applications folder is accessible for all users. There is also private ~/Applications folder in each user's home.
On the other hand apps that need to install data to system folders use installers. Installer usually copies application bundle to /Applications folder, but also handles authentication and asks user for admin credentials. Installers may also run scripts.
Maybe your license could be generated by a script during installation?
If not, you would have to generate license file on first application run. In such case, if you want to keep one file for all users in /Library/Application Support, you will have to escalate privileges and ask user for admin access. If you don't want to do that, consider storing separate license file for each user in their home ~/Library/Application Support folder.
I am using C# with .net 2.0
I am saving my program data in a file under: C:\ProgramData\MyProgramName\fileName.xml
After installing and running my application one time I uninstalled it (during uninstallation I'm removing all the files from "program data") and then I reinstall the application, and ran it.
The strange thing is that my application started as if the files in program data existed - means, I had old data in my app even though the data file was deleted.
When running:
File.Exists("C:\ProgramData\MyProgramName\fileName.xml")
I got "true" even though I knew for sure that the file does not exist.
The thing became stranger when I ran the application as admin and then the file didn't exist.
After a research, I found out that when running my application with no admin privileges instead of getting:
C:\ProgramData\MyProgramName\fileName.xml
I get
C:\Users\userName\AppData\Local\VirtualStore\ProgramData\MyProgramName\fileName.xml
and indeed there was a file that existed from the previous installation (that I obviously didn't delete, because I didn't know it existed).
So just guide me how could I stop this when apps running with no admin right.
I do not want to create any file automatically in VirtualStore folder. Please discuss all the possible ways to stop this.
First, ask yourself, do this need to be globally saved for all users?
If it doesn't have to be, save the file in Application Data instead, you can get the path with Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), it should always reliably expand to C:\Users\Username\AppData\Roaming\. Do note that this path is unique for each user though.
If you have to, you're out of luck. There is no reliable way to store application data for all users without admin rights (or UAC) on any Windows post-XP that's not extremely hacky, like storing your data in the Public user (which may or may not be possible, I can't check right now).
An approach to solving this is to use the Environment.SpecialFolder.CommonApplicationData location, but with some very important caveats & setup.
CommonApplicationData is
The directory that serves as a common repository for
application-specific data that is used by all users.
This location is described further here and here.
Important requirements and restrictions are given in another SO answer: https://stackoverflow.com/a/22107884/3195477
which said in part:
The recommended solution is for your installer to create a sub
directory of C:\ProgramData for your shared storage. And that sub
directory must be given a permissive ACL by the installation program.
That is what grants the desired access to all standard users.
Otherwise the program running with standard user permission will still not be all equally able to read/write files in that location for all users.
I found a work around for this issue when transferring a very old win32 app to windows 7 & 10. The program wrote to a database on C:\Program Files... but the OS auto changed the path to virtual store. However the database was required globally. By changing compatablilty mode to Windows 95 or XP SP2 and always running as administrator the database was worked on directly in C:\Program Files\etc.
There are security implications for this and the box was removed from all networks and adapters disabled etc.
I'm writing a desktop app and need a folder which...
Exists in Windows 7 and Vista
Is common to all users (for store config data).
Application can save data on it, without Admin privileges (not like "ProgramData").
is standard (I don't want to create another app specific folder in "C:", the Desktop or other place alike.)
"Program Files" is not an option, of course.
Can you suggest an appropriate folder, or better use the Registry?
The recommended way to do this is to create a folder at install time, dedicated to your application, underneath "ProgramData" (i.e. CSIDL_COMMON_APPDATA/FOLDERID_ProgramData).
As you already know, the CSIDL_COMMON_APPDATA folder is read only for standard users. So your install program needs to give the folder that it creates an ACL that permits the access that you require.
This is the solution that meets all the criteria laid out in your bullet points.
You mention the registry. There is no area of the registry that is shared between all users and yet writeable by standard users. Whilst you can use ACLs to grant more permissive access rights to the registry, it is really not the done thing. Please forget that I even mentioned this possibility!
IF your app is .NET then use CommonApplicationData - you can get the real location by calling GetFolderPath.
EDIT - as per comments:
You need to setup ACL correctly - for sample source code on how to do this see http://www.codeproject.com/Tips/61987/Allow-write-modify-access-to-CommonApplicationData
What about Public User directories? For Example: C:\Users\Public\Libraries or C:\Users\Public\Documents
I've noticed these folder on several of my Windows 7 machines. I'm not sure if it is always there, but might be an option. I was hoping for something like an %appdata% for the Public User, but the closest thing I found was Public\Libraries.
(As a side note, it appears C:\Users\Public\Desktop does require admin to write to.)
what about using %APPDATA%/Company/Product for the directory?