I have a WorkAboutPro 4 and on this i run an application.
This application uses an SQLlite database.
Now i also run a computer program along side it, in here i use RAPI2 to work with my handheld device.
As soon i connect my device a function triggers and it first pulls my database from my handheld to my computer.
I then do some stuff with it and go on to push it back. problem is that the database that returns is always 0kb and has no data, not even tables.
//Create my Paths
string myDevice = device.GetFolderPath(SpecialFolder.ProgramFiles);
string deviceFile = myDevice + #"\PPPM\SQL_PPPM.s3db";
string myComputer = Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase).Substring(6);
string localFile = myComputer + #"\SQL_PPPM.s3db";
//Get the Database
RemoteFile.CopyFileFromDevice(device, deviceFile, localFile, true);
//Do Stuff
try
....
catch(Exception ex)
....
//Push The Database back
RemoteFile.CopyFileToDevice(device, localFile, deviceFile, true);
Now first i thought it was beccause i am not able to push a database over the connection. So i tried to pull a full database to my computer. but this works just fine.
Then i went on and placed an empty Txt file on my hadn held. pulled it, added text and pushed it and also this works fine.
So the only thing that goes wrong is when i try i push a full database back to my HandHeld resulting in an 0kb empty database.
Anyone an idea why this is?
Lotus~
Edit: if you know a beter way to detect if a device is connected and push/pull files from a PDA please let me know.
So i faced the same problem as well.
It most likely has to do with your Sqlite connections still being open.
The thing that worked out best for me was to modify my SqlDataAccess class and start using the 'using'.
Example:
using(var connection = new SQLiteConnection(ConnectionString))
{
try
{
connection.Open();
}
catch (Exception e)
{
throw new Exception(e.Message);
}
finally
{
connection.Close();
}
}
For me the same worked with DataAdapters.
Good luck in the future, and remember never throw yourself in a case of Denvercoder9. You should have answered this a long time ago.
Related
I have an Azure app service setup for SyncTables. On my development machine, I can save items and they sync to the cloud, no problem. However, I am having a hard time getting the data to a new device. I assumed that when first loading the application on the new device that the table.PullAsync() calls would fetch all the data for each table.
The push/pull process completes successfully, but no data is pulled to the device. I can add a new item on the new device, and it uploads to the cloud, but I am not having any luck getting the initial data onto the new device. Here is my SyncAsync method:
private IMobileServiceSyncTable<Person> personTable = App.MobileService.GetSyncTable<Person>();
private IMobileServiceSyncTable<Card> cardTable = App.MobileService.GetSyncTable<Card>();
private async Task SyncAsync(bool showMessage)
{
string errorString = null;
try
{
await App.MobileService.SyncContext.PushAsync();
await personTable.PullAsync("person", personTable.CreateQuery());
await cardTable.PullAsync("cards", cardTable.CreateQuery());
}
catch (MobileServicePushFailedException ex)
{
errorString = "Push failed because of sync errors: " +
ex.PushResult.Errors.Count + " errors, message: " + ex.Message;
errorString = ex.PushResult.Errors.Aggregate(errorString, (current, error) => current + ("\r\n" + error.Result));
}
catch (Exception ex)
{
errorString = "Pull failed: " + ex.Message +
"\n\nIf you are still in an offline scenario, " +
"you can try your Pull again when connected with your Mobile Service.";
}
if (errorString != null)
{
// TODO: log some sort of error message
MessageBox.Show(errorString);
}
else
{
if (showMessage)
{
MessageBox.Show("Database synchronization complete.");
}
LastSynced = string.Format("Last Synced: {0}", DateTime.Now.ToString());
}
}
As I said, new data created will sync to the new device, but I need to be able to do an initial pull of the data when the application is installed on a new device. Is there a way to force the PullAsync() call to fetch all data, or somehow to make the SyncTables know that they have data to fetch so that the next time SyncAsync is called, they will fetch the data?
Here is my InitLocalStoreAsync() method, which initializes the local database on application launch. I have also tried deleting the localstore.db file and launching again, hoping that the fresh copy of the file would want to pull all the data, but that wasn't the case.
private async Task InitLocalStoreAsync()
{
if (!MobileService.SyncContext.IsInitialized)
{
var store = new MobileServiceSQLiteStore("localstore.db");
store.DefineTable<Person>();
store.DefineTable<Card>();
await MobileService.SyncContext.InitializeAsync(store);
}
}
EDIT
One thing I'm thinking is that maybe for now I will have to make sure all instances of the software are installed before adding any data, but I want to get this figured out in case of adding more installations in the future.
EDIT 2
I tried to fetch the data from the remote database manually and import it into the new installation, but that caused the items to be duplicated on the server after the next sync.
EDIT 3
Installing multiple instances prior to adding any data also did not work. Both instances can push data to the remote server, but neither are fetching the new data as they should. I'm hoping that it is something simple like a setting somewhere, but I don't have this problem with another Azure app service that I'm running.
The problem ended up being that I was trying to use the old NuGet packages WindowsAzure.MobileServices and WindowsAzure.MobileServices.SQLiteStore. Changing to use the new Microsoft.Azure.Mobile.Client and Microsoft.Azure.Mobile.Client.SQLiteStore packages got everything working properly.
One of the things that is different is that the new Azure system properties no longer contain the leading __ so the old packages didn't know how to compare what data was new on the server.
I am building a Windows Phone 8 app using sqlite.net using this link as a reference:-
http://developer.nokia.com/community/wiki/How_to_use_SQLite_in_Windows_Phone
There is a database in the project which is being seeded in the Isolated Storage. The database contains only one table which has almost 26k entries.
I am trying to connect to that database in my MainPage.xaml.cs as follows:-
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
using (SQLiteConnection db = new SQLiteConnection(App._dbPath))
{
db.GetTableInfo("IWMCemeteries");
try
{
List<IWMCemeteries> cemeteriesList = db.Table<IWMCemeteries>().ToList<IWMCemeteries>();
MessageBox.Show("Number of elements in table is " + cemeteriesList.Count);
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
}
The problem is that it takes too long(over 25 seconds) for the message dialog to show up.
I tried an alternate method running a raw query as follows:-
List<IWMCemeteries> cemeteries = db.Query<IWMCemeteries>("select * from IWMCemeteries");
MessageBox.Show("Number of elements in list is " + cemeteries.Count);
But this seems to take even longer!(almost 30s).
Can someone please tell me what I am doing wrong here?
Thanks,
Rajeev
Nothing wrong here for me. As some people noticed, with 26k rows you are starting to work with an interesting bulk of data. So, in mobile devices working with a "lite" database, you must adapt your request depending on what you really need :
You want the number of rows, then use SELECT COUNT(*)
You want to display all rows in a list, then use paging or asynchronous loading (on scroll down) to fetch only 20 elements each times.
In any apps, but mostly in mobile devices, you have to consider the volume of data which moves.
In this way, any request would be instant and your application will perform well.
There's nothing wrong with your query. Just limit the data you fetch from the database. It's a mobile device with limited power, not a full blown pc.
I have some problems while trying using WindowsInstaller library or Wix Microsoft.Deployment.WindowsInstaller.
I'm, getting exception that the file being used by the process and I cannot delete it even though I've closed all record,view and database and disposed them.
try
{
string currentDir = Directory.GetParent(Directory.GetCurrentDirectory()).Parent.FullName;
string msiPath = "PathTo\MyMSI.msi";
using (InstallPackage installPackage = new InstallPackage(msiPath, DatabaseOpenMode.ReadOnly))
{
string query = "SELECT * FROM Property WHERE Property = 'ProductVersion'";
using (View view = installPackage.OpenView(query))
{
view.Execute();
using (Record record = view.Fetch())
{
string version = record.GetString(2);
Console.WriteLine(version);
record.Close();
}
view.Close();
}
installPackage.Close();
}
File.Delete(msiPath);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
And still I get the following:
Access to the path 'PathTo\MyMSI.msi' is denied.
I've also tried with the object
Database
Any help will be appreciated.
I was able to figure out what is blocking the delete action.
It appears that the file was in read only.
I don't know why I got this kind of exception but the following solved it:
//removing read only from file in order to interact with it
FileInfo fileInfo = new FileInfo(msiPath);
if (fileInfo.IsReadOnly)
{
fileInfo.IsReadOnly = false;
}
Hope it will help others.
I appreciate everyone who helped here for your time.
Below are some steps you could follow for ur problem :
Wait a minute and try deleting the file again, sometimes Windows or the program using the file may still be closing and therefore still using the file you're attempting to delete.
Close and Explorer window and re-open.
Locate the program using the file and close it. If you're uncertain what program is using the file, close all programs until you're able to delete the file.
Try using unlocker, a free software program designed to unlock any file being used by Windows or other programs without restarting the computer.
Reboot the computer. If after closing all programs you're still unable to delete the file, it's likely that something in the background is still using the file.
If after rebooting the computer you're still unable to delete the file, boot the computer into Safe Mode and delete the file.
Thanks
I was following this other post --> C# DSN Util
So I have the following code. (Slightly Modified)
OdbcConnection DbConnection = null;
try
{
DbConnection = new OdbcConnection(
"DataSourceName=NEWDSN;"+
"Driver=SQL Server;" +
"Description=New DSN;" +
"Server=<NameofServer>;");
DbConnection.Open();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
Console.ReadKey();
System.Environment.Exit(0);
}
Everything seems to work fine, I get no errors but nothing is created? I have tried troubleshooting with the following techniques
I am able to create one when doing it manually in the ODBC Admin tools
When adding "DatabaseName=blah;"
I have tried many things in this field but am unable to produce anything.
EDIT:
Hmm, there may not be a way to create one using this code. DBConnection.Open seems to be my only decent option. Is it even possible to create one that will appear in the ODBC Data Source Admin?
The code and example you are using is for opening a DSN that has already been created, not for actually creating them in the first place.
You probably need something more like this example
http://www.codeproject.com/KB/database/DSNAdmin.aspx
My problem involves checking if I have a valid database connection before reading from the database. If the database is down I'd like to write to a xml file instead. I have the location of the database (if it's up) at runtime so if the database was working I can create a new sqlConnection to it.
Use a typical try...catch...finally structure, and based on the specific exception type and message, decide whether you want to write to xml or not.
try
{
SqlConnection connection = new SqlConnection(DB("Your DB Name"));
connection.Open();
}
catch (Exception ex)
{
// check the exception message here, if it's telling you that the db is not available. then
//write to xml file.
WriteToXml();
}
finally
{
connection.Close();
}
I would just use something like:
using(SqlConnection conn = new SqlConnection(c)) {
conn.Open();
}
It will throw an exception if invalid. You could write to the xml in the exception.
An easy way would be to execute a simple query and see if an error occurs:
For Oracle:
SELECT * FROM DUAL
For SQL Server
SELECT 1
Basicly just some kind of relatively "free" query that will let you know that the database is up and running and responding to requests and your connection hasn't timed out.
You cannot really tell whether the DB is up and running without actually opening a connecting to it. But still, connection might be dropped while you're working with it, so this should be accounted for.