views:

210

answers:

4

I have a program written in VB.NET which stops a service that uses file x, modifies x, and restarts the service.

I have modified my code for testing so that it just reads in the file as a string and immediately writes it back out.

Shell("net stop " & SERVICE_NAME, , True)

Dim myReader As System.IO.StreamReader
myReader = My.Computer.FileSystem.OpenTextFileReader(x)
fileString = myReader.ReadToEnd()
myReader.Close()

Dim tempFile As System.IO.StreamWriter
tempFile = My.Computer.FileSystem.OpenTextFileWriter(x, False)
tempFile.Write(fileString)
tempFile.Close()

Shell("net start " & SERVICE_NAME, , True)

The stopping of the service is no problem, and modifying the file is no problem, but when the service starts it stops immediately because, as best I can guess, the file is in use. Even when I try to start the service manually, it stops immediately. However, I found that I can open file x, click save without modifying anything, close the file, and start the service and everything works correctly.

If I comment out the writing part, everything works fine.

Also, the file I'm modifying has a .conf file extension. I don't know if this is relevant.

Any suggestions on what could be causing this behavior?

Thanks,

B.J.

A: 

It's entirely possible that this problem is caused by something unrelated to the file access - I think the first point of attach is to check the EventLogs for an error message from the service, and / or to run your script in a debugger and check to see if the file is truly locked just before the service start call.

That said, if you're using VB.Net, I would suggest the correct way to use resources is always within a using statement:

Using tempFile = My.Computer.FileSystem.OpenTextFileWriter(x, False) as System.IO.StreamWriter
    tempFile.Write(fileSting)
    tempFile.Close()
End Using

If this is actually VB6 (as originally described in the question), then you need tear down the file object, and release memory (because VB6 is not garbage collected, you need to do this explicitly). Setting the file to Nothing should release the lock on the file:

Set tempFile = Nothing
Dexter
Still a no-go. Assigning Nothing to tempFile doesn't change the behavior.Thanks for your fast response, though.
Benny
Sorry, but that's not going to tear down the object either. That just makes it available for the Garbage Collector, which may not be called for entire minutes (which is basically forever in terms of a running program).
Binary Worrier
He's talking about VB6 here though - not .Net? VB6 is _not_ garbage collected
Dexter
Or at least, it's labelled as a VB6 question.. although I suspect that the .Net library references mean it's actually VB.Net?
Dexter
I can understand Dexter's confusion since the poster says he's using VB6, when the code is actually VB.net.
Alex Warren
As I stated in the comment on my original post, The Event log says that the service suffered a FATAL error because there's syntax error on line 1 of the conf file. Is it possible that it has something to do with endline consistency or some extra characters being added?
Benny
Deleted own comments, they were meaningless since qestion and answers changed. Apologies for confusion.
Binary Worrier
A: 

You should be using the System.IO.File instead of My.Computer.FileSystem

Josh Stodola
+1  A: 

So, I found the problem, but I don't know why it's there.

3 additional binary characters are being inserted at the beginning of the .conf file when its written.

They are: , hex EF BB BF. I have no idea where they're coming from.

Any ideas?

Also, sorry for the VB6/VB.NET confusion. I was in the wrong.

Thanks, B.J.

Benny
Thats a BOM (Byte order mark) http://en.wikipedia.org/wiki/Byte_order_mark
Binary Worrier
Indeed. It seems the default text encoding is UTF-8, so the BOM was prepended when the text was written. It looks like the program using the file was unable to interpret it, so the service stopped. I had to add a text-encoding parameter to the StreamWriter declaration specifying ASCII encoding and that solved the problem.Thanks for all your help.
Benny
Use System.Text.Encoding.Default instead of System.Text.Encoding.ASCII, the latter will lose characters over the 7-bit barrier.
Chris Haas
+2  A: 

To avoid the BOM you need to specify an encoding that doesn't have one, use System.Text.Encoding.Default

My.Computer.FileSystem.WriteAllText("c:\test.txt", fileString, False, System.Text.Encoding.Default)

While that convenience method is nice I still prefer to manually create a FileStream object so I can set the sharing flag ensuring that no one accesses my file until I'm done with it:

    Using FS As New System.IO.FileStream("c:\test.txt", IO.FileMode.Create, IO.FileAccess.Write, IO.FileShare.None)
        Using SW As New System.IO.StreamWriter(FS, System.Text.Encoding.Default)
            SW.WriteLine(fileString)
        End Using
    End Using
Chris Haas
Yes, this is the answer. The service doesn't know how to properly read UTF8 encoded files.
Hans Passant