Open extern SQLite-Database in a Windows 8 Metro-App? - c#

I use the "Sqlite for Windows Runtime" and sqlite-net (just as described at http://timheuer.com/blog/archive/2012/08/07/updated-how-to-using-sqlite-from-windows-store-apps.aspx) to develop a Windows 8 Metro-App, just . If I want to open a Database at the Program-Directory is no problem:
var dbPath = Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "db.sqlite");
using (var db = new SQLite.SQLiteConnection(dbPath)) {
...
}
But when I want to use an extern Path like this:
var dbPath = "C:\\Users\\xxxxxx\\db.sqlite";
then an error occurs with "Cannot open database file". Why? Here I am using C#, normally I use C++, but for this problem I am sure it doesn't matter ;)

You cannot select arbitrary files on the file system. See here for details.
By default you can access these locations:
Application install directory
Application data locations
User’s Downloads folder
and
Additionally, your app can access some of the files on connected
devices by default. This is an option if your app uses the AutoPlay Device extension to launch automatically when users connect a device,
like a camera or USB thumb drive, to their system. The files your app
can access are limited to specific file types that are specified via
File Type Association declarations in your app manifest. Of course,
you can also gain access to files and folders on a removable device by
calling the file picker (using FileOpenPicker and FolderPicker) and
letting the user pick files and folders for your app to access. Learn
how to use the file picker in Quickstart: Accessing files with file pickers.
If you have the right capabilities declared you can also access:
Documents Library
Music Library
Picture Library
Videos Library
Homegroup Library
Removable devices
Media server devices (DLNA)
Universal Naming Convention (UNC) folders
A combination of the following capabilities is needed.
The home and work networks capability:
PrivateNetworkClientServer
And at least one internet and public networks capability:
InternetClient InternetClientServer
And, if applicable, the domain credentials capability:
EnterpriseAuthentication
Note You must add File Type Associations to your app manifest that declare specific file types that your app can access in this location.

In windows metro application...
It support only sandbox property of an application.
So you cant use
var dbPath = "C:\\Users\\xxxxxx\\db.sqlite";
U can only store data in local storage or application installed directory.
Please avoid to use any other path . it will not work .

Related

CommonApplicationData folder read-only after using MSIX Packaging Tool

I have written a .Net Windows Forms application that uses the common application data folder to store logfiles and user accounts. The application is distributed using an install shield project and runs perfect on all different Windows versions.
Some parts of the code from different files is shown below
// Defining the path to use (in ProductInfo class)
public static string CommonApplicationDataPath
{
get
{
string path = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
path = StringHelper.EnsureEndsWithSlash(path);
path += Vendor + #"\" + ProductName + #"\";
return path;
}
}
// Configuring the logger and user manager instances at startup
Logger.Configure(string.Empty, ProductInfo.Password, ProductInfo.CommonApplicationDataPath);
UserManager.Configure(User.Empty, ProductInfo.Password, ProductInfo.CommonApplicationDataPath,
ProductInfo.UserLimitCount);
// Example method for saving the users to file (in UserManager class)
public bool SaveUsers(AppUsers appUsers)
{
AppUsersSerializer serializer = new AppUsersSerializer(_password, _fileName);
if (serializer.Serialize(appUsers) == true)
{
return true;
}
else
{
Logger.Instance.Log(Logs.ErrorB.UserSave, _fileName);
return false;
}
}
I would now like to publish the application via Windows Store and have used the MSIX Packaging Tool. To sign the package I have created a self signed certificate and added it to the Trusted Root Certificate Authorities. The .msix package is install on the same PC as my old desktop version of the app.
The problem I have is that the application is not able to write to the files located in the CommonApplicationData folder. The application can read and load the data, but not update and write the changes to the files. Thus, the path to the files is correct, but some write permission seems to be missing. I have tried different capabilities on the package and even ticked all, but without any effect.
I have also browsed to the C:\Program Files\WindowsApps\<my app package>\ folder and checked the structure of the application and located the files. They are there, but only readable for the app. Removing the files will not create new ones when they should be added as done in the old desktop Windows Forms version.
The application is quite big and contains lots of functionality which runs great in the Windows Store app context. The only missing piece is the above mentioned issues with the file writing.
Any advice would be really appreciated.
After some continued searching on different websites I came across a viable solution for my issue.
The Microsoft MSDN blog described how to use the different folders in an appropriate way.
http://blogs.msdn.microsoft.com/appconsult/2017/03/06/handling-data-in-a-converted-desktop-app-with-the-desktop-bridge/
The proposed solution is to change:
string path = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
to:
string path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
It will place the files in the user's local directory, meaning the data will be available only for the current user. Sharing the same log file and user accounts between different users of the application, will thus not be possible but that is ok for now.
You may also need to make sure that the folder exists:
C:\Users\<user>\AppData\Local\<vendor>\<product> because it might not always be created during installation of your application. It depends if it has user specific settings or not.
CommonApplicationData folder read-only after using MSIX Packaging Tool
If you have converted your app to store app, we could regard it as UWP app, In general, we store the user info with LocalSettings class that could keep the data during the app updating.
var localSettings = Windows.Storage.ApplicationData.Current.LocalSettings;
// Create a simple setting.
localSettings.Values["exampleSetting"] = "Hello Windows";
// Read data from a simple setting.
Object value = localSettings.Values["exampleSetting"];
if (value == null)
{
// No data.
}
else
{
// Access data in value.
}
// Delete a simple setting.
localSettings.Values.Remove("exampleSetting");
For more detail, please refer Store and retrieve settings and other app data

C# UWP using System.IO.Directory return empty array?

i am trying to return all the files contain in a folder in UWP application for Windows 10, the code is shown below:
var path = #"C:\Users\Desktop";
var files = System.IO.Directory.GetFiles(path); //get empty arrays
But, i get empty string arrays, may I know what causes this problem?
You can't. For uwp and store apps, only the app installation and app temp folders are granted for direct access. 'Direct' means ... accesses without Windows.Storge broker process. (System.IO is 'direct'.)
If you want to access the 'outside' of your app - like as desktop, you need to ask user to pick the location by File/FolderPicker. Without the user interaction, you can't access.
However, Windows.Storage broker service provide the rich methods for file operation, and additional functions like as CommnonQuery features.
There are some exception for pictures, video folders, but the basic concept is same.
Following link may helps you. :)
File access permissions
Probably because C:\Users\Desktop doesn't exist on the system - it would be under C:\Users\YOUR_USERNAME\Desktop.
Additionally, your application might be operating in a sandbox, so all filesystem access will be virtualized to a private silo elsewhere - Windows would pretend that the directory you specified exists but says it's empty, because it doesn't want you accessing the user's files without prior permission.

Windows 10 Universal App File/Directory Access

I´m developing an app that is reading jpeg and pdf files from a configurable location on the filesystem.
Currently there is a running version implemented in WPF and now I´m trying to move to the new Windows Universal apps.
The following code works fine with WPF:
public IList<string> GetFilesByNumber(string path, string number)
{
if (string.IsNullOrWhiteSpace(path))
throw new ArgumentNullException(nameof(path));
if (string.IsNullOrWhiteSpace(number))
throw new ArgumentNullException(nameof(number));
if (!Directory.Exists(path))
throw new DirectoryNotFoundException(path);
var files = Directory.GetFiles(path, "*" + number + "*",
SearchOption.AllDirectories);
if (files == null || files.Length == 0)
return null;
return files;
}
With using Universal Apps I ran into some problems:
Directory.Exists is not available
How can I read from directories outside of my app storage?
To read from an other directory outside the app storage I tried the following:
StorageFolder folder = StorageFolder.GetFolderFromPathAsync("D:\\texts\\");
var fileTypeFilter = new string[] { ".pdf", ".jpg" };
QueryOptions queryOptions = new QueryOptions(CommonFileQuery.OrderBySearchRank, fileTypeFilter);
queryOptions.UserSearchFilter = "142";
StorageFileQueryResult queryResult = folder.CreateFileQueryWithOptions(queryOptions);
IReadOnlyList<StorageFile> files = queryResult.GetFilesAsync().GetResults();
The thing is: It isn´t working, but I get an exception:
An exception of type 'System.UnauthorizedAccessException' occurred in TextManager.Universal.DataAccess.dll but was not handled in user code
Additional information: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
I know that you have to configure some permissions in the manifest, but I can´t find one suitable for filesystem IO operations...
Did someone also have such problems/a possible solution?
Solution:
From the solutions that #Rico Suter gave me, I chosed the FutureAccessList in combination with the FolderPicker. It is also possible to access the entry with the Token after the program was restarted.
I can also recommend you the UX Guidlines and this Github sample.
Thank you very much!
In UWP apps, you can only access the following files and folders:
Directories which are declared in the manifest file (e.g. Documents, Pictures, Videos folder)
Directories and files which the user manually selected with the FileOpenPicker or FolderPicker
Files from the FutureAccessList or MostRecentlyUsedList
Files which are opened with a file extension association or via sharing
If you need access to all files in D:\, the user must manually pick the D:\ drive using the FolderPicker, then you have access to everything in this drive...
UPDATE:
Windows 10 build 17134 (2018 April Update, version 1803) added additional file system access capabilities for UWP apps:
Any UWP app (either a regular windowed app or a console app) that declares an AppExecutionAlias is now granted implicit access to the files and folders in the current working directory and downward, when it’s activated from a command line. The current working directory is from whatever file-system location the user chooses to execute your AppExecutionAlias.
The new broadFileSystemAccess capability grants apps the same access to the file system as the user who is currently running the app without file-picker style prompts. This access can be set in the manifest in the following manner:
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
...
IgnorableNamespaces="uap mp uap5 rescap">
...
<Capabilities>
<rescap:Capability Name="broadFileSystemAccess" />
</Capabilities>
These changes and their intention are discussed at length in the MSDN Magazine article titled Universal Windows Platform - Closing UWP-Win32 Gaps. The articles notes the following:
If you declare any restricted capability, this triggers additional
scrutiny at the time you submit your package to the Store for
publication. ... You don’t need an AppExecutionAlias if you have this
capability. Because this is such a powerful feature, Microsoft will
grant the capability only if the app developer provides compelling
reasons for the request, a description of how this will be used, and
an explanation of how this benefits the user.
further:
If you declare the broadFileSystemAccess capability, you don’t need to
declare any of the more narrowly scoped file-system capabilities
(Documents, Pictures or Videos); indeed, an app must not declare both
broadFileSystemAccess and any of the other three file-system
capabilities.
finally:
Even after the app has been granted the capability, there’s also a
runtime check, because this constitutes a privacy concern for the
user. Just like other privacy issues, the app will trigger a
user-consent prompt on first use. If the user chooses to deny
permission, the app must be resilient to this.
The accepted answer is no longer complete. It is now possible to declare broadFileSystemAccess in the app manifest to arbitrarily read the file system.
The File Access Permissions page has details.
Note that the user can still revoke this permission via the settings app.
You can do it from UI in VS 2017.
Click on manifest file -> Capabilities -> Check photo library or whatever stuff you want.
According to MSDN doc : "The file picker allows an app to access files and folders, to attach files and folders, to open a file, and to save a file."
https://msdn.microsoft.com/en-us/library/windows/apps/hh465182.aspx
You can read a file using the filepicker through a standard user interface.
Regards
this is not true:
Files which are opened with a file extension association or via sharing
try it, by opening files from mail (outlook) or from the desktop...
it simply does not work
you first have to grant the rights by the file picker.
so this ist sh...
This is a restricted capability. Access is configurable in Settings > Privacy > File system. and enable acces for your app. Because users can grant or deny the permission any time in Settings, you should ensure that your app is resilient to those changes. If you find that your app does not have access, you may choose to prompt the user to change the setting by providing a link to the Windows 10 file system access and privacy article. Note that the user must close the app, toggle the setting, and restart the app. If they toggle the setting while the app is running, the platform will suspend your app so that you can save the state, then forcibly terminate the app in order to apply the new setting. In the April 2018 update, the default for the permission is On. In the October 2018 update, the default is Off.
More info

Launching files from path in Windows 10 UWP

I have tried to launch a file from the computer in many ways, suppose is d:\a.pdf
1.- Tried with Launcher.LaunchFileAsync but needs StorageFile that should be GetFileFromPathAsync but as everybody knows W10 apps are unauthorized to open such that path.
2.- Tried using file:/// like file:///d:/a.pdf but it simply returns false
var success = await Launcher.LaunchUriAsync(new Uri("file:///d:/a.pdf", UriKind.Absolute), options);
3.- Launcher.FindFileHandlersAsync() neither returns empty.
So is there any way to launch files?
There is no way to launch files from paths that the app doesn't have permissions to read. Apps don't have access to d:\
You can use LaunchUriAsync to launch files by path from within the app package or app data directories, but not elsewhere. Using the ms-appx: or ms-appdata: protocols is a cleaner way to address those locations.
If you have permission then you can get a StorageFile. This will allow launching files from libraries, locations chosen via FilePicker, files clicked on to launch the app (though that would be circular), etc.

C# Windows Store BackgroundDownloader to removable storage

I am working on an app that will run on all Windows 8 devices (RT support a must) and I am working on adding some offline capabilities, but I can't figure out how to download to a removable storage device such as a USB drive or, in the case of a Surface RT, the micro SD card. Ideally I would like to be able to have the user specify the directory, but it may end up downloading hundreds of files so it has to be specified just once, not once per file. I also want to avoid requiring the user to manually configure libraries.
I have found plenty of articles about how to download to the various libraries, but those go to the internal storage and thus has very limited space on a Surface RT. How can I have the user specify a location for a large number of files to download and/or download to a removable storage device?
A really slick solution would be a way to programmatically create a library in a location of the user's choosing so the user can choose if they want it on the local system or on a removable device.
I appreciate any suggestions.
You should take advantage of FutureAccessList. It allows you to reuse files and folders that the user has previously granted you access to.
First the user will select the target folder using a FolderPicker:
var picker = new FolderPicker();
picker.FileTypeFilter.Add("*");
var folder = await picker.PickSingleFolderAsync();
You then add the folder to FutureAccessList and get back a string token which you can store for later use (e.g. to ApplicationData.LocalSettings):
var token = StorageApplicationPermissions.FutureAccessList.Add(folder);
When you want to download a file, first get the folder from FutureAccessList and create the target file:
var folder = await StorageApplicationPermissions.FutureAccessList
.GetFolderAsync(token);
var file = await folder.CreateFileAsync(filename);
With that data you can create a DownloadOperation:
var downloader = new BackgroundDownloader();
var download = downloader.CreateDownload(uri, file);
From here on proceed as if you were downloading to any other location (start the download, monitor progress...).

Categories

Resources