Sunday, May 22, 2011

Access Denied - Windows Service - StreamWriter- VB.Net

I'm going to cut right to the chase on this one.  I didn't realize that Windows obfuscates error messages for security.  Without that gem of knowledge, I spent WAY more time than I should have last week trying to get a Windows Service to write a file to the local file system on a server.  (I have another post related to obfuscated error messages with Windows here, but it focuses on IIS).

I was continually getting an access denied message trying to programatically create and write a file using a StreamWriter in VB.Net.  My Windows Service was running as a particular service account, and I had  given that particular account Modify access to the parent folder where the file was supposed to be created - but it would not write.  I tried pushing to a different server to see if it would work there - still no dice.  I tried adding security policies (run as a service, run as a batch job, run as part of the OS) to the service account running the service - again, the annoying message 'Access Denied'.  For a while it was thought that maybe the file size was an issue - it was a little over a Mb.  I deployed another version that wrote just one line.  No luck.

In the end, I enlisted a colleague's help (thanks Dorina) and we discovered that the problem wasn't the user at all.  It was in the path that I was trying to write to.  I was using the Path.combine() method to put the path together which, in the debugger appeared to put the file name and path together correctly.  However when we used Procmon to look at the output it complained on a createFile command that the 'file' was 'isDirectory'.  Upon closer examination, it turned out that my Nunit test was calling one constructor that correctly used that Path.combine() method, and my Service called another constructor that did not use the Path.combine() method.

So in the end, my AccessDenied error, was really an incorrect path issue.  Windows (apparently) doesn't display the correct error message so as not to advertise potentially sensitive paths.  And I need to ensure that my Nunits exercise the same methods that my implementation classes use.

No comments: