Note that there are some explanatory texts on larger screens.

plurals
  1. POInvalid static method invocation syntax exception while loading MsBuild project file
    primarykey
    data
    text
    <p>I created MergeSolution task for MsBuild. It is for merging multiple solutions into one solution file. I'm using PLINQ to to parse and process all solutions in parallel. I'm using my DisposableProject class to access project files inside every solution to get some project-specific values. DisposableProject class was created to fix race condition issues because some project files are included in multiple solutions and also to fix huge memory consumption during merging process. </p> <pre class="lang-cs prettyprint-override"><code>/// &lt;summary&gt; /// Adding disposable functionality to Microsof.Build.BuildEngine.Project class. /// Every project file is locked during processing to get a rid of huge memory consumption and race condition issues. /// Project files are unloaded from build engine to save memory. /// &lt;/summary&gt; public class DisposableProject : Project, IDisposable { // Build engine - is it really needed? private static Engine buildEngine = new Engine(); // Event used for thread safe Mutex creation static AutoResetEvent loadingEvent = new AutoResetEvent(true); // Project file name private string FileName {get;set;} // Dictionary with Mutex name - Mutex static ConcurrentDictionary&lt;string, Mutex&gt; mutexLocks = new ConcurrentDictionary&lt;string, Mutex&gt;(); /// &lt;summary&gt; /// DisposableProject constructor. Project file is loaded and named Mutex is created to lock file by its file name. /// &lt;/summary&gt; /// &lt;param name="projectFileName"&gt;MsBuild project file name&lt;/param&gt; public DisposableProject(string projectFileName) : base(buildEngine) { // Use file name as mutex name FileName = GetMutexName(projectFileName); // Lock file during processing // Lock Mutex creation because multiple threads can create duplicate Mutexes causing sync exceptions loadingEvent.WaitOne(); // Check if mutex object already exists if(!mutexLocks.ContainsKey(FileName)) mutexLocks[FileName] = new Mutex(false, FileName); // Unlock mutex creation loadingEvent.Set(); // Wait for file mutexLocks[FileName].WaitOne(); // Load project file this.Load(projectFileName, ProjectLoadSettings.IgnoreMissingImports); } /// &lt;summary&gt; /// Unload MsBuild project file from memory and Mutex (file lock) is released. /// &lt;/summary&gt; public void Dispose() { // Unload from build engine to save memory this.ParentEngine.UnloadProject(this); // Unlock file mutexLocks[FileName].ReleaseMutex(); } /// &lt;summary&gt; /// Create mutex name from file name. /// &lt;/summary&gt; /// &lt;param name="pathName"&gt;File name&lt;/param&gt; /// &lt;returns&gt;Mutex name&lt;/returns&gt; private string GetMutexName(string pathName) { // Replace directory separator chars with underscore return pathName.Replace(Path.DirectorySeparatorChar, '_'); } } </code></pre> <p>Sometimes my MergeSolutions task fail with following exception during loading of the first project file:</p> <pre><code>InvalidProjectFileException: Invalid static method invocation syntax: "$([Microsoft.Build.Utilities.ToolLocationHelper]::GetPathToStandardLibraries($(TargetFrameworkIdentifier), $(TargetFrameworkVersion), $(TargetFrameworkProfile)))". Static method invocation should be of the form: $([FullTypeName]::Method()), e.g. $([System.IO.Path]::Combine(`a`, `b`))\r at Microsoft.Build.BuildEngine.Shared.ProjectErrorUtilities.VerifyThrowInvalidProject(Boolean condition, String errorSubCategoryResourceName, XmlNode xmlNode, String resourceName, Object arg0)\r at Microsoft.Build.BuildEngine.Expander.Function.ExtractPropertyFunction(String expressionFunction, Object propertyValue)\r at Microsoft.Build.BuildEngine.Expander.ExpandPropertyBody(String propertyBody, Object propertyValue, BuildPropertyGroup properties, ExpanderOptions options)\r at Microsoft.Build.BuildEngine.Expander.ExpandPropertiesLeaveTypedAndEscaped(String expression, XmlNode expressionNode)\r at Microsoft.Build.BuildEngine.Expander.ExpandAllIntoStringLeaveEscaped(String expression, XmlNode expressionNode)\r at Microsoft.Build.BuildEngine.BuildPropertyGroup.Evaluate(BuildPropertyGroup evaluatedPropertyBag, Hashtable conditionedPropertiesTable, ProcessingPass pass)\r at Microsoft.Build.BuildEngine.Project.ProcessProjectChildren(XmlElement projectElement, String projectDirectoryLocation, Boolean importedProject)\r at Microsoft.Build.BuildEngine.Project.ProcessImportElement(XmlElement importElement, String projectDirectoryLocation, Boolean importedProject)\r at Microsoft.Build.BuildEngine.Project.ProcessProjectChildren(XmlElement projectElement, String projectDirectoryLocation, Boolean importedProject)\r at Microsoft.Build.BuildEngine.Project.ProcessImportElement(XmlElement importElement, String projectDirectoryLocation, Boolean importedProject)\r at Microsoft.Build.BuildEngine.Project.ProcessProjectChildren(XmlElement projectElement, String projectDirectoryLocation, Boolean importedProject)\r at Microsoft.Build.BuildEngine.Project.ProcessMainProjectElement()\r at Microsoft.Build.BuildEngine.Project.InternalLoadFromXmlDocument(XmlDocument projectXml, ProjectLoadSettings projectLoadSettings)\r at Microsoft.Build.BuildEngine.Project.Load(String projectFileName, BuildEventContext buildEventContext, ProjectLoadSettings projectLoadSettings)\r at XXX.Build.Common.Types.DisposableProject..ctor(String projectFileName) in D:\XXX\DisposableProject.cs:line 35\r </code></pre> <p>MergeSolution task always throw this exception at the beginning of merging process and it happen only sometimes. Is is BuildEngine initialization issue, I guess. BuildEngine constructor is probably not thread-safe. I'm using default MSBuild constructor. Any ideas how to solve it?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload