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:
- Use
the above pre-build event modified to move the pdb file instead of the dll.*
- 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.*
- 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