Bit Lock During Out of Process Debugging Workaround

During out of process debugging occasionally the pdb file becomes locked and prevents builds from finishing successfully.  The VstaDesignTimeIntegration.DeleteMacroPdb method, called in OnBuildBegin, is suppose to ensure that this does not happen by cycling until the bits are no longer locked, then deleting them.  Unfortunately this does not always work and the project can get stuck in an unbuildable state.  Keyvan Nayyeri posted a workaround to a similar issue in add-in programming (the dll file becoming locked) which can be applied to this.  He suggests using a pre-build event to move/rename the locked files thus clearing the way for the updated bits to be built. 

Keyvan’s workaround:
You can add following lines of code to the pre-build event command line of your project.

if exist "$(TargetPath).locked" del "$(TargetPath).locked"
if exist "$(TargetPath)" if not exist "$(TargetPath).locked" move "$(TargetPath)" "$(TargetPath).locked"

Ways to apply workaround:

  1. Use the above pre-build event modified to move the pdb file instead of the dll.*
  2. Use a modified version of the InstallAddIn.js file used in the post build event in the pre-build event to move the pdb bits.*
  3. In the DeletePdb method move the locked file in the catch block (see code below).

* Keep in mind that like the post build event, the pre build event can be added programmatically.

By using this workaround, the build will no longer fail if the pdb bits become locked.  However, if the bits do become locked, debugging will fail. 

Related blog:  ShapeAppMacroRecordingCSharp- common problems and workarounds
One issue with the DeletePdb bit method is that it catches only the IOException, not the UnauthorizedAccessException which is also thrown.   

 

Code for #3 In the DeletePdb method move the locked file in the catch instead of cycling

private static void DeleteMacroPdb()

 {

     string projectPath = Path.GetDirectoryName(VstaDesignTimeIntegration.MacroProjectFilePath);

     string[] pdbFiles = Directory.GetFiles(projectPath, "*.pdb", SearchOption.AllDirectories);

 

     // Delete all PDB files for the project under \obj\.. and \bin\.. folders.

     // If a file is locked, retry to delete that file after 100 milliseconds.

     foreach (string pdbFile in pdbFiles)

     {

         bool done = false;

         int retry = 0;

 

         // Retry a maximum of 5 seconds to delete the file.

         while (!done && retry <= 50)

         {

             try

             {

                 File.Delete(pdbFile);

                 done = true;

             }

             catch (IOException ex)

             {

                 File.Delete(pdbFile+"old");

                 File.Move(pdbFile, pdbFile + "old");

                 Thread.Sleep(100);

                 retry++;

             }

             catch (Exception ex)

             {

                 File.Delete(pdbFile + "old");

                 File.Move(pdbFile, pdbFile + "old");

                 Thread.Sleep(100);

                 retry++;

             }

         }

     }

 }


Posted Aug 04 2008, 10:13 AM by Melody
Copyright Summit Software Company, 2008. All rights reserved.