Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Force Visual Studio 2008 debugger to release executable file

I find myself in the annoying situation where the visual studio debugger does not cleanly release itself once the debugging session is finished. Hence, devenv.exe retains a lock on the executable file and I cannot rebuild the project due to the dreaded error:

Error 1 Unable to copy file "obj\Debug\program.exe" to "bin\Debug\program.exe". The process cannot access the file 'bin\Debug\program.exe' because it is being used by another process.

This can be fixed by restarting visual studio but restarting my entire IDE after every run cycle is not exactly conducive to a great coding environment. Build -> Clean does not help.

I've googled this error and while the symptom seems to be fairly common the underlying cause is varied. Primarily I would like to know, in order of importance:

  1. Is there any speedy way to get the file to be unlocked without restarting visual studio?
  2. Barring that, what defensive programming techniques should I be employing to prevent this?
  3. What exactly is going on behind the scenes in the below example which is causing the debugger to not release?

An example of code that will produce this symptom is here.

class Program
{
    static void Main(string[] args)
    {
        var f1 = new Form1();
        f1.Dir = "asdf";
    }
}

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private FileSystemWatcher fsw;

    public string Dir
    {
        get { return fsw.Path;}
        set
        {
            fsw = new FileSystemWatcher(value);
            fsw.EnableRaisingEvents = true;
            throw new Exception("asdf");
        }
    }

    ~Form1()
    {
        if (fsw != null)
            fsw.Dispose();
    }
}

To reproduce:

  1. Run Program.Main using the Visual Studio 2008 debugger.
  2. Stop debugging when the exception is thrown.
  3. Change the source code and attempt to rebuild.

Edit: a solution of sorts:

public Form1()
{
    InitializeComponent();
    this.Closing += (sender, args) =>
    {
        if (watcher != null)
            watcher.Dispose();
    };
}

I am still interested in why this works and while placing it in the destructor does not.

like image 613
fostandy Avatar asked Dec 05 '25 15:12

fostandy


1 Answers

One way to attack this problem and one you should have in your toolbelt as a developer is to use Process Explorer from MS/Sys Internals. One of its features allows you to search ll the open handles in a system and when found, to kill the handle. It is a very handy and free app. Now, this does not solve your core issue but it will help along.

like image 190
Paul Sasik Avatar answered Dec 07 '25 03:12

Paul Sasik