|
Have you tried the Save method of the XmlDocument class??
|
|
|
|
|
Using XmlDocument.Save throws the same error - file is in use by another process
|
|
|
|
|
What does the code look like that's loading the XML document?? Save and WriteTo both work on a document that's been loaded by XmlDocument.LoadXml, so this has to be caused by some other reader or permissions issue.
|
|
|
|
|
Right now, the code is:
Dim CurDir As String = Environment.CurrentDirectory() & "\globalConfig.xml"
Try
Dim sr As New System.IO.StreamReader(CurDir)
Dim globalConfig As Xml.XmlDocument = New Xml.XmlDocument()
globalConfig.Load(CurDir)
Dim buildingList As Xml.XmlNodeList
Dim root As Xml.XmlElement = globalConfig.DocumentElement
buildingList = root.SelectNodes("/config/buildings/name")
Dim info As Xml.XmlNode
' xml text writer - used for writing for xml document
For Each info In buildingList
If info.InnerText = buildingName Then
info.NextSibling.InnerText = resource
End If
Next
globalConfig.WriteTo(CurDir)
[...]
I shall using XmlDocument.LoadXML...
Matt
|
|
|
|
|
OK. We'll start with line number 1:
CocaColaBoy wrote: Dim CurDir As String = Environment.CurrentDirectory() & "\globalConfig.xml"
Bad idea. CurrentDirectory is NOT a static directory. Annyone who's ever just thrown around an OpenFileDialog knows that the current directory can change at any time. A more proper method is to use a well-known folder that doesn't change, like Application.StartupPath . Also, don't use string concatenation to build paths, use something that's designed for the task:
Dim filePath As String = Path.Combine(Application.StartupPath, "globalConfig.xml")
CocaColaBoy wrote: Dim sr As New System.IO.StreamReader(CurDir)
Dim globalConfig As Xml.XmlDocument = New Xml.XmlDocument()
globalConfig.Load(CurDir)
Dim buildingList As Xml.XmlNodeList
...
Yikes. You're opening a file on the first line of this section, but never using it, nor ever CLOSING it either. This is where your problem originated from. Then, in the next line, you're using the XmlDocument.Load method to grab the contents of the .xml file. You can have two processes (or the same process in this case) both read the same file at the same time, but writing to an already open file usually requires exclusive access to the file. In your case, you've guaranteed that exclusive access is impossible by putting creating the StreamReader instance at the top of your code.
|
|
|
|
|
Dave Kreskowiak wrote: OK. We'll start with line number 1
I'm guessing I've headed in the wrong direction? Hmmm... not a good start.
The purpose of using Environment.CurrentDirectory is that the location of this application will vary somewhat. Would:
Dim filePath As String = Path.Combine(Application.StartupPath, "globalConfig.xml")
...achieve the same thing?
Basically I am trying to update an XML document that is opened in:
Dim globalConfig As Xml.XmlDocument = New Xml.XmlDocument()
globalConfig.Load(CurDir)
...and, yeah, now you point this out, filePath would definitely been a much better name!
I guess my next question would be: how do I open an XML file for exclusive access? Would this allow for read/write access. I'm guessing so?
|
|
|
|
|
OK... so I now have working what I wanted in the first place... and I want to thank you for your help.
Anyhow, for reference purposes, here is the working code:
Public Function setBuildingInfo(ByVal buildingName As String, ByVal resource As String) As String
' create and open XML document
Dim CurDir As String = Environment.CurrentDirectory() & "\globalConfig.xml"
Try
'Dim sr As New System.IO.StreamReader(CurDir)
Dim globalConfig As Xml.XmlDocument = New Xml.XmlDocument()
globalConfig.Load(CurDir)
Dim buildingList As Xml.XmlNodeList
Dim root As Xml.XmlElement = globalConfig.DocumentElement
buildingList = root.SelectNodes("/config/buildings/name")
Dim info As Xml.XmlNode
' xml text writer - used for writing for xml document
For Each info In buildingList
If info.InnerText = buildingName Then
info.NextSibling.InnerText = resource
End If
Next
Dim writeDocument As Xml.XmlTextWriter = New Xml.XmlTextWriter("globalConfig.xml", _
System.Text.Encoding.Unicode)
globalConfig.WriteTo(writeDocument)
writeDocument.Close()
Catch ex As Exception
MessageBox.Show(Err.Description())
End Try
End Function
Where buildingName is what is being searched for in the document and resource is the replacement text!
Matt
|
|
|
|
|
CocaColaBoy wrote: I guess my next question would be: how do I open an XML file for exclusive access? Would this allow for read/write access. I'm guessing so?
They invented a couple of things called documentation and Google, so you can come up with
all the questions you want, and have a pretty good chance of finding the answers yourself
in a matter of minutes.
Have a look at the File.Open Method (String, FileMode, FileAccess, FileShare)
Luc Pattyn [Forum Guidelines] [My Articles]
This month's tips:
- before you ask a question here, search CodeProject, then Google;
- the quality and detail of your question reflects on the effectiveness of the help you are likely to get;
- use PRE tags to preserve formatting when showing multi-line code snippets.
|
|
|
|
|
CocaColaBoy wrote: The purpose of using Environment.CurrentDirectory is that the location of this application will vary somewhat. Would:
Dim filePath As String = Path.Combine(Application.StartupPath, "globalConfig.xml")
...achieve the same thing?
The problem with using CurrentDirectory is that the current directory can change during the execution of your app. Application.StartupPath always points to the folder your .EXE was launched from.
CocaColaBoy wrote: I guess my next question would be: how do I open an XML file for exclusive access? Would this allow for read/write access. I'm guessing so?
XmlDocument.Load only opens the file for shared read, share deny write, for as long as it needs to read the entire file. When the document is done loading, the file is closed.
If you wanted to retain an exlusive (basically share deny all) lock on the file, you'd have to open it using a FileStream instance. FileStream lets you specify a shared access setup when you create the filestream instance. You could then pass that stream the the XmlDocument.Load method to laod the document. Just remember to Seek the filestream back to position 0 before you try to write the XML back to the file, and, of course, close the filestream when your done.
|
|
|
|
|
I'm wondering which account to run my vb.net windows service under to allow it access to a server. I assume it's "user" but cant test it at the minute. Is there another way to allow this?
|
|
|
|
|
You have to use a user account that has access permissions to the network. There's no way around this. An application or service runs AS the user that launched it. Whatever permissions the user account has, that's what the application gets access to.
|
|
|
|
|
figured as much. Thanks anyway for the quick response!
|
|
|
|
|
I have a form with a combobox and a datagrid. When a selection is made in the combobox the datagrid populates based on the fk databinding. The combobox is binding to the name cell of the parent table so that the user can see what parent row he is on. My problem is that the combobox initially fills with the correct values, but when I move on to the second item in the list all of the names in the combobox become the name for index #1. The combobox grid still populates correctly but the combo box is showing the wrong names. So for instance if item #1 is Jill, and #2 is Tom, at first the combobox drop says Jill and Tom, but if I move down to Tom the datagrid populates with tom's related data but now the combobox will show Jill twice. If I now move to Jill #2, Tom's data populate below.
Thanks in advance for your help.
|
|
|
|
|
From your description, there shouldn't be any updates to the combobox at all. Are you binding the combo to the same table that's being shown in the datagrid?? Ideally, in a scalable solution, the combo should be bound to a table that only has the ID and name you're showing in the combo itself. Upon a selection, you should be retrieving the data to be shown in the datagrid into a seperate table and binding the grid to that.
Without seeing the code that set's up the datatables and bindings and the selection changed event of the combo, it's impossible to say what the problem is.
|
|
|
|
|
I am using the designer to handle most of the work but the setup is basically as you described...
tblWebsites
Columns:
Website ID Site_Name
tblProducts
Columns:
SKU WebsiteID ProductName
In designer I set the combobox datasource to WebSiteBindingSource and its display member to site_name. The datagrid's datasource is fkNicheProductsNicheSites. The problem occurs when I select site #2. The datagrid populates properly and then when I go back to the combobox site #1's name becomes the name for site # 2. However, when the first site is selected, even though it displays site #2's name, the grid fills with site #1's data (Implying it is on the correct row.) Like you said, I can't understand why the name value is changing.
|
|
|
|
|
OK, I duplicated the problem. Using the designer to do database work does NOT relinquish you from knowing how all this stuff works. IMHO, it actually makes it more difficult to understand.
First, delete all of the DataSet, TableAdapter and BindingSource objects from the form.
You'll need to set this up so there is a single DataSet object that contains both of your tables. In the DataSet Designer, make sure there is a one-to-many relationship between the two tables on their Website ID columns.
You also need a single BindingSource that has it's DataSource property set to the DataSet.
The ComboBox's DataSource property should be set to the BindingSource.tblWebSites table. It's DisplayMember property should then be set to the Site_Name field. At this point you should have a couple of new objects added automatically, a tblWebsites BindingSource and TableAdapter.
The DataGrid's DataSource property should be set to the new tblWebSites BindingSource.FK_tbl_WebSites_tblProducts. This is the foreign key relationship between the two tables.
That's it! It should be good to go.
|
|
|
|
|
hi
how can i print form using vb2008
please i need help
i have a lot of rich box nearly 45 richbox
please help
|
|
|
|
|
|
thanks i will see it
|
|
|
|
|
Try this :-
Public Class PrintForm<br />
<br />
Private _frmForm As Windows.Forms.Form<br />
Private _imgScreenShot As System.Drawing.Bitmap<br />
<br />
'API Calls to help generate final screenshot<br />
Private Declare Auto Function BitBlt Lib "gdi32.dll" _<br />
(ByVal hdcDest As IntPtr, ByVal nXDest As Integer, _<br />
ByVal nYDest As Integer, ByVal nWidth As Integer, _<br />
ByVal nHeight As Integer, ByVal hdcSrc As IntPtr, _<br />
ByVal nXSrc As Integer, ByVal nYSrc As Integer, _<br />
ByVal dwRow As System.Int32) As Boolean<br />
<br />
Public Sub New(ByRef Form As Windows.Forms.Form)<br />
_frmForm = Form<br />
End Sub<br />
<br />
Public Sub Print()<br />
GetScreen()<br />
Dim printDialog As New Windows.Forms.PrintDialog<br />
Dim printDocument As New System.Drawing.Printing.PrintDocument<br />
AddHandler printDocument.PrintPage, AddressOf printDocument_PrintPage<br />
printDialog.Document = printDocument<br />
If printDialog.ShowDialog = Windows.Forms.DialogResult.OK Then<br />
printDocument.Print()<br />
End If<br />
End Sub<br />
<br />
Public Sub Dispose()<br />
_imgScreenShot.Dispose()<br />
End Sub<br />
<br />
Private Sub GetScreen()<br />
Const SRCCOPY As Integer = &HCC0020<br />
<br />
Dim oGraphics As System.Drawing.Graphics = _frmForm.CreateGraphics<br />
Dim oSize As System.Drawing.Size = _frmForm.Size<br />
<br />
_imgScreenShot = New System.Drawing.Bitmap(oSize.Width, oSize.Height, oGraphics)<br />
Dim oGraphics2 As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(_imgScreenShot)<br />
Dim deviceContext1 As IntPtr = oGraphics.GetHdc<br />
Dim deviceContext2 As IntPtr = oGraphics2.GetHdc<br />
<br />
BitBlt(deviceContext2, 0, 0, _frmForm.ClientRectangle.Width, _frmForm.ClientRectangle.Height, deviceContext1, 0, 0, SRCCOPY)<br />
oGraphics.ReleaseHdc(deviceContext1)<br />
oGraphics2.ReleaseHdc(deviceContext2)<br />
End Sub<br />
<br />
Private Sub printDocument_PrintPage(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs)<br />
Dim oImageToPrint As System.Drawing.Graphics = e.Graphics<br />
oImageToPrint.DrawImage(_imgScreenShot, 0, 0)<br />
oImageToPrint.Dispose()<br />
e.HasMorePages = False<br />
End Sub<br />
<br />
End Class
Then to print from your form :-
Dim oScreen as New PrintForm(me)<br />
oScreen.Print
Steve Jowett
-------------------------
It is offen dangerous to try and see someone else's point of view, without proper training. Douglas Adams (Mostly Harmless)
|
|
|
|
|
thanks it work
but it do not print the part at the right what is the argument you think i have to change
thank so much
|
|
|
|
|
asha_s wrote: but it do not print the part at the right what
Not really sure what you mean, but I assume that your form is wider than your paper. If this is the case you will need to resize the bitmap that is generated, so that it fits the paper.
Steve Jowett
-------------------------
It is offen dangerous to try and see someone else's point of view, without proper training. Douglas Adams (Mostly Harmless)
|
|
|
|
|
thanks Steve Jowett
sorry about latency
yes that what i mean but i do not know how to resize the bitmap con you tell me please
|
|
|
|
|
I think you will find that the Bitmap object has Height and Width properties. You will need to change these to resize the screen shot.
Steve Jowett
-------------------------
It is offen dangerous to try and see someone else's point of view, without proper training. Douglas Adams (Mostly Harmless)
|
|
|
|
|
|