1

After some great arguments made by other users in this question: How to write to a text file inside of the application, I decided to not use a resource file, instead create a file in a folder & then read/write from there.

Although, for some reason, I can't seem to write to the file in question, it keeps throwing an exception telling me the file is already in use by another process.

Here's the code which I use for writing to this file.

If System.IO.File.Exists(credentials) Then
                        Dim objWriter As New System.IO.StreamWriter(credentials, False)
                        objWriter.WriteLine(remember)
                        objWriter.Close()
                    Else
                        System.IO.Directory.CreateDirectory(Mid(My.Application.Info.DirectoryPath, 1, 1) & ":\ProgramData\DayZAdminPanel")
                        System.IO.File.Create(credentials)
                        Dim objWriter As New System.IO.StreamWriter(credentials, False)
                        objWriter.WriteLine(remember)
                        objWriter.Close()
                    End If

Any ideas on how I can write to the text file in question?

Community
  • 1
  • 1
Yorrick
  • 377
  • 2
  • 8
  • 28

3 Answers3

2

There's a good chance that a previous iteration of your application failed to properly close access to the file in the StreamWriter. Since your constructor is set to overwrite (and not append) to the file, this could be the source.

Try setting up your application with a "Using" statement to properly open/close the file:

If System.IO.File.Exists(credentials) Then

   Using objWriter As StreamWriter = New StreamWriter(credentials, False)
       objWriter.WriteLine(remember)
       objWriter.Close()
   End Using

Else             

   System.IO.Directory.CreateDirectory(Mid(My.Application.Info.DirectoryPath, 1, 1) & ":\ProgramData\DayZAdminPanel")
   System.IO.File.Create(credentials)

   Using objWriter As StreamWriter = New StreamWriter(credentials, False)
       objWriter.WriteLine(remember)
       objWriter.Close()
   End Using

End If

It does look rather redundant to have a Using block and a close statement, but this ensures access to your file even if an exception occurs.

Dillie-O
  • 29,277
  • 14
  • 101
  • 140
1

You are trying to create a directory in the common application data directory. This directory should be found using the Environment class methods and enums because is different between operating systems. However you use the value credentials for the filename. I suppose that you want to store your datafile in the common application directory and not in a place where there is no permission to write data files (Like C:\program files (x86)).

Then, to avoid problems with file stream not correctly closed try to use the Using statement that assures a correct closure and disposal of your file resource (No need to call close inside a Using).

Also, notice that StreamWriter is perfectly capable to create the file if it doesn't exists or if you wish to overwrite the previous contents (passing false for the Append flag).
So your code could be reduced to these lines.

' Get the common application data directory (could be different from Win7 and XP)
Dim workDir = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)
' Combine with your own working data directory
workDir = Path.Combine(workdir, "DayZAdminPanel")
' Create if not exists
If Not Directory.Exists(workDir) Then
    Directory.CreateDirectory(workDir)
End If

' Create/Overwrite your data file in a subfolder of the common application data folder
Dim saveFile = Path.Combine(workDir, Path.GetFileName(credentials))
Using objWriter = New System.IO.StreamWriter(saveFile, False)
    objWriter.WriteLine(remember)
End Using
Steve
  • 213,761
  • 22
  • 232
  • 286
  • Thanks, this works, although I do prefer having the file saved in the directories I used in my question. – Yorrick Mar 18 '13 at 22:42
  • The enum `SpecialFolder.CommonApplicationData` resolves to C:\PROGRAMDATA in Win7 and somewhere in C:\DOCUMENTS & SETTINGS\ALLUSER... for XP. So, this is the way to go to be independent from the underlying OS. – Steve Mar 18 '13 at 22:44
  • Oh I see, I thought `SpecialFolder.CommmonApplicationData` was a reference for a location in the %appdata% area. My bad – Yorrick Mar 18 '13 at 23:08
  • By the way, it is not clear what do you mean for `directories used in my question`. I think that is better (more professional?) to write your data in the folder specifically thought for this by Windows engineers – Steve Mar 18 '13 at 23:20
  • Well, I personally prefer having the least amount of files as possible on my C:\ drive, which is where the file would be stored with `SpecialFolder.CommonApplicationData` (standard for W7 = C:\ProgramData\), so I was looking into having the file saved onto the drive where the actual program is saved (in my case it's on my D:\ drive), using the code in my question, the file would eventually be saved in D:\ProgramData\... I guess it's mainly a personal preference and not being clever on my part :) – Yorrick Mar 19 '13 at 01:06
0

File.Create returns an opened FileStream that you should be passing into the StreamWriter constructor on the subsequent, rather than passing the filename again, or you can just omit the File.Create call altogether.

You might want to look into a Using block for the StreamWriter so it gets predictably closed.

Ryan Cavanaugh
  • 209,514
  • 56
  • 272
  • 235
  • So I should be able to use the code pasted in this pastebin? [link](http://pastebin.com/X62QxP7U), omitting the check if the file exists, the directory creation and the file creation? – Yorrick Mar 18 '13 at 22:38