diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/MarkupCompiler/MarkupCompiler.cs b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/MarkupCompiler/MarkupCompiler.cs
index 556ea8e7850..aa28323ce5a 100644
--- a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/MarkupCompiler/MarkupCompiler.cs
+++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/MarkupCompiler/MarkupCompiler.cs
@@ -154,6 +154,11 @@ internal TaskLoggingHelper TaskLogger
set { _taskLogger = value; }
}
+ ///
+ /// Support custom IntermediateOutputPath and BaseIntermediateOutputPath outside the project path
+ ///
+ internal bool SupportCustomOutputPaths { get; set; } = false;
+
// If the xaml has local references, then it could have internal element & properties
// but there is no way to determine this until MCPass2. Yet, GeneratedInternalTypeHelper,
// which is the class that allows access to legitimate internals, needs to be generated
@@ -1575,11 +1580,64 @@ private string ParentFolderPrefix
{
get
{
-#if NETFX
- return PathInternal.GetRelativePath(TargetPath, SourceFileInfo.SourcePath, StringComparison.OrdinalIgnoreCase) + Path.DirectorySeparatorChar;
+ if (SupportCustomOutputPaths)
+ {
+ // During code generation, ParentFolderPrefix returns the relative path from a .g.cs file to its markup file.
+ //
+ // One example is generated #pragmas: #pragma checksum "..\..\..\..\Views\ExportNotificationView.xaml"
+ //
+ // The path information for a markup file is represented in SourceFileInfo:
+ //
+ // SourceFileInfo.OriginalFilePath: "c:\\greenshot\\src\\Greenshot.Addons\\Views\\ExportNotificationView.xaml"
+ // SourceFileInfo.TargetPath: "c:\\greenshot\\src\\Greenshot.Addons\\obj\\Debug\\net6.0-windows\\"
+ // SourceFileInfo.RelativeFilePath: "Views\\ExportNotificationView"
+ // SourceFileInfo.SourcePath = "c:\\greenshot\\src\\Greenshot.Addons\\"
+ //
+ // The path of the generated code file associated with this markup file is:
+ //
+ // "c:\greenshot\src\Greenshot.Addons\obj\Debug\net6.0-windows\Views\ExportNotificationView.g.cs"
+ //
+ // The markup file path is in SourceFileInfo.OriginalFilePath:
+ //
+ // "c:\\greenshot\\src\\Greenshot.Addons\\Views\\ExportNotificationView.xaml"
+ //
+ // The relative path calculation must take in to account both the TargetPath and the RelativeFilePath:
+ //
+ // "c:\\greenshot\\src\\Greenshot.Addons\\obj\\Debug\\net6.0-windows\\" [SourceFileInfo.TargetPath]
+ // "Views\\ExportNotificationView" [SourceFileInfo.RelativeTargetPath]
+ //
+ // TargetPath concatenated with the directory portion of the RelativeTargetPath is the location to the .g.cs file:
+ //
+ // "c:\\greenshot\\src\\Greenshot.Addons\\obj\\Debug\\net6.0-windows\\Views"
+ //
+ string pathOfRelativeSourceFilePath = System.IO.Path.GetDirectoryName(SourceFileInfo.RelativeSourceFilePath);
+
+ // Return the parent folder of the target file with a trailing DirectorySeparatorChar.
+ // Return a relative path if possible. Else, return an absolute path.
+ #if NETFX
+ string path = PathInternal.GetRelativePath(TargetPath + pathOfRelativeSourceFilePath, SourceFileInfo.SourcePath, StringComparison.OrdinalIgnoreCase);
#else
- return Path.GetRelativePath(TargetPath, SourceFileInfo.SourcePath) + Path.DirectorySeparatorChar;
+ string path = Path.GetRelativePath(TargetPath + pathOfRelativeSourceFilePath, SourceFileInfo.SourcePath);
#endif
+ // Always return a path with a trailing DirectorySeparatorChar.
+ return path.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar;
+ }
+ else
+ {
+ string parentFolderPrefix = string.Empty;
+ if (TargetPath.StartsWith(SourceFileInfo.SourcePath, StringComparison.OrdinalIgnoreCase))
+ {
+ string relPath = TargetPath.Substring(SourceFileInfo.SourcePath.Length);
+ relPath += SourceFileInfo.RelativeSourceFilePath;
+ string[] dirs = relPath.Split(new Char[] { Path.DirectorySeparatorChar });
+ for (int i = 1; i < dirs.Length; i++)
+ {
+ parentFolderPrefix += PARENTFOLDER;
+ }
+ }
+
+ return parentFolderPrefix;
+ }
}
}
diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/CompilerWrapper.cs b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/CompilerWrapper.cs
index d47c9af6ff0..5ae45bc28d4 100644
--- a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/CompilerWrapper.cs
+++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/CompilerWrapper.cs
@@ -201,6 +201,11 @@ internal int ErrorTimes
get { return _nErrors; }
}
+ internal bool SupportCustomOutputPaths
+ {
+ set { _mc.SupportCustomOutputPaths = value; }
+ }
+
//
// Start the compilation.
//
diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/TaskHelper.cs b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/TaskHelper.cs
index e6808dd1266..527ec58082d 100644
--- a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/TaskHelper.cs
+++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/TaskHelper.cs
@@ -223,7 +223,7 @@ internal static string GetWholeExceptionMessage(Exception exception)
//
// Helper to create CompilerWrapper.
//
- internal static CompilerWrapper CreateCompilerWrapper(bool fInSeparateDomain, ref AppDomain appDomain)
+ internal static CompilerWrapper CreateCompilerWrapper()
{
return new CompilerWrapper();
}
diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft.WinFX.targets b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft.WinFX.targets
index 32ba51576be..4674f005c9b 100644
--- a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft.WinFX.targets
+++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft.WinFX.targets
@@ -244,7 +244,8 @@
ExtraBuildControlFiles="@(ExtraBuildControlFiles)"
XamlDebuggingInformation="$(XamlDebuggingInformation)"
IsRunningInVisualStudio="$(BuildingInsideVisualStudio)"
- OutputPath="$(IntermediateOutputPath)">
+ OutputPath="$(IntermediateOutputPath)"
+ SupportCustomOutputPaths="$(IncludePackageReferencesDuringMarkupCompilation)">
@@ -304,7 +305,8 @@
XamlDebuggingInformation="$(XamlDebuggingInformation)"
GeneratedBaml=""
OutputPath="$(IntermediateOutputPath)"
- ContinueOnError="false" >
+ ContinueOnError="false"
+ SupportCustomOutputPaths="$(IncludePackageReferencesDuringMarkupCompilation)">
+
+
<_SourceGeneratedNuGetPropsAndTargets Include="$(MSBuildProjectExtensionsPath)$(_ParentProjectName)$(_ParentProjectExtension).nuget.g.props"/>
<_SourceGeneratedNuGetPropsAndTargets Include="$(MSBuildProjectExtensionsPath)$(_ParentProjectName)$(_ParentProjectExtension).nuget.g.targets"/>
<_SourceGeneratedNuGetPropsAndTargets Include="$(MSBuildProjectExtensionsPath)$(_ParentProjectName)$(_ParentProjectExtension).nuget.dgspec.json"/>
- <_DestGeneratedNuGetPropsAndTargets Include="$(MSBuildProjectExtensionsPath)$(_TemporaryTargetAssemblyProjectName).nuget.g.props"/>
- <_DestGeneratedNuGetPropsAndTargets Include="$(MSBuildProjectExtensionsPath)$(_TemporaryTargetAssemblyProjectName).nuget.g.targets"/>
- <_DestGeneratedNuGetPropsAndTargets Include="$(MSBuildProjectExtensionsPath)$(_TemporaryTargetAssemblyProjectName).nuget.dgspec.json"/>
+ <_DestGeneratedNuGetPropsAndTargets Include="$(BaseIntermediateOutputPath)$(_TemporaryTargetAssemblyProjectName).nuget.g.props"/>
+ <_DestGeneratedNuGetPropsAndTargets Include="$(BaseIntermediateOutputPath)$(_TemporaryTargetAssemblyProjectName).nuget.g.targets"/>
+ <_DestGeneratedNuGetPropsAndTargets Include="$(BaseIntermediateOutputPath)$(_TemporaryTargetAssemblyProjectName).nuget.dgspec.json"/>
+
+
+ <_SourceGeneratedNuGetPropsAndTargets Include="$(MSBuildProjectExtensionsPath)project.assets.json"/>
+ <_SourceGeneratedNuGetPropsAndTargets Include="$(MSBuildProjectExtensionsPath)project.nuget.cache"/>
+
+ <_DestGeneratedNuGetPropsAndTargets Include="$(BaseIntermediateOutputPath)project.assets.json"/>
+ <_DestGeneratedNuGetPropsAndTargets Include="$(BaseIntermediateOutputPath)project.nuget.cache"/>
+
+
+ /// Support custom IntermediateOutputPath and BaseIntermediateOutputPath outside the project path
+ ///
+ public bool SupportCustomOutputPaths { get; set; } = false;
+
///
/// Generated source code files for the given programing language.
///
@@ -1215,7 +1220,7 @@ private void DoMarkupCompilation()
try
{
- compilerWrapper = TaskHelper.CreateCompilerWrapper(AlwaysCompileMarkupFilesInSeparateDomain, ref appDomain);
+ compilerWrapper = TaskHelper.CreateCompilerWrapper();
if (compilerWrapper != null)
{
@@ -1239,6 +1244,8 @@ private void DoMarkupCompilation()
compilerWrapper.ContentFiles = CompilerAnalyzer.ContentFiles;
+ compilerWrapper.SupportCustomOutputPaths = SupportCustomOutputPaths;
+
// Process Reference list here.
ArrayList referenceList = ProcessReferenceList();
diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/MarkupCompilePass2.cs b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/MarkupCompilePass2.cs
index b00d05886dd..bc9f6dd0bba 100644
--- a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/MarkupCompilePass2.cs
+++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/MarkupCompilePass2.cs
@@ -322,6 +322,11 @@ public bool XamlDebuggingInformation
set { _xamlDebuggingInformation = value; }
}
+ ///
+ /// Support custom IntermediateOutputPath and BaseIntermediateOutputPath outside the project path
+ ///
+ public bool SupportCustomOutputPaths { get; set; } = false;
+
///
/// Known reference paths hold referenced assemblies which are never changed during the build procedure.
/// such as references in GAC, in framework directory or framework SDK directory etc.
@@ -634,7 +639,7 @@ private void DoLocalReferenceMarkupCompilation(FileUnit localApplicationFile, Fi
try
{
- compilerWrapper = TaskHelper.CreateCompilerWrapper(AlwaysCompileMarkupFilesInSeparateDomain, ref appDomain);
+ compilerWrapper = TaskHelper.CreateCompilerWrapper();
if (compilerWrapper != null)
{
@@ -645,6 +650,8 @@ private void DoLocalReferenceMarkupCompilation(FileUnit localApplicationFile, Fi
compilerWrapper.UnknownErrorID = UnknownErrorID;
compilerWrapper.XamlDebuggingInformation = XamlDebuggingInformation;
+ compilerWrapper.SupportCustomOutputPaths = SupportCustomOutputPaths;
+
compilerWrapper.TaskFileService = _taskFileService;
if (OutputType.Equals(SharedStrings.Exe) || OutputType.Equals(SharedStrings.WinExe))