Access to the path Log is denied randomly - vb.net

when I write to my log file I sometimes get access to log path is denied C:/app/log.log
Here is my code:
Private filePath As String
Private fileStream As FileStream
Private streamWriter As StreamWriter
Public Sub OpenFile()
Dim strPath As String
strPath = My.Application.Info.DirectoryPath + "\log.log"
If System.IO.File.Exists(strPath) Then
fileStream = New FileStream(strPath, FileMode.Append, FileAccess.Write)
Else
fileStream = New FileStream(strPath, FileMode.Create, FileAccess.Write)
End If
streamWriter = New StreamWriter(fileStream)
End Sub
Public Sub WriteLog(ByVal strComments As String)
OpenFile()
streamWriter.WriteLine(Date.Now.ToString & " " & strComments)
CloseFile()
End Sub
Public Sub CloseFile()
streamWriter.Close()
fileStream.Close()
End Sub
Is there anyway to make this use admin permissions or fix this issue? It only happens sometimes, and I'm not sure why it happens, but if I delete the log.log file the application can write to log again. Very weird.

You are calling your function WriteLog from multiple threads asynchronously, you should protect this function for example with a mutex.

Related

Problem with Crunch occurring after some time FtpWebRequest in vb.net

i have this Code From My Class
The code is working fine, but the memory is increasing, which is causing Crunch to close the program for itself
I tried all the methods and did not find a solution to this problem
Imports System.Net
Imports System.IO
Public Class class1
Private host As String
Private password As String
Private username As String
Dim x As New List(Of String)
Public Sub New(host As String, username As String, password As String)
Me.host = host
Me.username = username
Me.password = password
End Sub
Friend Sub start()
Try
Dim request As FtpWebRequest = WebRequest.Create("ftp://" + Me.host)
request.Timeout = 4000
request.Credentials = New NetworkCredential(Me.username, Me.password)
request.Method = WebRequestMethods.Ftp.ListDirectory
'-----------------------------------
Try
'-----------------------------------
Dim listResponse As FtpWebResponse = request.GetResponse()
' listResponse = request.GetResponse()
Dim reader As StreamReader = New System.IO.StreamReader(listResponse.GetResponseStream())
Dim Filedata As String = reader.ReadToEnd
'-----------------------------------
x.Add(Filedata)
'-----------------------------------
File.WriteAllLines(IO.Directory.GetCurrentDirectory() & "\logs.txt", x)
'-----------------------------------
Threading.Thread.Sleep(1000)
listResponse.Close()
listResponse.Dispose()
request.Abort()
Catch ex As WebException
request.Abort()
Exit Sub
End Try
Catch ex As Exception
Exit Sub
End Try
Exit Sub
End Sub
End Class
i Call this class from the main app
This method call
And use threading
Dim x As New testing(host, username, password)
x.start()
can anyone help me do this i am using Vb.net

Visual Basic FTP File Zilla Server?

I'm using this code:
Imports System.IO
Imports System.Net
Public Class sendftp
Public Function UploadFileToFtp(ByVal f As String, ByVal host As String, ByVal username As String, ByVal password As String, ByVal folderToUploadTo As String) As Boolean
Try
'create an FtpRequest object, holds the value of the path you are trying to reach
Dim ftpRequest As FtpWebRequest = DirectCast(FtpWebRequest.Create(New Uri(host & "/" & Path.GetFileName(folderToUploadTo))), FtpWebRequest)
'pass in our login credentials
ftpRequest.Credentials = New NetworkCredential(username, password)
'set the method to Upload, since we're uploading a file
ftpRequest.Method = WebRequestMethods.Ftp.UploadFile
'don't use passive mode
ftpRequest.UsePassive = True
'unless we're uploading a file like an image
'we need to set this to false as we're not uploading
'binary data
ftpRequest.UseBinary = True
'set KeepAlive to false
ftpRequest.KeepAlive = False
'now create a new FileStream, then open the file we're uploading
'this allows us to get the size of the file for our buffer
Dim stream As FileStream = File.OpenRead(f)
'create a byte[] array buffer the size of the file
'we're uploading
Dim buffer As Byte() = New Byte(stream.Length - 1) {}
'read in our file into the FileStream
stream.Read(buffer, 0, buffer.Length)
'close the FileStream
stream.Close()
'create a new stream, this will be used to write to the
'FTP server
Dim requestStream As Stream = ftpRequest.GetRequestStream()
'write the data to the FTP server
requestStream.Write(buffer, 0, buffer.Length)
'close the stream
requestStream.Close()
'since we made it this far return true
Return True
Catch ex As Exception
'something went wront so let the user know
MessageBox.Show("Error uploading file: " + ex.Message, "Upload Error")
'return false
Return False
End Try
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
UploadFileToFtp("C:\file.txt", "ftp://ftp.drivehq.com", "**user**", "**password**", "new.txt")
End Sub
End Class
And it works.
However I would like to use my FileZilla Server, so I edit the ftp url:
UploadFileToFtp("C:\file.txt", "ftp://localhost", "**user**", "**password**", "new.txt")
but I get this error : ?
The remote server returned an error:(550) File unavailable (e.g., file not found, no access).
I can't figure it out, any ideas?
Turned out to be permission that I fixed by going to ftp server settings... sorry for my inconvenience

Blocking more folders and applications

As you can see here I block the directory called "cleo". If I have it in my folder I can't click connect. How can I check if, for example, "Cleo", "Images", "Logs" exist in browsed file. I don't think making multiple If statements would be good, is there any other way?
Private Sub connect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles connect.Click
Dim cleoPath As String
Dim filePath As String
filePath = System.IO.Path.Combine(TextBox2.Text, "gta_sa.exe")
cleoPath = System.IO.Path.Combine(TextBox2.Text, "cleo")
If File.Exists(filePath) Then
If Directory.Exists(cleoPath) Then
MsgBox("Pronasli smo cleo fajl u vasem GTA root folderu. Da se konektujete na server morate ga obrisati.")
Else
Dim p() As Process
p = Process.GetProcessesByName("samp")
If p.Count > 0 Then
MsgBox("Vec imate pokrenut SAMP - ugasite ga.")
Else
Try
Dim prozess As Process = Process.GetProcessesByName("samp")(0)
prozess.Kill()
Catch ex As Exception
End Try
My.Computer.Registry.SetValue("HKEY_CURRENT_USER\Software\SAMP", "PlayerName", TextBox1.Text)
Process.Start("samp://193.192.58.55:7782")
Dim client As New TcpClient
client.Connect("193.192.58.55", 10924)
Dim sendbytes() As Byte = System.Text.Encoding.ASCII.GetBytes(TextBox1.Text)
Dim stream As NetworkStream = client.GetStream()
stream.Write(sendbytes, 0, sendbytes.Length)
End If
End If
Else
MsgBox("Da se konektujete morate locirati GTA San Andreas folder.")
End If
End Sub
End Class
You could use extension methods combined with a directoryinfo to check if any of a list of directory exists. Depending of if you just want a true/false return or if you need to process each directories (for instance, by adding a custom message with the name of the folders that prevent your application from continuing.
Public Module DirectoryInfoExt
<System.Runtime.CompilerServices.Extension()>
Public Function AnyExists(DirInfo As IO.DirectoryInfo, ParamArray Directories As String()) As Boolean
Dim MyPath As String = DirInfo.FullName.TrimEnd("\"c) & "\"
Return Directories.Any(Function(Dir) IO.Directory.Exists(MyPath & Dir))
End Function
<System.Runtime.CompilerServices.Extension()>
Public Function GetExistingDirectories(DirInfo As IO.DirectoryInfo, ParamArray Directories As String()) As IEnumerable(Of String)
Dim MyPath As String = DirInfo.FullName.TrimEnd("\"c) & "\"
Return Directories.Where(Function(Dir) IO.Directory.Exists(MyPath & Dir))
End Function
End Module
An example the boolean return.
Dim BaseDirectory As String = "C:\Games\GTA"
Dim GamePath As New DirectoryInfo(BaseDirectory)
' Will not give the specific path that exists, only a Boolean if any of theses folder are found
Dim ModsFound As Boolean = GamePath.AnyExists("Images", "Cleo", "Logs", "SomeFolder\Subfolder")
If Not ModsFound Then
'Connect
Else
' Do something
End If
An example using the list return to generate a custome message prompt stating the name of the specific folders found.
'This version gives a list instead.
Dim ModsFoundList As IEnumerable(Of String) = GamePath.GetExistingDirectories("Images", "Cleo", "Logs", "SomeFolder\Subfolder")
Dim HasMod As Boolean = ModsFoundList.Count > 0
If HasMod Then
EvilModdedUserPrompt(ModsFoundList)
Exit Sub
End If
' Here, since HasMod is false, we can proceed with connection.
' Do connection
As for the EvilModdedUserPrompt method
Public Sub EvilModdedUserPrompt(ModsFoundList As List(Of String))
Dim OutputMessage As New Text.StringBuilder
OutputMessage.AppendLine("The following mods have been detected on your system:")
For Each Moditem As String In ModsFoundList
OutputMessage.AppendFormat("- {0}", Moditem)
OutputMessage.AppendLine()
Next
MessageBox.Show(OutputMessage.ToString)
End Sub

Using IO.File Class to read a file that is in use

I am working on improving an old class and I am stuck here.
There is a method like this which works.
Private Database_Bytes As Byte()
Private Base as String = 'Path of Some database file.
Sub New()
If File.Exists(Base) Then
FileOpen(1, Base, OpenMode.Binary, OpenAccess.Read, OpenShare.Shared)
Dim asi As String = Space(LOF(1))
FileGet(1, asi)
FileClose(1)
Database_Bytes = Encoding.Default.GetBytes(asi)
End If
'Operations
End Sub
As FileOpen is old and IO Class offers better performance, I am trying to change it to below method but. I get an IOException if the file is in use by another process.
Private Database_Bytes As Byte()
Private Base as String = 'Path of Some database file.
Sub New()
If File.Exists(Base) Then
Database_Bytes = IO.File.ReadAllBytes(Base)
End If
'Operations
End Sub
How can I avoid the IOException if the file is in use?
As you have found out, File.ReadAllBytes does not allow you to read a file that is in use. However, you can do that with FileStream.Read.
Private Database_Bytes As Byte()
Private Base as String = "Path of Some database file."
Sub New()
If File.Exists(Base) Then
Using fs As New FileStream(Base, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
ReDim Database_Bytes(CInt(fs.Length) - 1)
fs.Read(Database_Bytes, 0, Database_Bytes.Length)
End Using
End If
'Operations
End Sub
The code above assumes that you have Imports System.IO (which seems to be the case based on the code you posted). Otherwise, File.Exists, FileStream, etc. would need to be qualified (e.g. IO.File.Exists, etc.).

visual basic 2010 | continue on error (UnauthorizedAccessException)

Just as the title says, anyone know how to get past this error? This is my first program using visual basic and can't seem to find an answer to this...
Tried
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles GetProfiles_Button.Click
For Each fileName As String In FileIO.FileSystem.GetDirectories("C:\", FileIO.SearchOption.SearchAllSubDirectories)
CheckedListBox1.Items.Add(fileName)
On Error Resume Next
Next
End Sub
End Class
And I tried
Public Class Form1
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles GetProfiles_Button.Click
Try
For Each fileName As String In FileIO.FileSystem.GetDirectories("C:\", FileIO.SearchOption.SearchAllSubDirectories)
CheckedListBox1.Items.Add(fileName)
Next
Catch ex As UnauthorizedAccessException
MsgBox("Unable to access " & ex.Message)
End Try
End Sub
End Class
I think i could make a work around by creating a loop that tests each and every folder but that would be considerably more code and seems quite inefficient... Any suggestions?
You can get multiple exception on the file methods like GetFiles or GetDirectories.
Some of the possible exceptions(from)
some path (long ones- PathTooLongException) are not supported by CLR
security restrictions on folders/files
junctions/hard links that introduce duplicates (and in theory cycles to case StackOverflow in recursive iteration).
basic sharing violation restrictions (if you try to read files).
You have to iterate all files and folders manually:
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim allCFileName = FindAllFiles("C:\")
For Each fileName As String In allCFileName
CheckedListBox1.Items.Add(fileName)
Next
End Sub
Public Shared Function FindAllFiles(rootDir As String) As String()
Dim paths = New Queue(Of String)()
Dim fileNames = New List(Of String)()
paths.Enqueue(rootDir)
While paths.Count > 0
Dim dir = paths.Dequeue()
Try
Dim files = Directory.GetFiles(dir)
For Each file As String In Directory.GetFiles(dir)
fileNames.Add(file)
Next
For Each subDir As String In Directory.GetDirectories(dir)
paths.Enqueue(subDir)
Next
Catch unauthorizedAccessException As UnauthorizedAccessException
' log the exception or ignore it
Console.WriteLine("Directory {0} could not be accessed!", dir)
Catch generalException As Exception
' log the exception or ...
Throw
End Try
End While
Return fileNames.ToArray()
End Function
Try
For Each path As String In filePath
If File.Exists(path) Then
' This path is a file
ProcessFile(path)
ElseIf Directory.Exists(path) Then
' This path is a directory
ProcessDirectory(path)
Else
Console.WriteLine("{0} is not a valid file or directory.", path)
End If
Next
Catch ex As UnauthorizedAccessException
MsgBox("Unable to access " & ex.Message)
End Try
Public Shared Sub ProcessDirectory(targetDirectory As String)
' Process the list of files found in the directory.
Dim fileEntries As String() = Directory.GetFiles(targetDirectory)
For Each fileName As String In fileEntries
ProcessFile(fileName)
Next
' Recurse into subdirectories of this directory.
Dim subdirectoryEntries As String() = Directory.GetDirectories(targetDirectory)
For Each subdirectory As String In subdirectoryEntries
ProcessDirectory(subdirectory)
Next
End Sub
Public Shared Sub ProcessFile(path As String)
File.Exists(path)
End Sub
This will access all the directory, subdirectories and files. Files.Exists should return false if you don't have access to the file, so you should also check on that.