in src/Tasks/ResolveComReference.cs [397:538]
public override bool Execute()
{
if (!VerifyAndInitializeInputs())
{
return false;
}
if (!ComputePathToAxImp() || !ComputePathToTlbImp())
{
// unable to compute the path to tlbimp.exe, aximp.exe, or both and that is necessary to
// continue forward, so return now.
return false;
}
allProjectRefs = new List<ComReferenceInfo>();
allDependencyRefs = new List<ComReferenceInfo>();
_timestampCache = (ResolveComReferenceCache)StateFileBase.DeserializeCache(StateFile, Log, typeof(ResolveComReferenceCache));
if (_timestampCache == null || (_timestampCache != null && !_timestampCache.ToolPathsMatchCachePaths(_tlbimpPath, _aximpPath)))
{
if (!Silent)
{
Log.LogMessageFromResources(MessageImportance.Low, "ResolveComReference.NotUsingCacheFile", StateFile == null ? String.Empty : StateFile);
}
_timestampCache = new ResolveComReferenceCache(_tlbimpPath, _aximpPath);
}
else if (!Silent)
{
Log.LogMessageFromResources(MessageImportance.Low, "ResolveComReference.UsingCacheFile", StateFile == null ? String.Empty : StateFile);
}
try
{
ConvertAttrReferencesToComReferenceInfo(allProjectRefs, TypeLibNames);
ConvertFileReferencesToComReferenceInfo(allProjectRefs, TypeLibFiles);
// add missing tlbimp references for aximp ones
AddMissingTlbReferences();
// see if we have any typelib name clashes. Ignore the return value - we now remove the conflicting refs
// and continue (first one wins)
CheckForConflictingReferences();
SetFrameworkVersionFromString(_projectTargetFrameworkAsString);
// Process each task item. If one of them fails we still process the rest of them, but
// remember that the task should return failure.
// DESIGN CHANGE: we no longer fail the task when one or more references fail to resolve.
// Unless we experience a catastrophic failure, we'll log warnings for those refs and proceed
// (and return success)
ArrayList moduleList = new ArrayList();
ArrayList resolvedReferenceList = new ArrayList();
ComDependencyWalker dependencyWalker = new ComDependencyWalker(Marshal.ReleaseComObject);
bool allReferencesResolvedSuccessfully = true;
for (int pass = 0; pass < 4; pass++)
{
foreach (ComReferenceInfo projectRefInfo in allProjectRefs)
{
string wrapperType = projectRefInfo.taskItem.GetMetadata(ComReferenceItemMetadataNames.wrapperTool);
// first resolve all PIA refs, then regular tlb refs and finally ActiveX refs
if ((pass == 0 && ComReferenceTypes.IsPia(wrapperType)) ||
(pass == 1 && ComReferenceTypes.IsTlbImp(wrapperType)) ||
(pass == 2 && ComReferenceTypes.IsPiaOrTlbImp(wrapperType)) ||
(pass == 3 && ComReferenceTypes.IsAxImp(wrapperType)))
{
try
{
if (!this.ResolveReferenceAndAddToList(dependencyWalker, projectRefInfo, resolvedReferenceList, moduleList))
{
allReferencesResolvedSuccessfully = false;
}
}
catch (ComReferenceResolutionException)
{
// problem resolving this reference? continue so that we can display all error messages
}
catch (StrongNameException)
{
// key extraction problem? No point in continuing, since all wrappers will hit the same problem.
// error message has already been logged
return false;
}
catch (FileLoadException ex)
{
// This exception is thrown when we try to load a delay signed assembly without disabling
// strong name verification first. So print a nice information if we're generating
// delay signed wrappers, otherwise rethrow, since it's an unexpected exception.
if (DelaySign)
{
Log.LogErrorWithCodeFromResources(null, projectRefInfo.SourceItemSpec, 0, 0, 0, 0, "ResolveComReference.LoadingDelaySignedAssemblyWithStrongNameVerificationEnabled", ex.Message);
// no point in printing the same thing multiple times...
return false;
}
else
{
Debug.Assert(false, "Unexpected exception in ResolveComReference.Execute. " +
"Please log a MSBuild bug specifying the steps to reproduce the problem.");
throw;
}
}
catch (ArgumentException ex)
{
// This exception is thrown when we try to convert some of the Metadata from the project
// file and the conversion fails. Most likely, the user needs to correct a type in the
// project file.
Log.LogErrorWithCodeFromResources("General.InvalidArgument", ex.Message);
return false;
}
catch (SystemException ex)
{
Log.LogErrorWithCodeFromResources("ResolveComReference.FailedToResolveComReference",
projectRefInfo.attr.guid, projectRefInfo.attr.wMajorVerNum, projectRefInfo.attr.wMinorVerNum,
ex.Message);
}
}
}
}
SetCopyLocalToFalseOnGacOrNoPIAAssemblies(resolvedReferenceList, GlobalAssemblyCache.GetGacPath());
ResolvedModules = (ITaskItem[])moduleList.ToArray(typeof(ITaskItem));
ResolvedFiles = (ITaskItem[])resolvedReferenceList.ToArray(typeof(ITaskItem));
// The Logs from AxImp and TlbImp aren't part of our log, but if the task failed, it will return false from
// GenerateWrapper, which should get passed all the way back up here.
return allReferencesResolvedSuccessfully && !Log.HasLoggedErrors;
}
finally
{
if ((_timestampCache != null) && _timestampCache.Dirty)
{
_timestampCache.SerializeCache(StateFile, Log);
}
Cleanup();
}
}