Showing posts with label C# CF. Show all posts
Showing posts with label C# CF. Show all posts

2008-02-20

Embedded Firebird, error trying to write to file

This error has been really annoying me tonight!

I have an app that uses Embedded Firebird for its DB so that I don't need to
install a DB server. On Vista my app throws an exception "Error trying to
write to file (the correct path here)".

I recreated the DB on my development machine (XP) and tried running it, it should work, it has for months, but it didn't! The same error too!

For the life of me I couldn't work out why it would suddenly stop working on both machines, what did they have in common? I uninstalled stuff, reinstalled it, etc, no joy.

The answer on my XP box was simple. I used the local server to create the GDB file + generate my DB structure using ECO. What I hadn't thought of was the fact that the firebird server then holds a file handle open on that GDB file in case I want to use it again. Embedded firebird needs an exclusive lock on the file so this was the problem on my XP box. I wish the error had read something like "Error trying to write to file, unable to obtain an exclusive lock", would have saved me some time!

However, I don't have the firebird server installed on my Vista test machine so what was causing the problem there? It seems that embedded firebird cannot access the GDB on vista if it is in the CommonApplicationData folder. This is a real pain because

A: I need the database in a common place so that any user using the software will see the same data.
B: This is where it is supposed to go!

So doesn't the current user have sufficient privileges to write to this folder? The following snippet of test code says they do.

static void Main(string[] args)
{
  string fileName = Environment.GetFolderPath(System.Environment.SpecialFolder.CommonApplicationData);
  fileName = Path.Combine(fileName, "MyTest.txt");
  Console.WriteLine("Writing to " + fileName);
  StreamWriter sw = new StreamWriter(fileName);
  using (sw)
    sw.WriteLine("Hello");
  Console.WriteLine("Done");
  Console.ReadLine();
}



I have checked and the database file is in CommonApplicationData on the Vista machine, so it's not as though I am installing into the wrong folder or something either.

The only thing I can think of is that the UAC rules are different between .NET assemblies and native DLLs. It's the only thing I can think of, I really could do with a solution to this!



Pete

2006-12-02

Validating XML against an XSD schema

I have a new job. Well, I say "new" but I actually started in December 2005. Anyway, this "new" job requires me to develop compact framework apps. Seeing as Delphi doesn't support CF I am developing my application in VS2005, it's a really nice tool but I miss ECO so much!

One thing I had to do was to write an XML importer routine. This would retrieve an XML file detailing tasks due for the next seven days and then import it into the PPC's database. Because I am not responsible for generating the XML, and because it is good practise anyway, I decided to create an XSD file to validate the XML. PDA's have very little storage resources (the flash card is shared between disk and memory) so I decided to read the XML file a line at a time using the XmlReader so that the contents don't exist on the flash memory twice (disk + memory), another benefit of this approach being that I can read it directly from a ZIP file too!

In dotnet V2 the class XmlValidatingReader is obsolete, not that it would have been much good anyway considering it is not implemented in V1 of the compact framework. After some playing around I was finally able to read the XSD information from a resourced embedded into my app, and read the XML one line at a time whilst validating it against that XSD file.

Here it is:

//1 Get a stream containint the XSD
Stream xsdStream = GetType().Assembly.GetManifestResourceStream("Eden.HandheldVendor.TaskFlow.DataImport.xsd");
//2) Create an XmlTextReader that uses this stream
XmlReader xsdReader = new XmlTextReader(xsdStream);
//Create an XmlSchema from the embedded XSD
System.Xml.Schema.XmlSchema xsdSchema = System.Xml.Schema.XmlSchema.Read(xsdReader, null);

//4) Create some XmlReaderSettings that use this XmlSchema
XmlReaderSettings readerSettings = new XmlReaderSettings();
readerSettings.ValidationType = ValidationType.Schema;
readerSettings.Schemas.Add(xsdSchema);

//5) Set an event for validation errors
readerSettings.ValidationEventHandler +=
new System.Xml.Schema.ValidationEventHandler(readerSettings_ValidationEventHandler);

//6) Create the xmlReader that will read the XML file using our reader settings
XmlReader xmlReader = XmlTextReader.Create(xmlStream, readerSettings);

//7) Now read the file
while (xmlReader.Read())