I have a database on "ms-appx:///Assets/mydbfile.db" . I want to copy it to the local application folder when the application will start the first time. Database Contain a large number of data.
I try with this Code. but it gives me an exception.
StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(
new Uri("ms-appx:///Assets/mydbfile.db"));
await file.CopyAsync(ApplicationData.Current.LocalFolder, "mydbfile.db");
Here Is My Db File
I tried with a text file and your code worked fine.
Do you have the Build Action in the file properties set to Content?
Where are you trying to run your code within your app?
Related
I have an app which is creating .json file. User enters required data and then app creates .json file inside bin folder:
File.WriteAllText("dbconfig.json", JsonConvert.SerializeObject(dbconfig, Newtonsoft.Json.Formatting.Indented));
Next time I start app the code reads bin folder using Environment.CurrentDirectory an searches for a .json file:
File.Exists($"{Environment.CurrentDirectory}\\dbconfig.json"
I am using this so that user shouldn't need to enter the same data everytime he starts an app, only once for the first time. While debugging everything is working fine. The problem is that after I've created setup file and install an application, after I enter required data to be saved to .json and press OK the application crashes.
Does anyone have an idea where the problem can be? Maybe something is wrong with file creation? I've never done such thing before so there is great possibility that I'm missing something in my code.
Almost impossible to say without more information like what is the exception? Is the error in the file create or json serialization.
Off the top of my head it could be dependent on where you install application. i.e. is it under a protected folder where you may need elevated privileges.
Looking at your filename looks like you want to store some user data, ideally those files should be stored in the users profile or all users profile. Try something like
// create a folder to store user data under c:\users\username\appdata\local
var appDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "myapp");
if (!Directory.Exists(appDataPath))
{
Directory.CreateDirectory(appDataPath);
}
//Write json to file
var jsonFile = Path.Combine(appDataPath, "dbconfig.json");
File.WriteAllText(jsonFile, JsonConvert.SerializeObject(dbconfig, Newtonsoft.Json.Formatting.Indented));
//ToRead
if (File.Exists(jsonFile))
{
var jsonString = File.ReadAllText(jsonFile);
.....
}
Prologue:
I am writing SQLite GUI client for UWP. I use Microsoft.Data.Sqlite library for SQLite API with C#. Also I use a redirection table to be able to open database within my sandbox app which is published in Microsoft Store. Redirection table replaces CreateFileW to CreateFileFromAppW calls and similar.
Problem:
User has File -> Save as feature. When user creates a new database file is created inside app local directory. Next when user saves his/her database as I need to move this file. I use StorageFile API cause I cannot use any other file API within a sandbox app. So I call:
var savePicker = new Windows.Storage.Pickers.FileSavePicker();
savePicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.DocumentsLibrary;
savePicker.FileTypeChoices.Add("SQLite3 Database", new List<string>() { ".sqlite", ".db" });
savePicker.SuggestedFileName = "Database";
var file = await savePicker.PickSaveFileAsync();
if(null != file)
{
Windows.Storage.AccessCache.StorageApplicationPermissions.FutureAccessList.Add(file);
sqliteConnection.Close(); // it is important cause if I skip this moving a file will fail
var localFolder = ApplicationData.Current.LocalFolder;
var currentStorageFile = await localFolder.GetFileAsync(App.UnsavedDatabaseFileName); // here I obtain StorageFile for opened database
await currentStorageFile.MoveAndReplaceAsync(file); // here I move a file
sqliteConnection = new SqliteConnection("Data Source=" + file.Path);
sqliteConnection.Open(); // this line fails with error 14: cannot open database file
}
I also tried to skip closing and reopening a connection -> then moving a file fails.
If I call FileOpenPicker between await currentStorageFile.MoveAndReplaceAsync(file); and sqliteConnection = new SqliteConnection("Data Source=" + file.Path); then everything will work fine but showing file open picker right after file save picker is a very bad user experience. I know that sandboxed app gives file access permission only after user selected a file manually. But it looks like that FileSavePicker does not give me a permission just like FileOpenPicker does. I could not find any info about it.
Epilogue:
This is the app https://sqliteman.dev. Please feel free to criticize cause it is what makes my app better.
If it is a permissions issue, then one solution would be to declare broadFileSystemAccess in your app's manifest.
https://learn.microsoft.com/en-us/windows/uwp/files/file-access-permissions
I find it odd that you don't have write access to a file you create.
Try putting MoveAndReplaceAsync() in a using statement, and opening the SQLite connection outside of it.
Update:
I have tested with broadFileSystemAccess capbility, and it doesn't work and still report the exception "cannot open database file". Therefore, it isn't feasible to use broadFileSystemAccess capbility.
If you want to use Sqlite in uwp, there are only two location can be accessed. ApplicationData and Application install directory, the difference is that ApplicationInstallation can only be read, and ApplicationData can be read and written. So it reported the exception when you connnect the file located in another location.
My meaning is that you could store the database file anywhere, but when you operate this database file, you need to move this file to the location that can access.(ApplicationData,Application install directory). OtherWise, you can't insert data to the table of database file, even, you can't connect the database file.
Object reference error
in below part (it couldn't find my local DB file 1st, in order to copy). Db file is inside my project folder - Assets ; Properties window, have set the Build action to Content.
StorageFile databaseFile = await Package.Current.InstalledLocation.GetFileAsync("people.sqlite");
await databaseFile.CopyAsync(ApplicationData.Current.LocalFolder)
I think you need to use Application.GetResourceStream.
"Returns a resource file from a location in the application package.
The GetResourceStream method enables you to load resource files with Content or Resource set as the Build Action property value."
This is for WP8 but should explain the process.
Hi can someone recommend me how I can connect to sql lite db in Windows store app? I add my file called database.sqlite to my app like new item. But I cannot find how I can connect to my existing file. I find this:
StorageFile DataFile =
await ApplicationData.Current.LocalFolder.GetFileAsync("database.sqlite");
But I dont know how write correct path to file. Does anyone have some idea.
When you add a database file to your project, it is considered an asset of your project. The file is stored with your application, and is in a read-only location.
To access the read-only version, you have to use this:
StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(
new Uri("ms-appx:///relative/path/to/db/database.sqlite"));
Where relative/path/to/db is the path relative from the top level of your project. For example if your project has a folder called Data that has your db file in it, then you would use "ms-appx:///Data/database.sqlite".
Since the file is read-only, you cannot write to it. If you need to do so, you must first make a copy of it into a writeable location (e.g. ApplicationData.Current.LocalFolder):
// get reference to read-only copy
StorageFile readonlyDb = await StorageFile.GetFileFromApplicationUriAsync(
new Uri("ms-appx:///Data/database.sqlite"));
StorageFolder localFolder = ApplicationData.Current.LocalFolder;
// make a copy in a writeable location
StorageFile DataFile = await readonlyDb.CopyAsync(localFolder, "database.sqlite");
// now open a sqlite connection to DataFile...
I have an application, where user download images to the Local App Storage, it works like this because in order for the application to display content properly we dont want the user to have direct contact with the images and alter them.
Now we want the user to be able to copy the image to the clipboard or to make a copy in Pictures Library. The problem is that I'm getting this exception when trying to do it.
The code example is here:
http://imgur.com/qnltKTa
If I copy the image selecting it with the file picker, or getting it from Pictures Library my code works fine. But this happens when doing it from the Local Storage Folder.
Your code has mistake. Remove "\\" from this line
StorageFile storageFile = await folder.GetFileAsync("Circulo 2_Atomo.png")