UWP PreLoaded SQLite - sqlite

I am trying to copy a preloaded SQLite db into my UWP app. On the initial installation it copies the "test.db", but the size is 0 bytes and there are no tables or data. The original db is 1300 bytes with data and tables.
Another factoid...when I create the app Using Visual Studio 2017 and compile and run/debug the app it works fine, but when I sideload the appx file or download from the Windows Store the db is empty.
Here is the code that I am using:
Task task = CopyDatabase();
private async Task CopyDatabase()
{
bool isDatabaseExisting = false;
try
{
StorageFile storageFile = await ApplicationData.Current.LocalFolder.GetFileAsync("Express.db");
isDatabaseExisting = true;
}
catch
{
isDatabaseExisting = false;
}
if (!isDatabaseExisting)
{
StorageFile databaseFile = await Package.Current.InstalledLocation.GetFileAsync("Express.db");
await databaseFile.CopyAsync(ApplicationData.Current.LocalFolder, "Express.db", NameCollisionOption.ReplaceExisting);
}
}
I'm not getting any error messages.

Does the your database file deployed correctly to the target system?
To confirm it, see your deployed - "Package" - folder. Open command prompt with administrative previleges, and see the directory
c:\Program Files\WindowsApps\your-app-id
If your database file deployed successfully, you can see it in the directory. If not, you may need to change the deploy settings.
To deploy the file to target machine, you should set the property of the one as ...
'BuildAction=Contents'
'Copy to output directory'='Always Copy'
You can set it from solution explorer and right-click the your database file.
If you succeeded the deploying file, your code will copy your database file to app local folder.
c:\Users\YOUR-USER-ID\AppData\Local\Packages\YOUR-APP-ID\LocalState

First, you would need to use await for your CopyDatabase method.
Second, I suggest you call this method in MainPage_Loaded event handler instead of MainPage's Constructor.
public MainPage()
{
this.InitializeComponent();
this.Loaded += MainPage_Loaded;
}
private async void MainPage_Loaded(object sender, RoutedEventArgs e)
{
gui = this; InitializeComponent();
await CopyDatabase();
DataSetup();
CreateNewChartButton.Visibility = Visibility.Collapsed;
SignInButton_Click(null, null);
}

Related

Creating PDF document from dotnet Core 2 using node service

I need to create a pdf file from an HTML on the server-side (dotnet core 2) and send it as an attachment of an email. I have created a node service (createPdf.js) as follows and kept it in a local directory (NodeService) within the solution -
module.exports = function (callback, html, outputFilePath) {
var pdf = require('html-pdf');
var options = { format: 'A3', orientation: 'portrait' };
pdf.create(html, options)
.toFile(outputFilePath, function (err, res) {
if (err)
return callback(null, false);
callback(null, true);
});
}
And I am triggering this function as follows -
public static async Task<bool> GeneratePdf(INodeServices nodeService, string html, string outputFilePath)
{
string pdfGenerationNodeService = Path.Combine(Directory.GetCurrentDirectory(), "NodeService", "createPdf.js");
try
{
return await nodeService.InvokeAsync<bool>(pdfGenerationNodeService, html, outputFilePath);
}
catch (Exception ex)
{
throw;
}
}
For calling this method from the controller -
public async Task<IActionResult> SendQuotationToHospitalAsync([FromServices]INodeServices nodeService, int id)
{
...
bool isAdminPdfGenerationSuccess = await PdfHelperService.GeneratePdf(nodeService, htmlContent, filePath);
...
}
I have also registered the node service in StartUp.cs -
services.AddNodeServices();
When I am triggering the function in debug mode, it's working properly and the pdf file is getting generated. However, once I deploy the application on the server, the node function is not getting triggered.
Any help regarding the issue will be very helpful. Thanks.
P.S. As it is a home project, I can not afford any premium HTML-to-PDF converter
You may have a look at this as a working example of what you are trying to achieve with NodeServices. It runs on Docker, so you can get a hint from the Dockerfile of what you need to have installed on the server to get it working there as well.
Another approach is to use PuppeteerSharp, as follows:
await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);
var browser = await Puppeteer.LaunchAsync(new LaunchOptions
{
Headless = true,
Args = new string[] { "--no-sandbox" }
});
var page = await browser.NewPageAsync();
await page.SetContentAsync(htmlContent);
await page.PdfAsync(filePath); // page.PdfStreamAsync() to generate only in-memory
I'm using angular 7 for client-side and had npm packages installed accordingly, which included the html-pdf package as well. However, I had not installed it in the directory where I have kept the node script. I was hoping that the package would be taken from the vendor.js after deployment, which was clearly not the case. I had to create another package.json file in the directory and installed it separately after deployment and everything went smooth thereafter.
That's what I was missing when deploying the application - a little manual npm install for installing the package I'm using, in the local directory of the node script.
Thanks a lot for discussing the issue, it helped me a lot in understanding what other mistakes I might have done.

Import data in Windows phone from SQLITE file

Well, The problem is that I have a SQLLITE database file which has data and can be browsed in SQLITE browser. I want this file to be imported in my windows phone app so that I can bind my Lists.
I have been googling and trying for a solution but no luck yet.
public async void UpDatabase()
{
bool isDatabaseExisting = false;
try
{
StorageFile storageFile = await ApplicationData.Current.LocalFolder.GetFileAsync("DTEMPCounselling");
isDatabaseExisting = true;
}
catch
{
isDatabaseExisting = false;
}
if (!isDatabaseExisting)
{
StorageFile databaseFile = await Package.Current.InstalledLocation.GetFileAsync("DTEMPCounselling");
await databaseFile.CopyAsync(ApplicationData.Current.LocalFolder);
}
}
Problem with above code is it searches it in the emulator filesystem while my database file is in my C: drive.
Any suggestion how can I achieve this.
Thanks.
The code I used here was all right. But the real cause of the problem was the idea that the Emulator and the hosting machine work as two different systems. Means, to be able to read the database file in Emulator it should have been placed in Emulator's file system.
Putting the file in Emulator's file system solved the problem.

How to deliver app with prefilled realm-database

I would like to deliver my app with already prefilled data in my realm database. Do I have to simply copy it to the documents directory or is there some other things to do?
Realm's documentation has a section on "Bundling a Realm with an App":
It’s common to seed an app with initial data, making it available to your users immediately on first launch. Here’s how to do this:
First, populate the realm. You should use the same data model as your final, shipping app to create a realm and populate it with the data you wish to bundle with your app. Since realm files are cross-platform, you can use an OS X app (see our JSONImport example) or your iOS app running in the simulator.
In the code where you’re generating this realm file, you should finish by making a compacted copy of the file (see -[RLMRealm writeCopyToPath:error:]). This will reduce the Realm’s file size, making your final app lighter to download for your users.
Drag the new compacted copy of your realm file to your final app’s Xcode Project Navigator.
Go to your app target’s build phases tab in Xcode and add the realm file to the “Copy Bundle Resources” build phase.
At this point, your bundled realm file will be accessible to your app. You can find its path by using [[NSBundle mainBundle] pathForResource:ofType:].
You can either create a read-only realm by calling [RLMRealm realmWithPath:readOnly:error:]. Or, if you’d like to create a writable realm file based on this initial data, you can copy the bundled file to your application’s Documents directory using [[NSFileManager defaultManager] copyItemAtPath:toPath:error:] and then construct your new realm by using [RLMRealm realmWithPath:].
You can refer to our migration sample app for an example of how to use a bundled realm file.
Pre filled Realm-database For Android
Put your realm database in res/raw folder
and execute following code in activity:
// Copying realm database
copyBundledRealmFile(this.getResources().openRawResource(R.raw.default0), "default0.realm");
RealmConfiguration config0 = new RealmConfiguration.Builder()
.name("default0.realm")
.build();
realm = Realm.getInstance(config0);
private String copyBundledRealmFile(InputStream inputStream, String outFileName) {
try {
File file = new File(this.getFilesDir(), outFileName);
FileOutputStream outputStream = new FileOutputStream(file);
byte[] buf = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buf)) > 0) {
outputStream.write(buf, 0, bytesRead);
}
outputStream.close();
return file.getAbsolutePath();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
A much easier way is just creating an ad-hoc function to be called just when there is no data on your realm model ("MyModel", in this example), at first app launch:
let realm = try! Realm()
lazy var data: Results<MyModel> = { self.realm.objects(MyModel.self) }()
func populateDefaultData() {
if yourdata.count == 0 {
try! realm.write() {
let defaultData = ["Data1", "Data2", "Data3"]
for data in defaultData {
let newData = MyModel()
newData.data = data
realm.add(newData)
}
}
data = realm.objects(MyModel.self)
}
}
override func viewDidLoad() {
super.viewDidLoad()
populateDefaultData()
}

Predefined database in windows phone 8.1 app

Where predefined database (.db) should add and how to use it in windows phone 8.1 app?
I am not using Silverlight in my app.
I was trying to do something like this
public MainPage()
{
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Required;
CopyDatabase();
}
private void CopyDatabase()
{
IsolatedStorageFile ISF = IsolatedStorageFile.GetUserStoreForApplication();
String DBFile = "myDB.sqlite";
if (!ISF.FileExists(DBFile)) CopyFromContentToStorage(ISF, "Assets/myDB.sqlite", DBFile);
}
It showing that the namespace name IsolatedStorageFile could not be found.
I found those codes in a sample database app for Windows-phone-8.0 and I was trying to do the same thing in Windows-phone-8.1 (without Silverlight).
As I see you try to copy the database from package to IsolatedStorage and you are targeting WinRT. The sample code can llok like this:
private async Task<bool> CopyDatabase()
{
StorageFolder packageFolder = Windows.ApplicationModel.Package.Current.InstalledLocation;
StorageFolder localFolder = ApplicationData.Current.LocalFolder;
StorageFile file = await packageFolder.GetFileAsync("Assets/myDB.sqlite");
await file.CopyAsync(localFolder);
return true;
}
I've written this code from the top of my head, but should work or help you to find the solution. The above is also possible by Uri schemes:
StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri(#"ms-appx:///Assets/myDB.sqlite"));
More about Data and Files you will find at MSDN.

ASP.NET- using System.IO.File.Delete() to delete file(s) from directory inside wwwroot?

I have a ASP.NET SOAP web service whose web method creates a PDF file, writes it to the "Download" directory of the applicaton, and returns the URL to the user. Code:
//Create the map images (MapPrinter) and insert them on the PDF (PagePrinter).
MemoryStream mstream = null;
FileStream fs = null;
try
{
//Create the memorystream storing the pdf created.
mstream = pgPrinter.GenerateMapImage();
//Convert the memorystream to an array of bytes.
byte[] byteArray = mstream.ToArray();
//return byteArray;
//Save PDF file to site's Download folder with a unique name.
System.Text.StringBuilder sb = new System.Text.StringBuilder(Global.PhysicalDownloadPath);
sb.Append("\\");
string fileName = Guid.NewGuid().ToString() + ".pdf";
sb.Append(fileName);
string filePath = sb.ToString();
fs = new FileStream(filePath, FileMode.CreateNew);
fs.Write(byteArray, 0, byteArray.Length);
string requestURI = this.Context.Request.Url.AbsoluteUri;
string virtPath = requestURI.Remove(requestURI.IndexOf("Service.asmx")) + "Download/" + fileName;
return virtPath;
}
catch (Exception ex)
{
throw new Exception("An error has occurred creating the map pdf.", ex);
}
finally
{
if (mstream != null) mstream.Close();
if (fs != null) fs.Close();
//Clean up resources
if (pgPrinter != null) pgPrinter.Dispose();
}
Then in the Global.asax file of the web service, I set up a Timer in the Application_Start event listener. In the Timer's ElapsedEvent listener I look for any files in the Download directory that are older than the Timer interval (for testing = 1 min., for deployment ~20 min.) and delete them. Code:
//Interval to check for old files (milliseconds), also set to delete files older than now minus this interval.
private static double deleteTimeInterval;
private static System.Timers.Timer timer;
//Physical path to Download folder. Everything in this folder will be checked for deletion.
public static string PhysicalDownloadPath;
void Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup
deleteTimeInterval = Convert.ToDouble(System.Configuration.ConfigurationManager.AppSettings["FileDeleteInterval"]);
//Create timer with interval (milliseconds) whose elapse event will trigger the delete of old files
//in the Download directory.
timer = new System.Timers.Timer(deleteTimeInterval);
timer.Enabled = true;
timer.AutoReset = true;
timer.Elapsed += new System.Timers.ElapsedEventHandler(OnTimedEvent);
PhysicalDownloadPath = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath + "Download";
}
private static void OnTimedEvent(object source, System.Timers.ElapsedEventArgs e)
{
//Delete the files older than the time interval in the Download folder.
var folder = new System.IO.DirectoryInfo(PhysicalDownloadPath);
System.IO.FileInfo[] files = folder.GetFiles();
foreach (var file in files)
{
if (file.CreationTime < DateTime.Now.AddMilliseconds(-deleteTimeInterval))
{
string path = PhysicalDownloadPath + "\\" + file.Name;
System.IO.File.Delete(path);
}
}
}
This works perfectly, with one exception. When I publish the web service application to inetpub\wwwroot (Windows 7, IIS7) it does not delete the old files in the Download directory. The app works perfect when I publish to IIS from a physical directory not in wwwroot. Obviously, it seems IIS places some sort of lock on files in the web root. I have tested impersonating an admin user to run the app and it still does not work. Any tips on how to circumvent the lock programmatically when in wwwroot? The client will probably want the app published to the root directory.
Your problem may be related to the fact that IIS reloads the Web Service Application if the directory or files contained in the main folder changes.
Try creating / deleting files in a temporary folder which is outside the root folder of your application (be aware of permissions on the folder to allow IIS to read/write files).
Instead of writing directly to the file system, why not use isolated storage?
http://msdn.microsoft.com/en-us/library/system.io.isolatedstorage.isolatedstorage.aspx
This should solve any location or permission based issues that you are having
I forgot to come back and answer my question.
I had to give the IIS_IUSRS group Modify permissions to the directory where I was reading/writing files.
Thanks to all those who answered.

Resources