I am developing an android app in Xamarin(C#) using SQLite database. But the issue is every time I install the application on emulator or mobile phone, the old database is deleted.
Is there any way I can make database permanent? I want it to be present on the device even the application is uninstalled assuming that the user will be re-installing the app again.
How do I ask user if he/she wants delete everything while uninstalling the app and then erase all the data or maintain at least the database if user does not want to delete everything?
It's not possible to keep a database if you uninstall the app.
Is there any way I can make database permanent?
Short of a custom ROM of some sort, nope.
How do I ask user if he/she wants delete everything while uninstalling the app and then erase all the data or maintain at least the database if user does not want to delete everything?
You won't be able to prompt the user as they are deleting applications to perform some other action. If this was an option that was available, unscrupulous developers could use such a hook to reinstall their application in a different location and this is bad.
You could, however, include some sort of preference that allows the user to backup their data and copy the database to a location out of your apps private directory. Of course, you would have to provide your own way of encrypting the data if it should be private, and there is no guarantee that the file will not be deleted by the user, another app, etc.
If your information is not sensitive in nature, perhaps writing the database to a public directory (anything other than your application filesDir or externalFilesDir from the start is the way to go. Files in public directories are not deleted when the application is uninstalled.
You may have a greater problem though. If the user is switching devices, a local copy of the database isn't going to help. You'll need someway to download the information and restore state. At this point, most people resort to sending the information to some sort of web service. Android's Backup Manager may be helpful in your case.
When you launch the emulator be sure "Wipe User Data" is not checked. This will allow the data to persist while you are testing. I don't know if it is possible to keep data after an uninstall because it is by default stored in a directory off the application root called data/data
Related
I have seen there are many technologies out there that make auto updating easy for the user (such as winsparkle). The problem we have is we want to be able to auto update our desktop (c#/c++) app without prompting.
If users have the ability to NOT update it makes our lives hell (10,000+ installs all need to be updated about once a month).
We currently install our application via WIX and it reinstalling a new version completely overwrites what was there before. This works fine but we'd love to not even have to run the new installer, thus the idea of auto updating.
I've looked at clickonce but since our app is both a tray icon/windows forms app and a Windows Service it appears installing a service via ClickOnce is somewhat unfeasible.
Any suggestions?
To do this update behavior you need two things:
1) An updater application which checks for updates regularly. If an update is found it should install it automatically. Most commercial setup authoring tools include good updater applications. You can try writing an updater yourself, but it's not as easy as it sounds.
2) Per-user installations for each of your product versions. A per-user installation writes data only in the user profile folder (AppData, Roaming folder etc.) and HKEY_CURRENT_USER. No Program Files or HKEY_LOCAL_MACHINE.
Per-user installations are required so you can perform the upgrade silently. If the installation is per machine, newer Windows version will show the elevation prompt and the user won't know what's happening.
The Updater
Some updaters use services. For automated updates this isn't a real solution because service installation needs Administrator privileges. So your install process and subsequent updates would show elevation prompts.
Another approach is to use a per-user Updater application. It doesn't require any elevation and it can be installed in the application folder. This type of updater can run either as a scheduled task or from within your application (execute it when your application starts).
In both scenarios you need to consider that the Updater may need to update itself. So the process which performs the update must be a temporary process (for example a temporary copy of the updater application). It also should run without elevation. This is why a service is not such a good idea. It would need to stop itself before the update, use a temporary process which handles the update and start again when finished.
Here's what I ended up doing for some applications that I manage, and that are written in C#.
I distribute an installer based on InnoSetup to deploy the files on the user system, and the application stores information version in the registry.
The application has a mechanism that checks at startup for available updates, and prompts the user. This system is based on a JSON manifest that contains a basic structure such as the following:
{
"releases": [
{
"CommitDate": "2020-09-05",
"Version": "0.1.0.0",
"VersionString": "0.1.0+19",
"SHA": "4ff750da44b41e569daf3c62f4495a8ee2b25f08",
"InstallerMd5Sum": "805497b5c13ee070b7465bb32689e0dd"
},
{
"CommitDate": "2020-09-07",
"Version": "0.1.0.0",
"VersionString": "0.1.0+22",
"SHA": "a04ec929b21230ba0e2577617713d10b106266e9",
"InstallerMd5Sum": "805497b5c13ee070b7465bb32689e0dd"
}
]}}
The application downloads that file and compares its local information with the latest entry in the file.
If the latest entry is more recent (based on things like commit date), it retrieves the installer from the distribution server, checks for integrity, and run the installer.
The installer takes care of updating the entries in the registry with the latest information.
Now, there are three angles to your question I believe.
The first one is whether a modularity is possible so that you don't end up replacing everything and can provide delta installers, the second is whether you can use a technology that knows how to deal with updates (which I believe MSI knows how to do). Finally, the third angle is whether or not you have a way for users to rollback in case the latest version has issue with their system or whatever your application is for.
so I have a bundled software that a client can download and install (using an msi on win machines).
part of this software is a mongoDB database, that stores client info, configurations, etc..
When the software is first installed, it creates an empty folder for the mongoDB, and whenever the software starts, it starts a mongod process (using C#'s Process.Start()): mongod.exe --dbpath <path> --port <port> --quiet.
My goal is to secure the mongoDB database with a username / password that will be known only to my application.
this will help prevent tampering with my client's data from the outside, as well as make it harder (but not impossible, see below) for the client themselves to tamper with the application's data.
The general idea, I guess, is that on installation (or on startup), to create a user with read / write privileges which my software will use to communicate with the database.
So My questions are:
1. How do I programmatically do this? I guess this is the right direction, but I couldn't find much info on the c# driver docs
2. How do I deal with upgrades? i.e clients who installed a previous version of the software, where the database is not secure at all; i would like to create a user with a password in that case as well.
3. how do I store the application user's credentials in my application? in a config file? but that can be read by the client. any best practices here?
versions info- (unfortunately, because of my company's issues, we're not using the latest product versions); mongoDB 2.6, mongoDB driver for .net 1.5.0.
thanks!
P.S. I have read through the security section on the mongoDB website, but wasn't able to find a simple example for the use case I'm trying to implement.. maybe I'm just missing something simple here..
This is kind of an interesting, unusual use case.
First of all, I want to make sure you're aware of the licensing/copyright implications of bundling MongoDB with your software. You should check out the license section of the mongo project GitHub page and read up on the AGPL.
Second, the easiest part of your question:
how do I store the application user's credentials in my application? in a config file? but that can be read by the client. any best practices here?
This goes beyond MongoDB. If a user owns the system that the mongod process is running on, they could just copy the data files and set up a no-auth mongod on top of your application data. You cannot reasonably stop them from doing things like that, so do not count on your application's data to be secure from the client user. Plus, if you install your application code locally, any decently smart and committed person should be able to extract the username and password from the compiled application code. You can make it hard, but not impossible.
Third,
How do I programmatically do this?
Based on what I just said, I'm taking "this" to mean
on installation (or on startup), to create a user with read / write privileges which my software will use to communicate with the database.
not the part about having it be secure from the person who owns the computer it's installed on, because that's not possible. To do this, I'd either package a mini datafile to start the mongod on top of, one that included users set up already, or include a dump that you use something like mongorestore to load into the mongod after you start it up. The first option is way simpler to implement and should not require you to have to take down and respawn the mongod process, so try that - see if you can set up a mongod with auth how you want it and then transplant user info by copying data files. FWIW, I'm pretty sure the passwords are not stored in plain text in the data files (they are salted), so you won't have that directly exposed from the data files.
Finally,
How do I deal with upgrades?
You'll have to take down their mongod, restart it with auth, use the localhost exception to create the users you need, turn off the localhost exception (optional but why not), and then end that connection and start new ones using auth. It's the same process as in the security tutorials, you just have to do it with C# driver commands. Note that moving between MongoDB versions is also tricky as the seurity model has improved over time, so you should consult the upgrade guide for extra things to do to make sure user schema gets upgraded correctly if you are moving a user from a secure 2.6 to a secure 3.0, say.
C# driver connectionstring can accept login credentials for the database.
mongodb://username:pwd#server:port/dbname
for ex
mongodb://myuser:mypassword#mydbserver:30254/mydb
The best way is to store the data in a config file. If you are worried about exposing it, it can be encrypted and stored. Other less likely option is to store in a resource file and reference that as a string.
I need to create a desktop WPF application in .NET.
The application communicates with a web server, and can work in offline mode when the web server isn't available.
For example the application needs to calculate how much time the user works on a project. The application connects to the server and gets a list of projects, the user selects one project, and presses a button to start timer. The user can later stop the timer. The project start and stop times need to be sent to the server.
How to implement this functionality when the application is in offline mode?
Is there are some existing solution or some libraries to simplify this task?
Thanks in advance.
You'll need to do a couple of things differently in order to work offline.
First, you'll need to cache a list of projects. This way, the user doesn't have to go online to get the project list - you can pull it from your local cache when the user is offline.
Secondly, you'll need to save your timing results locally. Once you go online again, you can update the server will all of the historic timing data.
This just requires saving the information locally. You can choose to save it anywhere you wish, and even a simple XML file would suffice for the information you're saving, since it's simple - just a project + a timespan.
It sounds like this is a timing application for business tracking purposes, in which case you'll want to prevent the user from easily changing the data. Personally, I would probably save this in Isolated Storage, and potentially encrypt it.
You can use Sql Server Compact for you local storage and then you microsoft sync framework to sync your local database to the server database. I recommend doing some research on the Microsoft Sync Framework.
Hello all I implemented this application I've created my own off-line framework
based on this article and Microsoft Disconnected Service Agent
DSA
I've adapted this framework for my needs.
Thank you for all.
you can use a typed or untyped dataset for offline-storage.
when online (connected to internet) you can download the data into a dataset and upload it back to the database server. the dataset can be loaded from and saved to a local file.
I want to create a window based application in C# so that we can run it without installing the application into each and every system.
It need to connect that application through database as well.
I want to create this application so that it can be run directly through pendrive and can write into database as well.
I know how to work with database though window application but with installer only.
I have created many window application
but all runs on client machine after
Installing the deployed setup. But now
i want client need not install the
setup deployed. He can use my
application by directly clicking my
executable file
There is nothing in Windows that requires an application to be installed. That said, installation is intended to:
Make things more simple for the end user.
Setup the registry, usually for path information and uninstall information.
Initialize any initial information the software may need before it's first run.
Simply avoiding using the registry and saving files locally to your application is usually enough to make your application portable.
That said, as long as you allow the user to select a database location within your software, you should be fine. Saving the information on the pen-drive, in an .ini file for instance, would allow each computer you plug into to read these same settings.
If you expect each computer to have a difference connection string to the database, you could save your settings to the %appdata% directory. When the user plugs the pendrive back in later, his settings will still be there, and no other user will see these same settings.
The downside to the second approach, however, is that the user has no way to "uninstall" and recover the space written to %appdata% automatically. However, for most private business applications, this isn't much of a concern.
Edit: If your real question here is how to distribute an application without an installer, simply build the Release version of your application, and look in /bin/Release/ within your project. Copy these files to another location, remove any debug or unneeded files, and make sure you have all your dependencies in order.
If you just want to connect to a database, you can do that in the EXE without any kind of installer needed. How that is done would depend on which database it is, and how you are connecting to it, but generally the item that requires encoding in the EXE (or in an outboard XML file which the EXE can read) is a connection string. This connection string is probably what the installer is managing.
A good tutorial on building your first Windows application in C# can be found here:
http://msdn.microsoft.com/en-us/library/360kwx3z.aspx
If you don't know where and how to start window form application or how to connect to database or so, there are plenty tutorials and you can Google for it very easily ;)
Here are few examples:
GUI related:
Tutorial: Working with Windows Forms
- Part I
GUI Windows Forms « C# / CSharp Tutorial
Windows Forms
tutorial with C#
Databases related:
Creating a database connection
Simplest form of installation; use an if/else; when application start, it would check for some registry key (lets say, installation=done), if the value of registery key is="done", then run the else part, which means run the app. If its "notdone", then setup all initial settings and then run the app. A pseudo will go as follows:
if(HasValidRegistryKeys()) //Check if initial settings are already there
{
Runnable=true;
}
else
{
//Not installed, lets setup app settings
//Assume that the application is running for the first time.
try
{
SetupRegistry(); //Set installation=done
SetupDatabase();
//Setup more things.
Runnable=true;
}
catch()
{Runnable=false;}
}
//Run the app
if(Runnable)
{
RunApp();
}
else
{
MessageBox.Show("Some error");
}
My question is sort of linked to this existing question
How to deploy a desktop .Net application with custom settings per user
However, I understand the idea of using Application Settings what I can't find information on is, how should I deploy the application settings for different customers?
We have a custom settings system that works just fine, however when the app is first run it needs to know a couple of things, such as Company Name and Application Server. These will obviously differ on a customer basis.
I don't want the user to have to input these settings at first run as in most cases the app will be deployed by Group Policy.
Currently my thinking is to have some sort of setting file in a separate build per customer. Is this the way to go, or have I missed some kind of native support for this idea of "customer profiles"?
EDIT:
More info that might help people grok my question.
This is an enterprise application that consists of a central database and application server, plus 100 installations of a client application. I need to be able to give the client application some application settings that will obviously be different for different customers.
A lot of applications ask you some initial settings at the first start (Microsoft Office, Visual Studio, etc.). So this behaviour is commonly known by the user.
Maybe the problem is more, that these initial settings revive an update of your application. To accomplish this you could save your data in a version independent path within the registry or somewhere below %AppData%.
Also it would be helpful to prefill these dialogs at the first startup, by getting these informations somewhere out of the machine (e.g. Company Name can be get from registry [HKLM\Software\Microsoft\WindowsNT\CurrentVersion\RegisteredOrganization] or as Application Server take the Gateway address, AD Server, whatever most commonly matches).
So in a best case the user will be presented with a already correct filled out form and just has to press enter or he makes only the changes that are necessary, but doesn't to fill out the complete dialog by himself.
Update:
So if the user doesn't know the Application Server path. Who does it? Where resides this information? Maybe you can enforce your customers to provide this information all the same way. Maybe they set some environment variable within the logon script or they put a file with the needed informations on a global accessible place (e.g. where the logon script resides).
If I understand right you want to deploy a pre-customized software for each user.
You could use WIX to create a MSI-package for each customer. You can deliver several user-settings in your customer-oriented msi. You can dynamically generate a WIX-XML-Document based on a data-source where you store your customers.
Is a bit work, but later saves a lot of work. The MSI-creation through WIX can be easily integrated into the build-process.
Given that it's an enterprise environment, have you considered using ClickOnce? We've had success mainly with startup arguments, e.g. http://servername/OurApp.application?environment=uat
It doesn't always scale, but you can pass arguments using GET variables and parsing the resulting QueryString when delivering via HTTP - http://msdn.microsoft.com/en-us/library/ms172242.aspx
You might pass in the settings in the QueryString, or create them in the database, generate a (hashed?) key and build a QueryString unique to that reference (with the added benefit that an inquisitive user wouldn't be able to manipulate the URI and fake a different set of parameters).