FolderMon
20 November 2008 byPieni apuohjelma joka valvoo sopivaa kansiota ja kun sinne tulee sopiva tiedosto niin aukaisee sen kyseisellä ohjelmalla. Tuli sitten väsättyä tämmöinen kun ei flash pelit enään huvittanut.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 | /* Need a small utility which chould be started to run in the background and monitors a folder for specific files when it finds a file it should open it with an application. I have an application on the server which creates files for users in their folder (e.g. "\\server\user"), I need a client side program which should run on the users computer and monitor that folder (local or network share) and open the file when it finds it. Program should be self contained as a single executable file and should not need an installer or any additional libraries/files. The program should take command line arguments as described further, when started with no arguments the program should just output a message box with brief usage instructions. The program should not open the file untill the server finishes writing it. Program needs no GUI and needs to be run in the background untill killed or computer is shut down. Program should use minimum resources (less than 5MB ram and less that 2% CPU). Variables need to be expanded in the arguments (e.g. %username%) The system should not stop working or give any errors if it can't find the path that it monitors (e.g. a network drive that got disconnected) even for extended periods of time, should also not crash for any other errors. The arguments it needs to take: /f:<folder to watch> - /f:"C:\Temp" or /f:"\\server\user\%username%" /e:<file extensions to watch> - /e:*.txt /x:<application to open file> - /x:"C:\WINDOWS\NOTEPAD.EXE" (if "" is used or /X: is omitted use default windows program for this filetype) /d - optional, if present delete all files in the watched folder when started FolderMon.exe /f:"\\server\%username% /e:*.txt /x:"C:\WINDOWS\NOTEPAD.EXE" /d Developer should fix any bugs if found in the first 3 months after payment without any charge. Program should keep a log file (in the same path as the executable file is) which should log every action (date-time, filename found whetrher opened etc.), the log file should be deleted when the program starts (to avoid getting large log files). Program should run with normal "User" rights */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Collections.Specialized; using System.Text.RegularExpressions; using System.IO; using System.Diagnostics; using System.Threading; namespace FolderMon { public partial class FolderMon : Form { String Folder; String Extension; String Application; Boolean Delete; public FolderMon() { InitializeComponent(); } /// <summary> /// Application main logic is here. /// </summary> private void Form1_Load(object sender, EventArgs e) { // Hide window this.WindowState = FormWindowState.Minimized; this.ShowInTaskbar = false; this.Visible = false; // Handle command line switchs. HandleCommandLine(); // Delete old log file File.Delete(Program.AppPath() + "FolderMon.txt"); // Log parameters file. Program.LogMessageToFile("Application started"); Program.LogMessageToFile("Folder: " + Folder); Program.LogMessageToFile("Extension: " + Extension); Program.LogMessageToFile("Application:" + Application); Program.LogMessageToFile("Delete: " + (Delete ? "True" : "False")); // Delete all files in Watching folder if /D is used. if (Delete) { string[] List = Directory.GetFiles(Folder); foreach (string f in List) { FileInfo fi = new FileInfo(f); fi.Delete(); } } // Create a new FileSystemWatcher and enable it. FileSystemWatcher watcher = new FileSystemWatcher(); watcher.Filter = Extension; watcher.Created += new FileSystemEventHandler(watcher_FileCreated); watcher.Path = Folder; watcher.EnableRaisingEvents = true; } /// <summary> /// Handle the command line. /// </summary> void HandleCommandLine() { //create an instance of the parser String[] args = Environment.GetCommandLineArgs(); CommandLineParser parser = new CommandLineParser(args); const string Help = "FolderMon /f:\"C:\\foo\" /e:\"*.txt\"\n\n" + "/f:<folder to watch>\n" + "/e:<file extensions to watch>\n" + "/x:<application to open file> (optional)\n" + "/d delete all files in the watched folder(optional)"; if (parser["f"] != null) Folder = Environment.ExpandEnvironmentVariables(parser["f"]); else { MessageBox.Show(Help,"FolderMon"); Environment.Exit(0); } if (parser["e"] != null) Extension = parser["e"]; else { MessageBox.Show(Help, "FolderMon"); Environment.Exit(0); } if (parser["x"] != null) Application = Environment.ExpandEnvironmentVariables(parser["x"]); if (parser["d"] != null) Delete = true; } /// <summary> /// Run when new file is created to watch folder. /// </summary> void watcher_FileCreated(object sender, FileSystemEventArgs e) { String run; if(Application != null) run = Application + e.FullPath; else run = e.FullPath; Program.LogMessageToFile("Run: " + run); System.Diagnostics.Process.Start(run); } } static class Program { /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { Application.ThreadException += new ThreadExceptionEventHandler( Application_ThreadException); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new FolderMon()); } /// <summary> /// Custom error handler. /// </summary> private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e) { string errorMsg = "An error occurred please contact the adminstrator " + "with the following information:\n\n"; errorMsg = errorMsg + e.Exception.Message + "\n\nStack Trace:\n" + e.Exception.StackTrace; LogMessageToFile(errorMsg); // Application.ExitThread(); } /// <summary> /// Return application path. /// Hack: Best way? /// </summary> internal static string AppPath() { return Application.StartupPath + "\\"; //return System.Environment.CurrentDirectory; } /// <summary> /// Write simple log file. /// </summary> internal static void LogMessageToFile(string msg) { System.IO.StreamWriter sw = System.IO.File.AppendText( AppPath() + "FolderMon.txt"); try { string logLine = System.String.Format( "{0:G}: {1}", System.DateTime.Now, msg); sw.WriteLine(logLine); } finally { sw.Close(); } } } public class CommandLineParser { private StringDictionary parameters; public CommandLineParser(string[] arguments) { //create our stringDictionary Object for holding //the resulting key/value pairs parameters = new StringDictionary(); //create a RegEx Object for splitting the parameters Regex paramSplit = new Regex(@"^-{1,2}|^/|=|:", RegexOptions.IgnoreCase | RegexOptions.Compiled); //create a RegEx Object for removing trailing & //leading single and double quotes Regex paramRemover = new Regex(@"^['""]?(.*?)['""]?$", RegexOptions.IgnoreCase | RegexOptions.Compiled); string param = null; string[] paramParts; //loop through each item in the arguments array foreach (string str in arguments) { //split the parameter array paramParts = paramSplit.Split(str, 3); //use a switch statement to tell the parser what //to do for each possible length of the array switch (paramParts.Length) { case 1: if (param != null) { if (!parameters.ContainsKey(param)) { paramParts[0] = paramRemover.Replace(paramParts[0], "$1"); parameters.Add(param, paramParts[0]); } param = null; } break; //here we found just a parameter case 2: // The last parameter is still waiting. // With no value, set it to true. if (param != null) { if (!parameters.ContainsKey(param)) parameters.Add(param, "true"); } param = paramParts[1]; break; //here we found a parameter with a value case 3: // The last parameter is still waiting. // With no value, set it to true. if (param != null) { if (!parameters.ContainsKey(param)) parameters.Add(param, "true"); } param = paramParts[1]; // Remove possible enclosing characters (",') if (!parameters.ContainsKey(param)) { paramParts[2] = paramRemover.Replace(paramParts[2], "$1"); parameters.Add(param, paramParts[2]); } param = null; break; } } // In case a parameter is still waiting if (param != null) { if (!(parameters.ContainsKey(param))) { parameters.Add(param, "true"); } } } /// <summary> /// indexer to retrieve the parameters value if it exists /// </summary> /// <param name="param">parameter we want the value for</param> /// <returns></returns> public string this[string param] { get { return (parameters[param]); } } } } |