public virtual void InvokeGenerator(FileNode fileNode)
{
if(fileNode == null)
{
throw new ArgumentNullException("fileNode");
}
SingleFileGeneratorNodeExtenderProperties nodeproperties = fileNode.NodeProperties.Extender(SingleFileGeneratorNodeExtenderProvider.Name) as SingleFileGeneratorNodeExtenderProperties;
if(nodeproperties == null)
{
throw new InvalidOperationException();
}
string customToolProgID = nodeproperties.CustomTool;
if(string.IsNullOrEmpty(customToolProgID))
{
return;
}
string customToolNamespace = nodeproperties.CustomToolNamespace;
try
{
if(!this.runningGenerator)
{
//Get the buffer contents for the current node
string moniker = fileNode.GetMKDocument();
this.runningGenerator = true;
//Get the generator
IVsSingleFileGenerator generator;
int generateDesignTimeSource;
int generateSharedDesignTimeSource;
int generateTempPE;
SingleFileGeneratorFactory factory = new SingleFileGeneratorFactory(this.projectMgr.ProjectGuid, this.projectMgr.Site);
ErrorHandler.ThrowOnFailure(factory.CreateGeneratorInstance(customToolProgID, out generateDesignTimeSource, out generateSharedDesignTimeSource, out generateTempPE, out generator));
//Check to see if the generator supports siting
IObjectWithSite objWithSite = generator as IObjectWithSite;
if(objWithSite != null)
{
objWithSite.SetSite(fileNode.OleServiceProvider);
}
//Determine the namespace
if(string.IsNullOrEmpty(customToolNamespace))
{
customToolNamespace = this.ComputeNamespace(moniker);
}
//Run the generator
IntPtr[] output = new IntPtr[1];
output[0] = IntPtr.Zero;
uint outPutSize;
string extension;
ErrorHandler.ThrowOnFailure(generator.DefaultExtension(out extension));
//Find if any dependent node exists
string dependentNodeName = Path.GetFileNameWithoutExtension(fileNode.FileName) + extension;
HierarchyNode dependentNode = fileNode.FirstChild;
while(dependentNode != null)
{
if(string.Equals(dependentNode.ItemNode.GetMetadata(ProjectFileConstants.DependentUpon), fileNode.FileName, StringComparison.OrdinalIgnoreCase))
{
dependentNodeName = ((FileNode)dependentNode).FileName;
break;
}
dependentNode = dependentNode.NextSibling;
}
//If you found a dependent node.
if(dependentNode != null)
{
//Then check out the node and dependent node from SCC
if(!this.CanEditFile(dependentNode.GetMKDocument()))
{
throw Marshal.GetExceptionForHR(VSConstants.OLE_E_PROMPTSAVECANCELLED);
}
}
else //It is a new node to be added to the project
{
// Check out the project file if necessary.
if(!this.projectMgr.QueryEditProjectFile(false))
{
throw Marshal.GetExceptionForHR(VSConstants.OLE_E_PROMPTSAVECANCELLED);
}
}
IVsTextStream stream;
string inputFileContents = this.GetBufferContents(moniker, out stream);
ErrorHandler.ThrowOnFailure(generator.Generate(moniker, inputFileContents, customToolNamespace, output, out outPutSize, this));
byte[] data = new byte[outPutSize];
if(output[0] != IntPtr.Zero)
{
Marshal.Copy(output[0], data, 0, (int)outPutSize);
Marshal.FreeCoTaskMem(output[0]);
}
//Todo - Create a file and add it to the Project
this.UpdateGeneratedCodeFile(fileNode, data, (int)outPutSize, dependentNodeName);
}
}
finally
{
this.runningGenerator = false;
}
}