Working with files in Xamarin PCL project - xamarin

I want to store a JSON to the file system. Where should i store the files so that the user can't see/delete them and that the files won't be deleted after a phone reboot/restart?
ApplicationData The directory for application data specific to the user executing the program. On non-Windows operating systems, this
path is the value of the environment variable XDG_CONFIG_HOME if it is
set, otherwise the ".config" directory in the current user's home
directory.
CommonApplicationData The directory for data shared by applications. On non-Windows operating systems, the "/usr/share"
directory.
LocalApplicationData The directory for application data shared by users of the computer. On non-Windows operating systems, this path is
the value of the environment variable XDG_DATA_HOME if it is set,
otherwise the ".local/share" directory in the current user's home
directory.
Personal The personal or home directory for the current user. On non-Windows operating systems, this is the user's home directory.
Source: System.Environment.SpecialFolder
I don't understand what Personal is for exactly, but on most sites on the web i found people using it. Should i use one of these or am i looking at the wrong things?
And for storing at the moment (May 2017) my only two options are SQLite and PCLStorage.

You can use any of the below folders for your requirements. If I understood your questions correctly you want only the app to be able to access (create/updated/delete) certain files which should be preserved on phone reboot or restart and the user shouldn't be able to access the files. You can use any of the below special folders:
Environment.SpecialFolder.ApplicationData is $HOME/.config, which maps to /data/data/#PACKAGE_NAME#/files/.config.
Environment.SpecialFolder.LocalApplicationData is $HOME/.local/share, which maps to /data/data/#PACKAGE_NAME#/files/.local/share.
Environment.SpecialFolder.Personal is $HOME, which maps to /data/data/#PACKAGE_NAME#/files
Looking at the description and mapping to the file system, for saving a JSON file I would probably pick Environment.SpecialFolder.ApplicationData, but there seems to be nothing wrong in picking either of the three based on how they map in the file system.
Notice that all these paths are within the specific directory for your app package so no other apps will be able to access these files. And neither will you be able to access them from any file system (unless the phone is rooted).
If you want more information on any file path, you can iterate through them, like this:
static void PrintFolderPath(System.Environment.SpecialFolder folder)
{
Console.WriteLine ("{0}={1}", folder, System.Environment.GetFolderPath(folder));
}
More reading: https://forums.xamarin.com/discussion/3773/system-environment-specialfolder

Related

What are the Python 3 os commands to establish "writable data files and C-Drive paths" for a typical Windows 10 Application

What are the Python 3 os commands to establish "writable data files and C-Drive paths" for a typical Windows 10 Application. There are several parts to this question:
My Python 3 program creates (multiple) data files as part of it's purpose. When my MSI installer installs into /Programs, my Python executable does not have permission to create and write data files. Thus, the first part of my question is: Do I need to change my Python 3 program to create data files in a specific directory (using the os capabilities) and could you give me an example.
The second part of my question is simply: What os command options can assist me in discovering the windows 10 directories of a general Windows 10 PC (e.g. the home path, the AppData path, etc).
Note that I am cx_Freezing to an MSI installer, so everything must be automated for a typical remote install from a cloud (google drive or GitHub) by the MSI installer, so keep that in mind when answering 1 and 2 above.
Attention: Here is the MSI Installer for this program:
New WINDOWS 10 Contact Management Application.
https://drive.google.com/drive/folders/0Bz98wvqqw-1QRUNFcUJLU21yT1k
Thanks in advance for your programming knowledge and experience.
I appreciate your technical assistance and clarification.
I suggest that you avoid storing files and directories directly in the user's profile folder (i.e. the UserProfile environment variable) or home folder (i.e. "%HomeDrive%%HomePath%"). This differs from the common practice in Unix for a home directory (if we're ignoring the XDG base-directory spec), but when in Redmond, do as the Microsofties do.
Create a folder that's uniquely named for the application in one or more of the following locations: the local data folder (per-user), the roaming data folder (per-user), or the program data folder (per-machine). Note that these folders are hidden by default since generally users aren't meant to access them directly.
Use a local data folder for caches. Use a roaming data folder for stateful user data and configuration. Use a program data folder for data and caches that aren't specific to a user. For example, a program like pip could use the program data folder to cache downloaded packages. (In practice, pip caches packages per user, but in principle it could cache per machine.)
If your application uses a program data folder, make sure the folder grants all users permission to add and modify subfolders and files. If you create the folder lazily, you can add the permissions manually. See this answer for an example of how to modify file security.
The environment variables for the local, roaming, and program data folders are, respectively, LocalAppData, AppData and ProgramData. In Windows XP the latter is "%AllUsersProfile%\Application Data", and maybe "Application Data" is localized. Generally you shouldn't use these environment variables in an application.
Since most known/special folders are easily relocatable in Explorer, it's best to ask the shell for the current path by calling SHGetFolderPath or the newer SHGetKnownFolderPath function instead of using environment variables and default locations. You can use ctypes for this if you need to stay within Python's standard library. But it's easier to use PyWin32, which can be pip installed as the "pypiwin32" package.
Here are some Known Folder GUIDs for data, documents, and media files:
User System
ProgramData FOLDERID_ProgramData
Local FOLDERID_LocalAppData
Roaming FOLDERID_RoamingAppData
Desktop FOLDERID_Desktop FOLDERID_PublicDesktop
Documents FOLDERID_Documents FOLDERID_PublicDocuments
Downloads FOLDERID_Downloads FOLDERID_PublicDownloads
Music FOLDERID_Music FOLDERID_PublicMusic
Pictures FOLDERID_Pictures FOLDERID_PublicPictures
Videos FOLDERID_Videos FOLDERID_PublicVideos
Here are the corresponding CSIDL constants, except there isn't one for "Downloads":
User System
ProgramData CSIDL_COMMON_APPDATA
Local CSIDL_LOCAL_APPDATA
Roaming CSIDL_APPDATA
Desktop CSIDL_DESKTOP CSIDL_COMMON_DESKTOPDIRECTORY
Documents CSIDL_PERSONAL CSIDL_COMMON_DOCUMENTS
Music CSIDL_MYMUSIC CSIDL_COMMON_MUSIC
Pictures CSIDL_MYPICTURES CSIDL_COMMON_PICTURES
Videos CSIDL_MYVIDEO CSIDL_COMMON_VIDEO
SHGetKnownFolderPath isn't wrapped by PyWin32. I have another answer that calls it via ctypes. Alternatively, you can use PyWin32 to create a KnownFolderManager instance. For example:
import pythoncom
from win32com.shell import shell
kf_mgr = pythoncom.CoCreateInstance(shell.CLSID_KnownFolderManager, None,
pythoncom.CLSCTX_INPROC_SERVER, shell.IID_IKnownFolderManager)
downloads_path = kf_mgr.GetFolder(shell.FOLDERID_Downloads).GetPath()
Or call the legacy SHGetFolderPath function with a CSIDL constant. For example:
from win32com.shell import shell, shellcon
SHGFP_TYPE_CURRENT = 0
SHGFP_TYPE_DEFAULT = 1
local_data_path = shell.SHGetFolderPath(None, shellcon.CSIDL_LOCAL_APPDATA,
None, SHGFP_TYPE_CURRENT)

Why does %AppData% in windows 7 seemingly points to wrong folder?

The best way to find and get to AppData folder (specifically windows 7) is to type %AppData% in start command. But it takes me to C:\Users\user.name\AppData\Roaming
Why does it takes me to Roaming folder when the actual AppData Folder is one level up? It happens on both computers I have.
There is no environment variable for the root "AppData" folder because no one should ever put data there. Instead, applications put data into subfolders of the "AppData" folder depending on the nature of that data.
There are three subfolders:
Roaming
Local
LocalLow
The regular old %AppData% environment variable points to the path for the "Roaming" subfolder, which is where most applications should store their data, unless they have a specific reason that that data should not roam with the user's profile.
If you want the "Local" (non-roaming) sub-folder, use the %LocalAppData% environment variable instead.
As for typing this into the Start → Run dialog, that doesn't make a lot of sense to me. Data that is stored here is not intended for user consumption. It is private data stored by applications for their own use—things like configuration files, databases, etc. User-facing data should be in the Documents folder or at a path specified by the user. If you're a software developer accessing this folder for testing purposes, just go up one level.
Typing appdata (not %appdata%) in Run dialog (Win+R) takes you to %USERPROFILE%\AppData (i.e. %AppData%\..).

Directory location for writing cache file

Hi I am trying to find out what is the best location to save a cache file.
I have an Windows form application that updates user's data from the server using a custom tool.
I want to write the timestamp of the latest updates done on user's machine in the cache file.
Where is the best location for keeping this file:
1. in application directory (c:\program files..)
2. in a temp location e.g. Users profile folder or c:\windows\temp
3. in any location (e.g. c:\dataupdates) where user has full access to read/write to.
Not in the application directory. That much is clear. :) The application directory shouldn't even be writable by the program (or actually by the user account that runs the program). Although some applications still use this location, it has actually been deprecated since Windows 95, I believe, and it has become a real pain since the more rigid UAC applied in Windows Vista and 7.
So the most obvious options are:
The temp folder, which is for temporary files. Note however, that you will need to clean those files up. Temp folder is not automatically cleared by default, so adding new files all the time will consume increasingly much space on the hard drive. On the other hand, some users do clear their temp folders, or may have scripts installed that do that for them, so you cannot trust such files to remain. Also, this is not always C:\Temp of whatever. You'll have to ask Windows what the location is.
You can pick 'any' location. Note that you cannot write anywhere. You cannot even expect the C drive to exist. If you choose this, then you have to make it a configurable setting.
The %app data% directory, my personal favorite, which is a special directory for applications to store their data in. The advantage is, that you can ask Windows for this location, and you can make up a relative path based on that directory, so you don't really have to make it an application setting. For more info on how to get it, see also this question: C# getting the path of %AppData%
I would definitely choose the App Data path for this purpose.

Where do I store reports created by my application on OSX

My application stores logs in /Users/username/Library/Logs/appname and preferences in /Users/username/Library/Preferences/appname but where I should store the reports it creates.
Originally they were in Logs, but they are not really logs. I then thought about putting them in /Users/username/Library/Reports/appname but the Reports folder does not exist under Library and it seems bad practise to create additional folders at this level.
What is the correct mac-friendly way to do things ?
A good candidate would be your app's folder in ~/Library/Application Support/
You may need to create it, and you should really use the bundle identifier for your app as the folder name.
~/Library/Application Support/com.bundleIdentifier.something/
In there you can create whatever you need to to support your app.
File System Programming Guide
Important: The files in the user’s Documents and Desktop directories
should reflect only the documents that the user created and works with
directly. Similarly, the media directories should contain only the
user’s media files. Those directories must never be used to store data
files that your app creates and manages automatically. If you need a
place to store automatically generated files, use the Library
directory, which is designated specifically for that purpose. For
information on where to put files in the Library directory, see “The
Library Directory Stores App-Specific Files.”
Application Support Use this directory to store all app data files except those associated with the user’s documents. For example, you
might use this directory to store app-created data files,
configuration files, templates, or other fixed or modifiable resources
that are managed by the app. An app might use this directory to store
a modifiable copy of resources contained initially in the app’s
bundle. A game might use this directory to store new levels purchased
by the user and downloaded from a server. All content in this
directory should be placed in a custom subdirectory whose name is that
of your app’s bundle identifier or your company. In iOS, the contents
of this directory are backed up by iTunes.
As far as I figured, those are reports that are the end result of the app itself and are something the user needs to have access to.
Even more so, the reports are HTML (so a valid recognizable format)?
I think that constitutes them as documents.
I would put a folder in documents named after the app and put the reports there.
A lot of apps do that (Office comes to mind at the moment).

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.

Resources