title: Sporadic file movement error
body: <p>I have a program that is a launcher for a mod for a game. The launcher works for most of the people who use it, including myself, but for some there is a strange bug that really has me struggling to fix it, and further more driving me absolutely mental!</p>
  
  <p>The basic idea is that my mod files are contained in a folder, the launcher iterates through these files, reads a certain byte of the file and based on the result either moves the file, or moves the file <em>and</em> writes some text to a certain file, then launches the game. Seemingly simple.</p>
  
  <p>The main launch function looks like this:</p>
  
  <pre><code>private void Launch()
      {
          using (StreamWriter writer = new StreamWriter(userScriptPath, false, Encoding.Unicode))
          {
              foreach (string file in Directory.GetFiles(modFolderPath + "\\Files\\", "*.pack"))
              {
                  int p = GetPackType(file);
  
                  if (p == 3)
                  {
                      if (File.Exists(modFolderPath + "\\Files\\" + Path.GetFileName(file)))
                      {
                          File.Move(modFolderPath + "\\Files\\" + Path.GetFileName(file), dataPath + "\\" + Path.GetFileName(file));
                      }
  
                      writer.WriteLine("mod \"" + Path.GetFileName(file) + "\";");
                  }
                  else if (p == 4)
                  {
                      if (File.Exists(modFolderPath + "\\Files\\" + Path.GetFileName(file)))
                      {
                          File.Move(modFolderPath + "\\Files\\" + Path.GetFileName(file), dataPath + "\\" + Path.GetFileName(file));
                      }
                  }
              }
          }
  
          Process game = Process.Start(gamePath);
  
          // There is code here that waits for a minute until the game process is actually found, incase its slow starting up
  
          game.WaitForExit();
          RestorePacks(); // &lt;- Method to put back the files after finishing
      }
  </code></pre>
  
  <p>The problem some users are getting is that when launching the mod the game launches but it appears as though the launcher doesn't move the files as the game is still in its normal state, it was very hard to ascertain exactly why this was happening as I had no way of debugging it on their computers and the program was working fine for me and all of my test users.</p>
  
  <p>To try and find out what was going on I added a number of checks and some logging to the launcher so that if the launcher didn't work, I'd at least have an idea why. (Note that no errors are thrown for the users even when it doesn't work)</p>
  
  <p>The checks I added included using <code>File.Exists()</code> after attempting to move a file to make sure it was actually moved, the logging kept a note of move attempts and the result of this check to see if the file was actually moved.
  I even added a specific if statement to the Process.Start function checking specifically that a certain file was indeed in the required location before launching the game.
  Finally before launching all of the files in the folder where the mod files <em>should</em> now be are written to the log.</p>
  
  <p>All of the logs from users who the launcher didn't work for shared one thing in common the program attempted to move the file, threw no error, and then when checking that the file was indeed moved, the file appeared to be there. But when reaching the point where all of the files in the required directory are written to the log, only one of the required 30+ mod files appear to be in the directory.</p>
  
  <p>An example output log looked something like this:</p>
  
  <blockquote>
    <p>File moving: <strong>modfile1.txt</strong></p>
    
    <p>Checking if file is where we tried to move it to: <strong>Yes</strong></p>
    
    <p>File moving: <strong>modfile2.txt</strong></p>
    
    <p>Checking if file is where we tried to move it to: <strong>Yes</strong></p>
    
    <p>File moving: <strong>modfile3.txt</strong></p>
    
    <p>Checking if file is where we tried to move it to: <strong>Yes</strong></p>
    
    <p>Writing out all files in directory:</p>
    
    <p>normalgamefile1.txt</p>
    
    <p>normalgamefile2.txt</p>
    
    <p>normalgamefile3.txt</p>
    
    <p>modfile1.txt</p>
  </blockquote>
  
  <p>After seeing this and noticing it was always only a single file that had moved and no others, and also that the program did think the files were where they where supposed to be, the confusion really started to kick in.</p>
  
  <p>This is the method that reads the file to ascertain what type of file it is:</p>
  
  <pre><code>private int GetPackType(string path)
      {
          FileStream fs = File.OpenRead(path);
          BinaryReader reader = new BinaryReader(fs);
          reader.ReadChars(4);
          int packType = reader.ReadInt32();
          fs.Close();
          fs.Dispose();
  
          return packType;
      }
  </code></pre>
  
  <p>As you can probably see, and what I've just noticed is that I've failed to close/dispose of <code>reader</code>, and I'm guessing and somewhat hoping this might be the cause of my problem.
  (Note I'm now using Using statements in this method but can't test this fix for quite a while)</p>
  
  <p>SO, if you've read this far thank you, my question is..</p>
  
  <p>Firstly do you have any idea what the problem is? Could it be that <code>reader</code> still might have the file open and has not closed and thus the file can't move, IF SO then why does it work perfectly for me and most others, but not for some? Surely a file still being used elsewhere would throw an error?</p>
  
  <p>I've gone through all the simple stuff like making sure the program is run with administrator privileges, etc.</p>
  
  <p>Thank you greatly for any help!</p>
  
  <hr>
  
  <p><strong>EDIT</strong></p>
  
  <p>As asked in the comments this is the version of the code with my checks and logging added. Simple stuff, which is why I omitted it, the log simply adds to a string, the string is then printed to file when all is done.</p>
  
  <pre><code>private void Launch()
      {
          using (StreamWriter writer = new StreamWriter(userScriptPath, false, Encoding.Unicode))
          {
              foreach (string file in Directory.GetFiles(modFolderPath + "\\Files\\", "*.pack"))
              {
                  int p = GetPackType(file);
  
                  if (p == 3)
                  {
                      if (File.Exists(modFolderPath + "\\Files\\" + Path.GetFileName(file)))
                      {
                          File.Move(modFolderPath + "\\Files\\" + Path.GetFileName(file), dataPath + "\\" + Path.GetFileName(file));
                      }
  
                      log += "Move File: " + Path.GetFileName(file) + "\r\n";
  
                      writer.WriteLine("mod \"" + Path.GetFileName(file) + "\";");
  
                      log += "Write mod line: " + Path.GetFileName(file) + "\r\n";
                  }
                  else if (p == 4)
                  {
                      if (File.Exists(modFolderPath + "\\Files\\" + Path.GetFileName(file)))
                      {
                          File.Move(modFolderPath + "\\Files\\" + Path.GetFileName(file), dataPath + "\\" + Path.GetFileName(file));
                      }
  
                      log += "Move File: " + Path.GetFileName(file) + "\r\n";
                  }
  
                  // Check the file did actually move
                  if (File.Exists(dataPath + "\\" + Path.GetFileName(file)) == false)
                  {
                      MessageBox.Show("The mod could not launch successfully!\n\nError: Packs failed to move", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                      return;
                  }
                  else
                  {
                      log += "File Found\r\n";
                  }
              }
          }
  
          if (File.Exists(dataPath + "\\_GreatWar5_DB.pack")) // This pack should always be there if things have worked
          {
              Process game = Process.Start(gamePath);
          }
          else
          {
              MessageBox.Show("The mod could not launch successfully!\n\nError: Data pack missing", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
              return;
          }
  
          // There is code here waits for a minute until the game process is actually found, incase its slow starting up
  
          game.WaitForExit();
          RestorePacks(); // &lt;- Method to put back the files after finishing
      }
  </code></pre>