How to close instance of an XML DOCUMENT - vb.net

While attempting to issue the SAVE of the XmlDocument class on an XML document, specifically on this line of code:
myXmlDocument.Save(strFileZillaFilePathAndName).
I get... During entry update - save of FileZilla file failed. The process cannot access the file 'C:\Program Files (x86)\FileZilla Server\FileZilla Server.xml' because it is being used by another process.
It occurs in the FindAndUpdateXMLEntries(...) method called from within my UpdateFtpAccountsProcess(...) function.
I thought that this use of the SAVE did not require a close.
It happens on a 2nd execution of the function so it seems that the file is not being closed. It should be closed by the 1st execution and it is not be being used by another process
Public Function UpdateFtpAccountsProcess(ByVal strIpAddress As String, ByVal strPassword As String, ByVal iBackupSpaceId As Integer, ByVal iFtpAccountId As Integer, ByVal strFtpAccountPassword As String, ByVal strAccountType As String) As Boolean Implements IBackupServerService.UpdateFtpAccountsProcess
Dim strErrorMessage As String = ""
' Start the backup service logging.
StartTheLog(iBackupSpaceId)
' Write an log entry.
strInputLogMessage = "In UpdateFtpAccountsProcess method."
LogAnEntry(strInputLogMessage)
' Validate the password arguement in order to use this WCF service method.
' Read the app.config files "appSettings" section to get the backup server password. If it matches, continue.
strEncryptedBackupServerPassword = GetAppSetting(strKeyPassword)
If strEncryptedBackupServerPassword = strPassword Then
' Update the FTP account's encrypted password by "backup space id" and "account type". The accounts are stored in the FileZilla Server.xml file.
' Read the app.config file to get the “FileZilla path and name”.
strFileZillaFilePathAndName = GetAppSetting(strKeyFileZilla)
' Read the app.config file to get the “FileZilla Application path and name”.
strFileZillaFileApplicationPathAndName = GetAppSetting(strKeyFileZillaApplication)
If ((strFileZillaFilePathAndName = "Not Found" Or strFileZillaFilePathAndName = "Error") Or (strFileZillaFileApplicationPathAndName = "Not Found" Or strFileZillaFileApplicationPathAndName = "Error")) Then
strErrorMessage = "During update of FTP accounts - cannot find the FileZilla entries in the app config. Space Id: " & iBackupSpaceId.ToString()
Else
Try
' Read the XML file and update the "password" of 1 of the 2 User entries [ftp accounts] - for the "backup space id".
FindAndUpdateXMLEntries(strFileZillaFilePathAndName, iBackupSpaceId, strFtpAccountPassword, strAccountType)
Try
' Execute command to run the FileZilla application to have FileZilla re-read the configuration.
ReloadFileZillaConfig(strFileZillaFileApplicationPathAndName)
Catch ex As Exception
strErrorMessage = "From: ReloadFileZillaConfig() ---> " & ex.Message
End Try
Catch ex As Exception
' Attach the message coming from the FindAndUpdateXMLEntries() method.
strErrorMessage = "During update of FTP account - Space Id: " & iBackupSpaceId.ToString() & " from: FindAndUpdateXMLEntries() ---> " & ex.Message
End Try
End If
Else
strErrorMessage = "During update of FTP accounts - invalid backup server password. It must match the app.config entry. Space Id: " & iBackupSpaceId.ToString()
End If
If strErrorMessage <> "" Then
Throw New System.Exception(strErrorMessage)
End If
' End the backup service logging.
EndTheLog()
Return bSuccess = True
End Function
Public Sub FindAndUpdateXMLEntries(ByVal strFileZillaFilePathAndName As String, ByVal iBackupSpaceId As Integer, ByVal strFtpAccountPassword As String, ByVal strAccountType As String)
Dim strErrorMessage As String = ""
Dim xmlNode1 As XmlNode
Dim xmlNode2 As XmlNode
Dim xmlNode3 As XmlNode
Dim strUserNodeAtrributeNameValue As String
Dim strUnderUserNodeThisNodesAtrributeNameValue As String
Dim bSuccess As Boolean = False
' The XmlDocument class represents the XML document and has a Load method to load the document from a file, stream, or an XmlReader.
' So load in the XML file.
Dim myXmlDocument As XmlDocument = New XmlDocument()
' Write an log entry.
strInputLogMessage = "In FindAndUpdateXMLEntries method."
LogAnEntry(strInputLogMessage)
Try
' Load in the XML file.
myXmlDocument.Load(strFileZillaFilePathAndName)
' Use the XmlNode object that the DocumentElement property of the XmlDocument returns to manipulate an XML node.
xmlNode1 = myXmlDocument.DocumentElement
' Field to match to under the "Users" node. Building the "#-Private" or "#-Private" User root node.
strUserNodeAtrributeNameValue = iBackupSpaceId.ToString() & "-" & strAccountType.Trim()
' The next field to match to under the "User" node that I find.
strUnderUserNodeThisNodesAtrributeNameValue = "Pass"
' Iterate thru to find the node to update.
For Each xmlNode1 In xmlNode1.ChildNodes
If xmlNode1.Name = "Users" Then
' Find the child nodes in "Users" only.
For Each xmlNode2 In xmlNode1.ChildNodes
' Find the "User" node that I want.
If xmlNode2.Attributes("Name").Value = strUserNodeAtrributeNameValue Then
For Each xmlNode3 In xmlNode2.ChildNodes
' Find the node that I want that is under the "User" node. Looking for: <Option Name="Pass">some value</Option>
If xmlNode3.Attributes("Name").Value = strUnderUserNodeThisNodesAtrributeNameValue Then
' Update the XML to the new password value.
xmlNode3.InnerText = strFtpAccountPassword
bSuccess = True
Exit For
End If
If bSuccess = True Then
Exit For
End If
Next
End If
Next
End If
If bSuccess = True Then
Exit For
End If
Next
If bSuccess = True Then
Try
' Use the Save method of the XmlDocument class to save the altered XML back to the input XML file.
myXmlDocument.Save(strFileZillaFilePathAndName)
Catch ex As Exception
strErrorMessage = "During entry update - save of FileZilla file failed. " & ex.Message
End Try
Else
strErrorMessage = "During entry update - No User node to update"
End If
Catch ex As Exception
strErrorMessage = "During entry update - load of FileZilla file failed. " & ex.Message
End Try
If strErrorMessage <> "" Then
Throw New System.Exception(strErrorMessage)
End If
End Sub

Related

vb.net cannot find file after file has been deleted and resaved by remote pc

I'm using a web page to create a file on a web server to control an Arduino device. The file gets created without issue. The problem exists when the VB app that controls the Arduino device reads the file and then deletes the file. After VB deletes the file the web app recreates the same file with new data. The VB app fails to see the new file. It still thinks the file has been deleted.
Here's the code:
Private Sub TimerCheck4CameraFile_Tick(sender As Object, e As EventArgs) Handles TimerCheck4CameraFile.Tick
Try
' Check if file exists if it doesn't leave this method.
Dim DirectoryList As New IO.DirectoryInfo("C:\inetpub\wwwroot")
Dim ArrayOfFilesFileInfo As IO.FileInfo() = DirectoryList.GetFiles("ServoDirection2Move.txt")
Dim Fi As IO.FileInfo
For Each Fi In ArrayOfFilesFileInfo
If String.Compare("ServoDirection2Move.txt", Fi.Name) <> 0 Then
TextBox1.Text += vbCrLf + "Did NOT Find File."
Exit Sub ' We DID NOT find the file so get out!
End If
Next
Catch ex As Exception
LabelStatus.Text = "Catch ex 1: " + ex.Message
End Try
' Read in the file.
Dim FileRead As String
Try
' **POSSIBLE ISSUE HERE**.
FileRead = My.Computer.FileSystem.ReadAllText("C:\inetpub\wwwroot\ServoDirection2Move.txt")
' Need better way to read txt file. It fails after file is deleted and can not read second file.
TextBox1.Text += vbCrLf + "Moving Value: " + FileRead
Catch ex As Exception
LabelStatus.Text = "Catch ex: " + ex.Message
End Try
' Check if it was UP.
If String.Compare("UP", FileRead) = 0 Then
' Delete the file to prepare for a new one.
System.IO.File.Delete("C:\inetpub\wwwroot\ServoDirection2Move.txt")
' Move servo to proper location.
Call PanningUp.PerformClick()
LabelStatus.Text = "Done Moving: UP" ' Update Status Bar.
TimerCheck4CameraFile.Enabled = True ' Turn timer back on.
Exit Sub
End If

Why does File.Open() not open the file?

I am implementing a Save File button in my VB.NET Windows Forms application.
I am attempting to encapsulate the normally expected behaviour of Save buttons in Windows applications. I.E: If a file was already selected then open the current file it, write to it and save it; else if there is no current file, or Save As was used, then show a SaveFileDialog, then open, write and save just the same.
I currently have coded the function below but I keep getting an exception:
Cannot access a closed file
The file is created just fine, but is empty (It should contain "Test string"). I can't understand how the file is closed unless some kind of garbage collection is doing away with it somehow??
The current code:
Function SaveFile(ByVal Type As ProfileType, ByVal suggestedFileName As String, ByVal saveAs As Boolean, ByVal writeData As String) As Boolean
Dim FileStream As Stream = Nothing
Dim FolderPath As String = Nothing
Dim CancelSave As Boolean = False
Dim SaveFileDialog As SaveFileDialog = New SaveFileDialog()
Try
If Type = ProfileType.Product Then 'Select the initial directory path
FolderPath = ProductPath
Else
FolderPath = ProfilePath
End If
If (FileName = String.Empty Or saveAs = True) Then 'If a file is not already selected launch a dialog to allow the user to select one
With SaveFileDialog
.Title = "Save"
.AddExtension = True
.CheckPathExists = True
.CreatePrompt = False
.DefaultExt = "xml"
.Filter = "Xml Files (*.xml)|*.xml"
.FilterIndex = 0
.FileName = suggestedFileName
.InitialDirectory = FolderPath
If .ShowDialog(Me) = Windows.Forms.DialogResult.OK Then
FullyQualfiedPathName = New String(SaveFileDialog.FileName) 'Save the path and name of the file
FileName = Path.GetFileName(FullyQualfiedPathName)
Else
CancelSave = True
End If
.Dispose()
End With
End If
If (FileName <> String.Empty) Then 'Write the string to the file if the filewas correctly selected
FileStream = File.Open(FullyQualfiedPathName, FileMode.OpenOrCreate, FileAccess.ReadWrite) 'Open the file
Using FileStreamWriter As New StreamWriter(FileStream) 'Create the stream writer
FileStreamWriter.Write(writeData) 'Write the data
FileStream.Close() 'Clse the file
End Using
ElseIf (CancelSave <> True) Then 'Only throw an exception if the user *didn't* cancel the SavefileDialog
Throw New Exception("File stream was nothing", New IOException())
End If
Catch ex As Exception
MessageBox.Show(ex.Message & Environment.NewLine & FullyQualfiedPathName)
End Try
Return True
End Function
One problem I see is that you should be putting your File.Open in a Using block:
Using fs = File.Open(fullyQualfiedPathName, FileMode.OpenOrCreate, FileAccess.ReadWrite)
Using writer As New StreamWriter(fs) 'Create the stream writer
writer.Write(writeData) 'Write the data
'fs.Close() <--- you do not need this line becuase the "Using" block will take care of this for you.
End Using
End Using
I'm not sure if this will resolve your issue because I can't run your code, but the Using block will automatically take care of closing and cleaning up disposable instances like FileStream and StreamWriter, even if an exception is thrown.
By the way, you should use proper naming conventions (lower camel case) for local variables.

Delete a single .txt file if exist in Visual Basic?

i have been trying to figure out how to delete a .txt file that constantly change name exept the first 4 ex: THISTEXT-123-45.txt where THISTEXT stays the same but -123-45 changes.
I have found a way to detect it, but i don't know how to delete it.
Dim paths() As String = IO.Directory.GetFiles("C:\", "THISTEXT*.txt")
If paths.Length > 0 Then
Anyone knows the command line to delete that special .txt file?
I am using Visual Basic on visual studio 2013 framework 3.5.
Use the Delete method of System.IO.
Assuming you have write access to C:\
Dim FileDelete As String
FileDelete = "C:\testDelete.txt"
If System.IO.File.Exists( FileDelete ) = True Then
System.IO.File.Delete( FileDelete )
MsgBox("File Deleted")
End If
Deleting a file is quite simple - but dangerous! So be very careful when you're trying out this code.
Edit
To delete all file use *(asterisk) followed with the file extension
example C:\*.txt"
For multiple files
Dim FileDelete As String
FileDelete = "C:\"
For Each FileDelete As String In IO.Directory.GetFiles(FileDelete & "THISTEXT*.txt")
File.Delete(FileDelete)
Next
If you read the MSDN page on GetFiles, you will realize that you have the file name and path in your paths array. You can then iterate through the array deleting your matches.
Dim x as Integer
Dim paths() as String = IO.Directory.GetFiles("C:\", "THISTEXT*.txt")
If paths.Length > 0 Then
For x = 0 to paths.Length -1
IO.File.Delete(paths(x))
Next
End If
To build on the feedback you provided to Omar's answer, it appears that your file path and file name are separate.
You cannot provide them separated by a comma, as commas denote separate parameters passed to a subroutine or function.
To fix this, you need to concatenate them, for example:
Dim fileName As String = "foo.txt"
Dim filePath As String = "C:\"
Dim FileToDelete As String = fileName + filePath
To delete a single .*txt file if it exists:
If (deleteFile("C:\")) Then
MsgBox("File deletion successful")
Else
MsgBox("File couldn't be deleted with the following error: " + exception)
End If
alternatively with concatenation:
If (deleteFile("C:\") Then
MsgBox("File deletion successful")
Else
MsgBox("File couldn't be deleted with the following error: " + exception)
End If
Dim exception As String 'Place this at the beginning of your app's class.
Dim path As String = "C:\"
If (deleteFile(path)) Then
MsgBox("File deletion successful")
Else
MsgBox("File couldn't be deleted with the following error: " + exception)
End If
Private Function deleteFile(ByVal dir) As Boolean
Dim fileToRemove As String
Try
Dim paths() As String = IO.Directory.GetFiles(dir, "THISTEXT*.txt")
For i As Integer = 0 To paths.Length
fileToRemove = paths(i).ToString
System.IO.File.Delete(fileToRemove)
If (Not System.IO.File.Exists(fileToRemove)) Then
Return True
Else
exception = "Unknown error."
Return False
End If
Next
Return False
Catch ex As Exception
exception = ex.Message
Return False
End Try
Return False
End Function
The above function checks if the file exists, if it does it tries to delete it. If the file cannot be deleted, or an error occurs (which is handled), the Function returns False.
Simple example:
For Each path As String In IO.Directory.GetFiles("C:\", "THISTEXT*.txt")
Try
System.IO.File.Delete(path)
Catch ex As Exception
MessageBox.Show(path, "Unable to Delete File")
End Try
Next

How to check if sub-folder text file exists

I am trying to search if a text file in a sub-folder exists.
This is the code I am using:
'Checks the program's root folder to see if the root folder exists.
Dim FolderName = New DirectoryInfo(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Cake Orders\" & TextBox1.Text))
Dim McKnwoll As String = Path.Combine(FolderName.FullName, Trim(TextBox2.Text) & (" ") & Trim(TextBox3.Text) + ".RTO")
If Not McKnwoll.Exists Then
‘Message to user that file does not exist in sub-folder
Else
‘Message to user that file does exists in sub-folder
End If
I am getting an error that 'Exists' is not a member of 'String'. How can I re-work my code to check if the text file whose name is in the format of "TextBox2.Text & (" ") & TextBox3.Text + ".RTO"; exists.
I am using Visual Basic 2010 Express. Thank you.
File.Exists returns a Boolean indicating whether a file at a certain path exists:
If File.Exists(pathToFile) Then
...
End If
Be sure to include Imports System.IO at the top of your source code file.
You seem quite new in programming. Welcome.
That error message you got ('Exists' is not a member of 'String') tells you exactely what is wrong: You try to ask a string (some text) whether it exists, but what you like to do is to ask a file whether it exists.
The class that provides information about a file is called "FileInfo", and FileInfo has an "Exists" property that you can call:
Dim myFileInfo As New FileInfo(McKnwoll)
If myFileInfo.Exists Then
'do something
End If
That's the object oriented answer, Heinzi's more service oriented one but works, of course, too.
There have been several other small issues I noticed with your code, e.g.
"Cake Orders\" & TextBox1.Text
does not use Path.Combine but makes a string concatenation using fix a "\" as directory separater. Or that the DirectoryInfo is not really used here, the string to the folder is enough.
You also try to handle 3 different issues (reading the values from the user interface, constructing the fullname of the file, checking whether the file exists) in one single code block. I would split them into 3 different ones (actually 4, I would add another one for displaying error messages).
Your simple few lines of codes could be complicated like this ;-)
Imports System.IO
Imports System.Text
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
ReadFileIfPossible(TextBox1.Text, TextBox2.Text, TextBox3.Text)
End Sub
Private Sub ReadFileIfPossible(subfolder As String, part1 As String, part2 As String)
'Get the path to the RTO file
Dim myFilePath As String = Nothing
Try
myFilePath = GetRtoFilePath(subfolder, part1, part2)
Catch ex As Exception
DisplayErrorMessage("Error constructing file name! Please check the values of TextBox1, TextBox2 and TextBox3.")
Return
End Try
'Get the file info
Dim myFile As FileInfo = Nothing
Try
myFile = New FileInfo(myFilePath)
Catch ex As Exception
DisplayErrorMessage(ex.Message)
Return
End Try
'Check whether it exists
Dim myExists As Boolean = False
Try
myExists = myFile.Exists 'it's IO, everything might throw an exception...
Catch ex As Exception
DisplayErrorMessage(ex.Message)
Return
End Try
'Display message if not found
If (Not myExists) Then
DisplayErrorMessage("File ""{0}"" could not be found!", myFilePath)
Return
End If
'Read the file
Dim myLines As String() = Nothing
Try
myLines = File.ReadAllLines(myFile.FullName, New UTF8Encoding(True))
Catch ex As Exception
DisplayErrorMessage(ex.Message)
Return
End Try
'Do something with it...
End Sub
Private Shared Function GetRtoFilePath(subfolder As String, part1 As String, part2 As String) As String
'Check args
If (subfolder Is Nothing) Then Throw New ArgumentNullException("subfolder")
If (part1 Is Nothing) Then Throw New ArgumentNullException("part1")
If (part2 Is Nothing) Then Throw New ArgumentNullException("part2")
'Normalize args
part1 = part1.Trim()
part2 = part2.Trim()
'Build path
Dim myDesktopPath As String = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
Dim myFolderPath As String = Path.Combine(myDesktopPath, "Cake Orders")
myFolderPath = Path.Combine(myFolderPath, subfolder)
Dim myFileName As String = String.Format("{0} {1}.RTO", part1, part2)
Dim myResult As String = Path.Combine(myFolderPath, myFileName)
myResult = Path.GetFullPath(myResult)
'Return result
Return myResult
End Function
Private Sub DisplayErrorMessage(message As String, ParamArray args As Object())
Dim myMsg As String = String.Format(message, CType(args, Object()))
MsgBox(myMsg, MsgBoxStyle.OkOnly, "Error")
End Sub
End Class
Have fun.

ByPassing System Files Permissions VB.Net

I started making a file manager which scans a folder selected by user through folderbrowserdialog in vb.net, extract the extentions of every file in every directory or subdirectory using GetFiles() Method with SearchOption.AllDirectories. I am having an UnauthorizedAccessException when it scans the Recycle Bin Folder in logical drive whereas i have seen Softwares like WinRar or R-Studio Scanning and showing every directory without having an exception or error. Following is my code:
Public Sub WriteExtentionsToFile()
Try
Title_Window.FolderBrowserDialog.ShowDialog()
Dim Path As String = Title_Window.FolderBrowserDialog.SelectedPath
'Getting FilesNames
Dim FileNames As String() = GetFilesNames(Path)
Title_Window.LblStatusBar.Text = "File Names Saved"
Dim MaximumForProgressBar As Integer = FileNames.Length
Title_Window.ToolStripProgressBar1.Maximum = MaximumForProgressBar
Title_Window.ToolStripProgressBar1.Step = 1
'Getting Extentions
Dim ExtentionsList As New List(Of String)
For Each item In FileNames
ExtentionsList.Add(System.IO.Path.GetExtension(item))
Next
'Deleting Duplicate Extentions
Dim NoDuplicateExtentionList As New List(Of String)
Dim ExtentionReadFromFile As String() = ReadExtentionsFromFile()'Another Function in my Class Which Reads previously saved extentions in a file and store them in an array
For Each item In ExtentionReadFromFile
NoDuplicateExtentionList.Add(item)
Next
For Each E In ExtentionsList
Dim LastIndexOfDot As Integer = E.LastIndexOf(".")
E = E.Remove(0, LastIndexOfDot + 1)
If NoDuplicateExtentionList.Contains(E.ToLower) = False Then
NoDuplicateExtentionList.Add(E.ToLower)
My.Computer.FileSystem.WriteAllText("d:\ExtentionsList.txt", E.ToString & vbCrLf, True)
End If
Next
MessageBox.Show("Writing Process Completed", "Success")
Catch ex As UnauthorizedAccessException
Dim Buttons As MessageBoxButtons = MessageBoxButtons.AbortRetryIgnore
Dim result As DialogResult
MessageBox.Show(ex.ToString, "Access Denied", Buttons)
If result = Windows.Forms.DialogResult.Ignore Then
'What should be Done Here????
ElseIf result = Windows.Forms.DialogResult.Abort Then
'What should be Done Here????
Else
'What should be Done Here????
End If
Catch ex As Exception
MessageBox.Show(ex.ToString)
End Try
End Sub
What should be the solution for thsi problem? Is this about getting the permissions through FileIoPermission Class or something else??