Thursday, April 3, 2008

The REAL Current Directory in .NET

I've got this little open source C# app I wrote called PowerFlag. PowerFlag is a response to the unending plethora of spammers on Craigslist. Now, I love Craigslist but the spammers really get on my nerves. So I wrote this app to automatically flag as spam posts which contain keywords that the user defines. The app worked pretty great except for the fact that when I tried to run it through the Windows Scheduler it seemed to run fine judging by the logs but it never seemed to find any posts to flag. For instance if I ran the app by double-clicking it and clicked the Flag! button in the app it would find maybe 10 or so spam posts and flag them. This would be evident via a text box in the app and the log file that is created on every run. If I right-clicked the scheduled task and chose 'Run' though the log file would be created but it would say that no posts were found to flag. I lived with it this way for a couple of months before today I finally got around to figuring out what the root of the problem was and how to fix it. My problem was that the app uses two settings files and the definitions for the filepaths for those two files were stored in string constants which concatenated together System.Environment.CurrentDirectory with the file names of the files. By adding more logging I was able to see that when the app was run via the task scheduler the value of System.Environment.CurrentDirectory was not the directory the app executable was in but instead was for some reason c:\windows\system32. Upon further investigation I found different settings files for the app in this location as well. These settings files contained the initial settings that the program uses on first startup and did not contain all of the keywords I had defined using the app itself. The fix for this problem of System.Environment.CurrentDirectory not always being the same as the current directory of the executing app is to instead use this: System.IO.Path.GetDirectoryName(System.Reflection.Assembly._ GetExecutingAssembly().Location) This is pretty much guaranteed to always give you the path to the folder containing the current executable. Once I made this change my log files overflowed with flagged posts from the scheduled app. Voila!

No comments: