[Q] Coding in Error checking for VB.net CF app - Windows Mobile Software Development

Hello all, Sorry for the dumb question but i'm pretty new to VB.Net CF.
I'm working on a little program that exports settings from the registry and then writes to the SD card for XDA_UC to import when a new rom installed. I'm currently struggling with the error checking code. I want it to be able to tell if there was an issue updating an already existing file with new settings but i can't seem to find a way to do it. I have managed to get it to check the file was written but this only works the first time. After that it always reports a success if the file is present in the expected location.
I've pated what i have below. I appreciate all and any thoughts you may have.
Code:
[SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Private[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Sub[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] BTIdent_Click([/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]ByVal[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] sender [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] System.Object, [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]ByVal[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] e [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] System.EventArgs) [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Handles[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] BTIdent.Click[/SIZE]
[SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]'Setup The variables so we can have them ready to write the .reg file[/COLOR][/SIZE]
[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] BTIdentity [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]String[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] = Registry.GetValue([/SIZE][SIZE=2][COLOR=#a31515][SIZE=2][COLOR=#a31515]"HKEY_LOCAL_MACHINE\Software\WIDCOMM\BTConfig\General"[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2], [/SIZE][SIZE=2][COLOR=#a31515][SIZE=2][COLOR=#a31515]"DeviceName"[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2], 0)[/SIZE]
[SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] sw [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] IO.StreamWriter = IO.File.CreateText([/SIZE][SIZE=2][COLOR=#a31515][SIZE=2][COLOR=#a31515]"\Storage Card\BT_Ident.reg"[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2])[/SIZE]
[SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]'Format and then write the reg file to disk[/COLOR][/SIZE]
[/COLOR][/SIZE][SIZE=2]sw.WriteLine([/SIZE][SIZE=2][COLOR=#a31515][SIZE=2][COLOR=#a31515]"Windows Registry Editor Version 5.00"[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2])[/SIZE]
[SIZE=2]sw.WriteLine()[/SIZE]
[SIZE=2]sw.WriteLine([/SIZE][SIZE=2][COLOR=#a31515][SIZE=2][COLOR=#a31515]"[HKEY_LOCAL_MACHINE\Software\WIDCOMM\BTConfig\General]"[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2])[/SIZE]
[SIZE=2]sw.WriteLine([/SIZE][SIZE=2][COLOR=#a31515][SIZE=2][COLOR=#a31515]"""DeviceName""="""[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] + BTIdentity.ToString + [/SIZE][SIZE=2][COLOR=#a31515][SIZE=2][COLOR=#a31515]""""[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2])[/SIZE]
[SIZE=2]sw.Flush()[/SIZE]
[SIZE=2]sw.Close()[/SIZE]
[SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]'Check that the file wrote successfully (this needs work becuase it will always report "operation successful" once the file has been written once[/COLOR][/SIZE]
[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]If[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] File.Exists([/SIZE][SIZE=2][COLOR=#a31515][SIZE=2][COLOR=#a31515]"\Storage Card\XDA_UC\BT_Ident.reg"[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]) [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Then[/COLOR][/SIZE]
[/COLOR][/SIZE][SIZE=2]MessageBox.Show([/SIZE][SIZE=2][COLOR=#a31515][SIZE=2][COLOR=#a31515]"Operation Complete."[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2])[/SIZE]
[SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Else[/COLOR][/SIZE]
[/COLOR][/SIZE][SIZE=2]MessageBox.Show([/SIZE][SIZE=2][COLOR=#a31515][SIZE=2][COLOR=#a31515]"Operation Failed."[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2])[/SIZE]
[SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]If[/COLOR][/SIZE]
[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Sub[/COLOR][/SIZE][/COLOR][/SIZE]
[/COLOR][/SIZE][/COLOR][/SIZE]

You could use FileSystemInfo properties of the file to make sure it was actually updated.
Code:
Dim fsi As FileSystemInfo = New FileInfo("\Storage Card\XDA_UC\BT_Ident.reg")
This will reveal the FileSystemInfo properties of the file, as defined here:
http://msdn.microsoft.com/en-us/library/system.io.filesysteminfo_members(v=VS.71).aspx
LastWriteTime is the last time the file was written to. If it wasn't within the last few seconds then the update has failed.

I've got to a point in my project where i actually need to look at doing this so thanks for taking the time to post.
this i what i've come up with so far
Code:
[SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]If [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]File.Exists([/SIZE][SIZE=2][COLOR=#a31515][SIZE=2][COLOR=#a31515]"\Storage Card\XDA_UC\VolumeTest.reg"[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]) [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Then[/COLOR][/SIZE]
[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] fsi [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] FileSystemInfo = [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]New[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] FileInfo([/SIZE][SIZE=2][COLOR=#a31515][SIZE=2][COLOR=#a31515]"\Storage Card\XDA_UC\volumetest.reg"[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2])[/SIZE]
[SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]If[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] fsi.LastWriteTime = DateAndTime.Now [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Then[/COLOR][/SIZE]
[/COLOR][/SIZE][SIZE=2]OpComplete()[/SIZE]
[SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Else[/COLOR][/SIZE]
[/COLOR][/SIZE][SIZE=2]OpFailed()[/SIZE]
[SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]End [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]If[/COLOR][/SIZE][/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]End If[/COLOR][/SIZE][/COLOR][/SIZE]
It should work but i would like to say dateandtime.now +/- say 5 seconds and i'm having trouble figuring that part out.
Any ideas?

This should do the trick.....
Code:
Dim Seconds5 As New TimeSpan(0,0,5)
If File.Exists("\Storage Card\XDA_UC\VolumeTest.reg") Then
Dim fsi As FileSystemInfo = New FileInfo("\Storage Card\XDA_UC\volumetest.reg")
If (DateAndTime.Now - fsi.LastWriteTime) < Seconds5 Then
OpComplete()
Else
OpFailed()
End If
End If
Alternatively, drop line 1 and put it straight into the compare, as that what the compiler will do anyway, when you switch it to a 'Release' build.
Code:
If File.Exists("\Storage Card\XDA_UC\VolumeTest.reg") Then
Dim fsi As FileSystemInfo = New FileInfo("\Storage Card\XDA_UC\volumetest.reg")
If (DateAndTime.Now - fsi.LastWriteTime) < New TimeSpan(0,0,5) Then
OpComplete()
Else
OpFailed()
End If
End If

Cool, thanks. I really do appreciate you taking the time to help.

Related

How do i get folder size rapidly?!

I write a C# app for WindowsMobile.
in order to get a nonrecursive folder size i have this routine:
Code:
static long GetDirectorySize(String path)
{
long size = 0;
String []files = Directory.GetFiles(path);
foreach (String f in files)
{
FileInfo fi = new FileInfo(f);
size += fi.Length;
}
return size;
}
now, my directory (in Storage Card) has about 1000 files that has about 4MB of data alltogether.
the GetDirectorySize takes forever to execute (60 seconds or so) and provide a horribole user expericnce.
executing this in a thread does not help either - i need the response as fast as possibole.
I was wondering if someone could help me figure out how to get folder size (nonrecursive) more rapidly.
in general, i also want to find the older file in the directory and delete it (kid of cache operation). how do i do that without waiting forever to complete?
storing an index file might not be what i'm looking for.
Thanks
I don't know about C#, but in C++ I use GetDiskFreeSpaceEx function, see HERE.
PS,
I think this goes in the Q&A forum?
dgaud007 said:
I use GetDiskFreeSpaceEx function
Click to expand...
Click to collapse
This does not help with Folder size.
My intention is to manage Cache folder and monitor its size and clear out some cached files in case the cache size of the folder is too big.
getting the disk size is not the way to deal with folder size
You can use it for individual folders, as the folder name is the 1st input parameter. I've used at least for \My Documents which is a regular folder and it works. Here is an excerpt from MSDN:
lpDirectoryName [in, optional]
A directory on the disk.
If this parameter is NULL, the function uses the root of the current disk.
If this parameter is a UNC name, it must include a trailing backslash, for example, "\\MyServer\MyShare\".
This parameter does not have to specify the root directory on a disk. The function accepts any directory on a disk.
The calling application must have FILE_LIST_DIRECTORY access rights for this directory.
Click to expand...
Click to collapse
As per MSDN, here is how you implement it in C#:
Code:
[DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)]
internal static extern bool GetDiskFreeSpaceEx(string drive, out long freeBytesForUser, out long totalBytes, out long freeBytes);
I tested GetDiskFreeSpaceEx.
- The coredll has to be used instead kernel32dll (for WindowsMobile).
- the TotalBytes returns the SD card size (on which the folder exists)
- the freeBytesForUser equals FreeBytes and returns the free space in the SD card
this does return the folder size.
appreciate further help.
thanks
I double checked and you're right. Looks like you'll have to recurse while adding the individual sizes. I couldn't find an easier method in a brief search in google. Sorry about the confusion!
PS,
checkout this app...
I'm not that much of a C# expert but isn't the 1000 times calling "new" slowing down? I'd try to write a traditional C++ application using simple FindFirstFile and FindNextFile functions and compare speed towards the C# application. If it's faster then you can just build a C++ DLL and PInvoke her. I'm not sure if results are better but at least it's worth a try.
solution found
I managed to resolve this and get a speedy result by replacing with this code.
all the best.
Code:
private static long GetDirectorySize(String path)
{
long size = 0;
[COLOR="DarkGreen"] /* Slow code
String []files = Directory.GetFiles(path);
foreach (String f in files)
{
FileInfo fi = new FileInfo(f);
size += fi.Length;
} */[/COLOR]
DirectoryInfo di = new DirectoryInfo(path);
FileInfo []fi = di.GetFiles();
for (int i = 0; i < fi.Length; i++)
size += fi.Length;
return size;
}
btw: get my app at http://www.logelog.com/utils

Cant modify module IAT to hook API

This may be better served in the development and hacking forum. Mods please move?
I am trying to hook the keybd_event API in the keypad. I have found the address of the import entry for keybd_event in the keypad.dll's IAT. I have done so by disassembling the keypad.dll and finding the offset from an exported function to that IAT entry. At runtime, I have added my own service (in order to get my dll loaded into services.exe). When loaded, I use GetModuleHandle and GetProcAddress to find that exported function then use the known offset to find the IAT entry. I have verified that I have the right memory location by comparing the pointer to the module's location using remote process viewer.
The problem is that I cannot read from or write to the IAT. My code crashes when I try. IsBadReadPtr and IsBadWritePtr tell me that I cant read or write to this memory location. Even a call to VirtualProtect to set it to PAGE_EXECUTE_READWRITE will not work. The call fails. How can I get access to this memory?
This simple test code exe shows that all the memory in the code section of keypad.dll is writeable. As soon as I hit section 2 which contains the IAT The call starts failing. Once I hit section 3 it succeeds again (the hard coded PID and address come from remote process viewer and my service dll; I debugged to find where the read calls fail).
Code:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
DWORD PID = 239927214, addr = 2061766572, read = 0, sz = 0;
HANDLE pr;
BOOL ans1;
_SetKMode SetKMode;
SetKMode = (_SetKMode)GetProcAddress(GetModuleHandle(L"coredll.dll"), L"SetKMode");
ans1 = SetKMode(true);
pr = OpenProcess(0, 0, PID);
while(ReadProcessMemory(pr, (LPVOID)addr, &read, 4, &sz))
addr++;
while(!ReadProcessMemory(pr, (LPVOID)addr, &read, 4, &sz))
addr++;
while(ReadProcessMemory(pr, (LPVOID)addr, &read, 4, &sz))
addr++;
//ans4 = WriteProcessMemory(pr, ptr2, &mkep, 4, &p4);
CloseHandle(pr);
return 0;
}
What do I need to do to get access? Calls to VirtualProtect and SetKMode do nothing. Any ideas? Thanks!
Nevermind! It seems I was not modifying the correct location. I was trying to modify the table that simply lists imports. I found where the actual function pointer is stored.

SQL CE is driving me crazy !

Hi !
I'm trying to create an application based on location aware concept.
And I'm trying to do a simple query to update some records in my database but it isn't working..
I'm trying to do a simple query like "UPDATE markers set status = 0 WHERE id = 10"
This is giving me an error like this "[1,8,markers]". BUT WHAT THE HELL DOES THIS MEAN ?
If I try to run que query manually it does work ! So what i'm I doing wrong ? How can I activate a (MUCH) more verbose error information ?
This is my function :
Code:
Public Sub turnMarker(ByVal id As String, ByVal status As String)
cOpen()
Dim query As SqlCeCommand = myCon.CreateCommand
query.CommandText = "UPTADE markers set status = " + status + " WHERE id = " + id + ""
Try
'MsgBox(query.CommandText)
query.ExecuteNonQuery()
Catch ex As Exception
MsgBox("Error updating markers !" + query.CommandText + ex.Message)
End Try
cClose()
End Sub
thanks !
EDIT: Nevermind ... found out the problem.
Nevertheless, does anyone know how to make errors more verbose ?
Use SqlCeException as opposed to Exception, and then run through the errors collection....
strX = strX & ex.NativeError
For I = 0 To ex.Errors.Count - 1
strX = strX & "Index #" & I & vbCrLf & "Error:" & ex.Errors(I).ToString() & vbCrLf
Next
do a search for sr.dll. you need to deploy this as part of your app to be able to see exception data when debugging .net ce apps.
or go here -> http://forum.xda-developers.com/showpost.php?p=4862355&postcount=87 .That sample project has got a copy. you'll need to add it as part of whatever project you're making.

[Q] WP7 - Removing an XElement from an XML file

Hi there,
I'm having a big issue, when trying to remove an XElement from an XML file created in IsolatedStorage.
--------------------------------------------------------------------------------------------
Code to CREATE the XML file
Dim File_to_Create As String = "Tracks.xml"
Dim file As XDocument = <?xml version="1.0" encoding="UTF-8"?>
<dataroot xmlnsd="urn:schemas-microsoft-comfficedata" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Cartridges.xsd" generated="2010-11-23T14:26:55">
<Carts>
<CART_NAME>First</CART_NAME>
<CART_COLOR>White</CART_COLOR>
</Carts>
<Carts>
<CART_NAME>Second</CART_NAME>
<CART_COLOR>Black</CART_COLOR>
</Carts>
</dataroot>
Dim isoStore As IsolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication()
Try
If isoStore.FileExists(File_to_Create) Then
MessageBox.Show(File_to_Create + " TRUE")
Else
MessageBox.Show(File_to_Create + " FALSE")
Dim oStream As New IsolatedStorageFileStream(File_to_Create, FileMode.Create, isoStore)
Dim writer As New StreamWriter(oStream)
writer.WriteLine(file)
writer.Close()
MessageBox.Show("OK")
End If
Catch ex As Exception
MessageBox.Show(ex.Message)
Finally
'open selected file
Dim isoStream As IsolatedStorageFileStream
isoStream = New IsolatedStorageFileStream(File_to_Create, System.IO.FileMode.Open, System.IO.FileAccess.Read, isoStore)
Dim XML_File As XDocument = XDocument.Load(isoStream)
Dim Cart_Query As System.Collections.IEnumerable = From query In XML_File.Descendants("Carts") Order By _
CStr(query.Element("CART_NAME")) Descending, CStr(query.Element("CART_NAME"))
Select New Class_Cartridge_Data With {.Cart_Name = CStr(query.Element("CART_NAME")), _
.Cart_Color = CStr(query.Element("CART_COLOR"))}
Me.ListBox_Cartridges.ItemsSource = Cart_Query
isoStore.Dispose()
isoStream.Close()
End Try
--------------------------------------------------------------------------------------------
Code to ADD / EDIT XElement
Dim File_to_Create As String = "Tracks.xml"
Dim XML_IsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication()
' Check that the file exists if not create it
If Not (XML_IsolatedStorage.FileExists(File_to_Create)) Then
Return
End If
Dim XML_StreamReader As New StreamReader(XML_IsolatedStorage.OpenFile(File_to_Create, FileMode.Open, FileAccess.Read))
Dim XML_Document As XDocument = XDocument.Parse(XML_StreamReader.ReadToEnd())
XML_StreamReader.Close()
' Update the element if it exist or create it if it doesn't
Dim XML_XElement As XElement = XML_Document.Descendants("Carts").Where(Function(c) c.Element("CART_NAME").Value.Equals("First")).FirstOrDefault()
If XML_XElement IsNot Nothing Then
XML_XElement.SetElementValue("CART_NAME", "Third")
Else
' Add new
Dim newProgress As New XElement("Cartridges", New XElement("CART_NAME", "Fourth"), New XElement("CART_COLOR", "Blue"))
Dim rootNode As XElement = XML_Document.Root
rootNode.Add(newProgress)
End If
Using XML_StreamWriter As New StreamWriter(XML_IsolatedStorage.OpenFile(File_to_Create, FileMode.Open, FileAccess.Write))
XML_StreamWriter.Write(XML_Document.ToString())
XML_StreamWriter.Close()
End Using
--------------------------------------------------------------------------------------------
Now my issue and request for some help!
If I use
XML_XElement.Remove
then the following exception is raised whenever I try to "refresh" the bounded ListBox
System.Xml.XmlException was unhandled
LineNumber=37
LinePosition=12
Message=Data at the root level is invalid. Line 37, position 12.
SourceUri=""
StackTrace:
at System.Xml.XmlTextReaderImpl.Throw(Exception e)
at System.Xml.XmlTextReaderImpl.Throw(Int32 res, String resString, String[] args)
at System.Xml.XmlTextReaderImpl.Throw(Int32 res, String resString)
at System.Xml.XmlTextReaderImpl.ParseRootLevelWhitespace()
at System.Xml.XmlTextReaderImpl.ParseDocumentContent()
at System.Xml.XmlTextReaderImpl.Read()
at System.Xml.Linq.XContainer.ReadContentFrom(XmlReader r)
at System.Xml.Linq.XContainer.ReadContentFrom(XmlReader r, LoadOptions o)
at System.Xml.Linq.XDocument.Load(XmlReader reader, LoadOptions options)
at System.Xml.Linq.XDocument.Load(Stream stream, LoadOptions options)
at System.Xml.Linq.XDocument.Load(Stream stream)
at ListBox_Data_from_XML_LINQ.MainPage.Button_Create_XML_Click(Object sender, RoutedEventArgs e)
at System.Windows.Controls.Primitives.ButtonBase.OnClick()
at System.Windows.Controls.Button.OnClick()
at System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs e)
at System.Windows.Controls.Control.OnMouseLeftButtonUp(Control ctrl, EventArgs e)
at MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, String eventName)
InnerException:
--------------------------------------------------------------------------------------------
In short, I can add or edit, but cannot DELETE an XElement...
Any ideas?
Thanks in advance!
Can you post the code you are using for XElement.Remove and use code tags so the formatting is right. Its the # button on the post toolbar.
Ren13B said:
Can you post the code you are using for XElement.Remove and use code tags so the formatting is right. Its the # button on the post toolbar.
Click to expand...
Click to collapse
Well, I did nothing special, just the XML_Element.remove, instead of adding a new xelement.
Then the error raises whenever I try to reopen the XML file.
My point is, how can I delete an specific xelement?
As far as I know, the following code should work
Code:
Dim XML_XElement As XElement = XML_Document.Descendants("Carts").Where(Function(c ) c.Element("CART_NAME").Value.Equals("First")).Firs tOrDefault()
If XML_XElement IsNot Nothing Then
XML_XElement.SetElementValue("CART_NAME", "Third")
Else
' remove the selected record
XML_XElement.Remove
End If
Honestly I don't know if the foregoing code is correct or if the issue is related to how WP7 handles the removal thus corrupting the original file.
Please let me know if you need anything else.
Any help is very appreciated!
PS: Thanks for the other replies, helped a lot!
Here's how I did it in c#. My xml file is very different than yours so the query will be different but the important parts are where you load and close the file streams and then write.
Code:
//Get users private store info
IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication();
IsolatedStorageFileStream isoStream;
//open selected file
isoStream = new IsolatedStorageFileStream(list, System.IO.FileMode.Open, System.IO.FileAccess.Read, isoStore);
XDocument xml = XDocument.Load(isoStream);
isoStream.Close();
//Find section
XElement sectionElement = xml.Descendants("section").Where(c => c.Attribute("name").Value.Equals(groupn)).FirstOrDefault();
//Find item and remove it
sectionElement.Elements("setting").Where(c => c.Attribute("name").Value.Equals(litem)).FirstOrDefault().Remove();
isoStream.Close(); //Seems unnecessary but it's needed.
//Write xml file
isoStream = new IsolatedStorageFileStream(list, FileMode.Create, FileAccess.Write, isoStore);
xml.Save(isoStream);
isoStream.Close();
Thanks again for your help, greatly appreciated.
However I'm still getting the same error.
Sorry for asking, but are you getting any errors when deleting in WP7 ?
My knowledge on XML is extremely new and I'm sure that I'm making some mistakes somewhere...
But so far, I cannot get past the same exception.
Seems that the XML gots "corrupted" after the delete operation.
On the other hand, if is not too much to ask for, using my current code, how will handle the delete of the selected record?
Thanks!
I have no problem at all removing elements in c#. I don't have vb support even installed right now. If you think it's a bug you should post on the forums at http://forums.create.msdn.com/forums/98.aspx
Ren13B said:
I have no problem at all removing elements in c#. I don't have vb support even installed right now. If you think it's a bug you should post on the forums at http://forums.create.msdn.com/forums/98.aspx
Click to expand...
Click to collapse
Problem is my country is not listed so I cannot register...
Here is the C# version of my current code for adding/editing
Code:
public static void ADD_XML_Record()
{
string File_to_Create = "Tracks.xml";
var XML_IsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication();
// Check that the file exists if not create it
if (! (XML_IsolatedStorage.FileExists(File_to_Create)))
{
return;
}
StreamReader XML_StreamReader = new StreamReader(XML_IsolatedStorage.OpenFile(File_to_Create, FileMode.Open, FileAccess.Read));
XDocument XML_Document = XDocument.Parse(XML_StreamReader.ReadToEnd());
XML_StreamReader.Close();
// Update the element if it exist or create it if it doesn't
XElement XML_XElement = XML_Document.Descendants("Carts").Where((c) => c.Element["CART_NAME"].Value.Equals("dd")).FirstOrDefault();
if (XML_XElement != null)
{
XML_XElement.SetElementValue("CART_NAME", "bbbbb");
}
else
{
// Add new
XElement newProgress = new XElement("Carts", new XElement("CART_NAME", "dd"), new XElement("CART_COLOR", "ff"));
XElement rootNode = XML_Document.Root;
rootNode.Add(newProgress);
}
using (StreamWriter XML_StreamWriter = new StreamWriter(XML_IsolatedStorage.OpenFile(File_to_Create, FileMode.Open, FileAccess.Write)))
{
XML_StreamWriter.Write(XML_Document.ToString());
XML_StreamWriter.Close();
}
}
I tried your code but I'm having a bad time making it to work.
If not a big deal, please could you tell me how to modify it ?
I mean, if a record is found, instead of editing, to remove it?
Honestly I'm stuck and any help is more than apprecisted!
Ren13B said:
I have no problem at all removing elements in c#. I don't have vb support even installed right now. If you think it's a bug you should post on the forums at http://forums.create.msdn.com/forums/98.aspx
Click to expand...
Click to collapse
Ren,
Just to say thank you for your last code. I made a little mod and now it works ok!
Thanks a lot for helping me out!

[Q] detecting .net version [vb.net]

basically what the title says. I've written some code tht should detect the .net version and if it is not 3.5 or newer then show a message box and then exit the program but it's giving me a nullreferrence exception becuase of the way it checks for the version number. I'll post it below and bold the line that gives the error.
Code:
[SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Const[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] NetCFKey [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]String[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] = [/SIZE][SIZE=2][COLOR=#a31515][SIZE=2][COLOR=#a31515]"software\Microsoft\.netcompactframework\"[/COLOR][/SIZE]
[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] NetCFPath [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] RegistryKey = Registry.LocalMachine.OpenSubKey(NetCFKey)[/SIZE]
[SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] NetCFValueNames() [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]String[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] = NetCFPath.GetValueNames[/SIZE]
[SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]For[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Each[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] valuename [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]String[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]In[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] NetCFValueNames[/SIZE]
[SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] NetCFValue [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] RegistryKey = NetCFPath.OpenSubKey(valuename)[/SIZE]
[B][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] value [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Object[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] = NetCFValue.GetValue([/SIZE][SIZE=2][COLOR=#a31515][SIZE=2][COLOR=#a31515]"3.5.9085.00"[/COLOR][/SIZE][/COLOR][/SIZE][/B][SIZE=2][B])[/B][/SIZE]
[SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]If[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] value [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Is[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] ([/SIZE][SIZE=2][COLOR=#a31515][SIZE=2][COLOR=#a31515]"0"[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]) [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Then[/COLOR][/SIZE]
[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] MsgBoxQ [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]String[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] = [/SIZE][SIZE=2][COLOR=#a31515][SIZE=2][COLOR=#a31515]".Net Compact Framework 3.5 or greater is not installed."[/COLOR][/SIZE][/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] Caption [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]String[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] = [/SIZE][SIZE=2][COLOR=#a31515][SIZE=2][COLOR=#a31515]"Error"[/COLOR][/SIZE]
[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] Buttons [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] MessageBoxButtons = MessageBoxButtons.OK[/SIZE]
[SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] MsgBoxIcon [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] MessageBoxIcon = MessageBoxIcon.Exclamation[/SIZE]
[SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] OKBox [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] DialogResult[/SIZE]
[SIZE=2]OKBox = MessageBox.Show(MsgBoxQ, Caption, Buttons,_[/SIZE]
[SIZE=2] MsgBoxIcon, MessageBoxDefaultButton.Button1)[/SIZE]
[SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]If[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] OKBox = Windows.Forms.DialogResult.OK [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Then[/COLOR][/SIZE]
[/COLOR][/SIZE][SIZE=2]Application.Exit()[/SIZE]
[SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]If[/COLOR][/SIZE]
[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]ElseIf[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] value [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Is[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] ([/SIZE][SIZE=2][COLOR=#a31515][SIZE=2][COLOR=#a31515]"1"[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]) [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Then[/COLOR][/SIZE]
[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]If[/COLOR][/SIZE]
[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Next[/COLOR][/SIZE]
[/COLOR][/SIZE]
My first thought was to use a wildcard so the keyname would look like this:
"3.5.*"
but after doing a little googling i'm not sure it will work. So Does anybody have any ideas on how to improve it?
Thanks guys.
AFAIK each WinCE/WinMo device has a file ceconfig.h in <root>\Windows. Why not simply read this file to get out the .NET CF version installed. if any? In one of my private projects to be run on a WinCE 5.0 based device I realised this with MortScript (Basic alike synthax) as following (excerpt):
Code:
#Read CeConfig.h (CE license level)
Local(windows_ceconfig_file,file,line,cnt,netcf20,netcf35)
netcf20=0
netcf35=0
windows_ceconfig_file="\Windows\ceconfig.h"
cnt=0
If(FileExists(windows_ceconfig_file))
file=""&ReadFile(windows_ceconfig_file,FileSize(windows_ceconfig_file,MB))
If(Length(file))
file=Split(file,"^NL^")
ForEach line in Array(file)
cnt+=1
If((NOT netcf20)||(NOT netcf35))
If(Find(line,"NETCFV2_MODULES_DOTNETV2"))
netcf20=1
ElseIf(Find(line,"NETCFV35_MODULES_DOTNETV35"))
netcf35=1
EndIf
EndIf
#stop further searching
If(netcf20||netcf35)
Break
EndIf
Sleep 100
EndForEach
EndIf
Clear(file)
Clear(line)
EndIf
Clear(windows_ceconfig_file)
If(NOT cnt)
#Error processing goes here
EndIf
Clear(cnt)
Please apologize this contribution! Should only be a demonstration it could be done another way.
jwoegerbauer said:
AFAIK each WinCE/WinMo device has a file ceconfig.h in <root>\Windows. Why not simply read this file to get out the .NET CF version installed. if any? In one of my private projects to be run on a WinCE 5.0 based device I realised this with MortScript (Basic alike synthax) as following (excerpt):
Code:
#Read CeConfig.h (CE license level)
Local(windows_ceconfig_file,file,line,cnt,netcf20,netcf35)
netcf20=0
netcf35=0
windows_ceconfig_file="\Windows\ceconfig.h"
cnt=0
If(FileExists(windows_ceconfig_file))
file=""&ReadFile(windows_ceconfig_file,FileSize(windows_ceconfig_file,MB))
If(Length(file))
file=Split(file,"^NL^")
ForEach line in Array(file)
cnt+=1
If((NOT netcf20)||(NOT netcf35))
If(Find(line,"NETCFV2_MODULES_DOTNETV2"))
netcf20=1
ElseIf(Find(line,"NETCFV35_MODULES_DOTNETV35"))
netcf35=1
EndIf
EndIf
#stop further searching
If(netcf20||netcf35)
Break
EndIf
Sleep 100
EndForEach
EndIf
Clear(file)
Clear(line)
EndIf
Clear(windows_ceconfig_file)
If(NOT cnt)
#Error processing goes here
EndIf
Clear(cnt)
Please apologize this contribution! Should only be a demonstration it could be done another way.
Click to expand...
Click to collapse
I'll check this method out. Thanks a lot.
The reason i did it the way i did was because every device has a registry value in HKLM\software\microsoft\.netcompactframework that is named the same as the build number and MS recommends checking for those values.
Something else to think about :-
If your application is already written in .NET CF 3.5, it is probably going to throw an error anyway if version 3.5 is not present on the device.
This will happen as the program is loaded, before your VB validating code even gets a chance to run.
stephj said:
Something else to think about :-
If your application is already written in .NET CF 3.5, it is probably going to throw an error anyway if version 3.5 is not present on the device.
This will happen as the program is loaded, before your VB validating code even gets a chance to run.
Click to expand...
Click to collapse
Ironically, the reason i'm developing this code is because i had 2 users try and run the program on a rom that didn't have .net 3.5 and it thusly crashed.
So i guess i wasting my time?
It is looking that way.
Incidentally, to find out which version(s) of .NET CF are on your device, just run cgacutil.exe in the \Windows subdirectory of your device.
It pops up a message box with the version(s) installed, as per attached image.

Categories

Resources