1
Vote

SingleFileGenerator doesen't truncate the generated file in Iso-Shell

description

The Method UpdateGeneratedCodeFile in the class SingleFileGenerator has two bugs:
 
1) If it is running in the Iso-Shell the generated file isn't truncated if it is shorter than befor. You can fix this by changing the line (around line 291)
using (FileStream generatedFileStream = File.Open(filePath, FileMode.OpenOrCreate))
to
using (FileStream generatedFileStream = File.Open(filePath, FileMode.Create))
 
2) If the generated file is open in visual studio it is not generated. I'll fix it by generating always. To do this I'll comment out the lines from 'if(docData != IntPtr.Zero)' until the 'else' block.

comments

ldubois wrote Sep 7, 2011 at 4:09 PM

I'm OK with first point.

But second point is because of a missing line of code: GetBufferContents( filePath, srpStream ); between IVSTextStream srpStream = null; and if( srpStream != null )

I also changed code so that in memory changed failure => save it on disk

IVsHierarchy hier;
uint cookie;
uint itemid;
IntPtr docData = IntPtr.Zero;
ErrorHandler.ThrowOnFailure(rdt.FindAndLockDocument((uint)(_VSRDTFLAGS.RDT_NoLock), filePath, out hier, out itemid, out docData, out cookie));
bool changedInMemory = false;
if(docData != IntPtr.Zero)
{
Marshal.Release(docData);
IVsTextStream srpStream = null;
GetBufferContents( filePath, out srpStream ); // Missing line ?!?!?
if(srpStream != null)
{
int oldLen = 0;
int hr = srpStream.GetSize(out oldLen);
if(ErrorHandler.Succeeded(hr))
{
  IntPtr dest = IntPtr.Zero;
  try
  {
    dest = Marshal.AllocCoTaskMem(data.Length);
    Marshal.Copy(data, 0, dest, data.Length);
    ErrorHandler.ThrowOnFailure(srpStream.ReplaceStream(0, oldLen, dest, size / 2));
    changedInMemory = true;
  }
  finally
  {
    if(dest != IntPtr.Zero)
    {
      Marshal.Release(dest);
    }
  }
}
}
}
if( !changedInMemory )
{
using(FileStream generatedFileStream = File.Open(filePath, FileMode.Create)) // not OpenOrCreate for the file to be truncated if necessary
{
generatedFileStream.Write(data, 0, size);
}

EnvDTE.ProjectItem projectItem = fileNode.GetAutomationObject() as EnvDTE.ProjectItem;
if(projectItem != null && (this.projectMgr.FindChild(fileNode.FileName) == null))
{
projectItem.ProjectItems.AddFromFile(filePath);
}
}
return filePath;

wrote Feb 14, 2013 at 3:58 AM