Skip to content

Commit 07b4268

Browse files
Merge pull request #10315 from MicrosoftDocs/main638569515163941963sync_temp
For protected branch, push strategy should use PR and merge to target branch method to work around git push error
2 parents 0b9175d + 72c4e16 commit 07b4268

13 files changed

+215
-35
lines changed

docs/deployment/quickstart-deploy-aspnet-web-app.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: Publish an ASP.NET web app
33
description: Use the Publish tool in Visual Studio to deploy ASP.NET and ASP.NET Core apps to local web servers like IIS or remote cloud environments like Azure App Service.
4-
ms.date: 01/11/2024
4+
ms.date: 07/15/2024
55
ms.topic: quickstart
66
helpviewer_keywords:
77
- "deployment, web app"
@@ -17,6 +17,9 @@ In this article, you'll learn how to publish your first ASP.NET web app to vario
1717

1818
This article supports ASP.NET and ASP.NET Core.
1919

20+
> [!NOTE]
21+
> This article covers manual deployment, which is great for quickly getting something up and running, but for larger projects and production scenarios, you might want to set up a deployment pipeline. You can use [GitHub Actions](../azure/azure-deployment-using-github-actions.md) or [Azure DevOps Pipelines](/azure/devops/pipelines/get-started/what-is-azure-pipelines) to set up automatic deployments with continuous integration for such scenarios.
22+
2023
## Prerequisites
2124

2225
You need [Visual Studio](https://www.visualstudio.com/downloads) installed with the ASP.NET and web development workload.
@@ -158,4 +161,4 @@ You can import publish settings [from IIS](./tutorial-import-publish-settings-ii
158161

159162
## Related Content
160163

161-
- [.NET appliction deployment](/dotnet/core/deploying/)
164+
- [.NET application deployment](/dotnet/core/deploying/)
Loading
Loading
Loading
Loading
Loading
Loading
Loading

docs/msbuild/obtaining-build-logs-with-msbuild.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: Obtaining Build Logs with MSBuild
33
description: Use switches with MSBuild and specify how much build data to review and whether to save build data to one or more files.
4-
ms.date: 02/14/2024
4+
ms.date: 07/15/2024
55
ms.topic: how-to
66
helpviewer_keywords:
77
- MSBuild, logging
@@ -75,7 +75,7 @@ msbuild MyProject.proj -t:go -fl -flp:logfile=MyProjectOutput.log;verbosity=diag
7575
msbuild MyProject.proj -t:go -fl1 -fl2 -fl3 -flp2:logfile=JustErrors.log;errorsonly -flp3:logfile=JustWarnings.log;warningsonly
7676
```
7777

78-
For more information, see [Command-line reference](../msbuild/msbuild-command-line-reference.md).
78+
If you're using a shell that interprets semicolons (for example, bash), put single or double quotes around any option that has semicolons to prevent it from being interpreted as a command separator. For more information, see [Command-line reference](../msbuild/msbuild-command-line-reference.md).
7979

8080
## Save a binary log
8181

docs/msbuild/resolveassemblyreference-task.md

Lines changed: 30 additions & 30 deletions
Large diffs are not rendered by default.

docs/msbuild/toc.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ items:
110110
href: how-to-use-reserved-xml-characters-in-project-files.md
111111
- name: Advanced concepts
112112
items:
113+
- name: Troubleshoot assembly references
114+
href: troubleshoot-assembly-references.md
113115
- name: Batching
114116
items:
115117
- name: MSBuild batching
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
---
2+
title: Troubleshoot assembly reference build errors
3+
description: Learn how to understand and troubleshoot assembly reference problems in .NET builds with MSBuild.
4+
ms.date: 06/21/2024
5+
ms.topic: how-to
6+
author: ghogen
7+
ms.author: ghogen
8+
manager: mijacobs
9+
ms.subservice: msbuild
10+
---
11+
# Troubleshoot assembly references
12+
13+
One of the most important tasks in MSBuild and the .NET build process is resolving assembly references, which happens in the `ResolveAssemblyReference` task. This article explains some of the details of how `ResolveAssemblyReference` works, and how to troubleshoot build failures that can happen when `ResolveAssemblyReference` is unable to resolve a reference. To investigate assembly reference failures, you might want to install the [Structured Log Viewer](https://msbuildlog.com/) to view MSBuild logs. The screenshots in this article are taken from the Structured Log Viewer.
14+
15+
The purpose of `ResolveAssemblyReference` is to take all the references specified in `.csproj` files (or elsewhere) via the `<Reference>` item and map them to paths to assembly files in the filesystem.
16+
17+
The compilers only can accept a `.dll` path on the filesystem as a reference, so `ResolveAssemblyReference` converts strings like `mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089` that appear in project files to paths like `C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\mscorlib.dll`, which are then passed to the compiler via the `/r` switch.
18+
19+
Additionally `ResolveAssemblyReference` determines the complete set (actually the *transitive closure* in graph theory terms) of all `.dll`and `.exe` references recursively, and for each of them determines whether it should be copied to the build output directory or not. It doesn't do the actual copying (that is handled later, after the actual compile step), but it prepares an item list of files to copy.
20+
21+
`ResolveAssemblyReference` is invoked from the `ResolveAssemblyReferences` target:
22+
23+
![Screenshot of log viewer showing when ResolveAssemblyReferences is called in the build process.](media/resolve-assembly-references-in-log-viewer.png)
24+
25+
If you notice the ordering, `ResolveAssemblyReferences` is happening before `Compile`, and of course, `CopyFilesToOutputDirectory` happens after `Compile`.
26+
27+
> [!NOTE]
28+
> `ResolveAssemblyReference` task is invoked in the standard `.targets` file `Microsoft.Common.CurrentVersion.targets` in the MSBuild installation folders. You can also browse the .NET SDK MSBuild targets online at <https://github.com/dotnet/msbuild/blob/a936b97e30679dcea4d99c362efa6f732c9d3587/src/Tasks/Microsoft.Common.CurrentVersion.targets#L1991-L2140>. This link shows exactly where the `ResolveAssemblyReference` task is invoked in the `.targets` file.
29+
30+
## ResolveAssemblyReference inputs
31+
32+
`ResolveAssemblyReference` is comprehensive about logging its inputs:
33+
34+
![Screenshot showing input parameters for the ResolveAssemblyReference task.](media/resolve-assembly-references-inputs.png)
35+
36+
The `Parameters` node is standard for all tasks, but additionally `ResolveAssemblyReference` logs its own set of information under Inputs (which is basically the same as under `Parameters`, but structured differently).
37+
38+
The most important inputs are `Assemblies` and `AssemblyFiles`:
39+
40+
```xml
41+
<ResolveAssemblyReference
42+
Assemblies="@(Reference)"
43+
AssemblyFiles="@(_ResolvedProjectReferencePaths);@(_ExplicitReference)"
44+
```
45+
46+
`Assemblies` uses the contents of the `Reference` MSBuild item at the moment when `ResolveAssemblyReference` is invoked for the project. All the metadata and assembly references, including your NuGet references, should be contained in this item. Each reference has a rich set of metadata attached to it:
47+
48+
![Screenshot showing metadata on an assembly reference.](./media/resolve-assembly-references-metadata.png)
49+
50+
`AssemblyFiles` comes from `ResolveProjectReference` target's output item called `_ResolvedProjectReferencePaths`. `ResolveProjectReference` runs before `ResolveAssemblyReference` and it converts `<ProjectReference>` items to paths of built assemblies on disk. So the `AssemblyFiles` will contain the assemblies built by all referenced projects of the current project:
51+
52+
![Screenshot showing AssemblyFiles.](./media/resolve-assembly-references-assemblyfiles.png)
53+
54+
Another useful input is the boolean `FindDependencies` parameter, which takes its value from the `_FindDependencies` property:
55+
56+
```xml
57+
FindDependencies="$(_FindDependencies)"
58+
```
59+
60+
You can set this property to `false` in your build to turn off analyzing transitive dependency assemblies.
61+
62+
## ResolveAssemblyReference algorithm
63+
64+
The simplified algorithm for the `ResolveAssemblyReference` task is as follows:
65+
66+
1. Log inputs.
67+
1. Check the `MSBUILDLOGVERBOSERARSEARCHRESULTS` environment variable. Set this variable to any value to get more detailed logs.
68+
1. Initialize the table of references object.
69+
1. Read the cache file from the `obj` directory (if present).
70+
1. Compute the closure of dependencies.
71+
1. Build the output tables.
72+
1. Write the cache file to the `obj` directory.
73+
1. Log the results.
74+
75+
The algorithm takes the input list of assemblies (both from metadata and project references), retrieves the list of references for each assembly it processes (by reading metadata) and builds a complete set (transitive closure) of all referenced assemblies, and resolves them from various locations (including the GAC, AssemblyFoldersEx, and so on).
76+
77+
Referenced assemblies are added to the list iteratively until no more new references are added. Then the algorithm stops.
78+
79+
Direct references that you provided to the task are called Primary references. Indirect assemblies that were added to the set because of a transitive reference are called Dependency. The record for each indirect assembly keeps track of all the primary ("root") items that led to its inclusion and their corresponding metadata.
80+
81+
## Results of the ResolveAssemblyReference task
82+
83+
`ResolveAssemblyReference` provides detailed logging of the results:
84+
85+
![Screenshot showing ResolveAssemblyReference results in the structured log viewer.](media/resolve-assembly-references-results.png)
86+
87+
Resolved assemblies are divided into two categories: Primary references and Dependencies. Primary references were specified explicitly as references of the project being built. Dependencies were inferred from references of references transitively.
88+
89+
> [!IMPORTANT]
90+
> `ResolveAssemblyReference` reads assembly metadata to determine the references of a given assembly. When the C# compiler emits an assembly, it only adds references to assemblies that are actually needed. So, it might happen that when you compile a certain project, the project may specify an unneeded reference that won't be baked into the assembly. It's OK to add references to project that are not needed; they are ignored.
91+
92+
## CopyLocal item metadata
93+
94+
References can also have the `CopyLocal` metadata or not. If the reference has `CopyLocal = true`, it will later be copied to the output directory by the `CopyFilesToOutputDirectory` target. In this example, `DataFlow` has `CopyLocal` set to true, while `Immutable` does not:
95+
96+
![Screenshot showing CopyLocal settings for some references.](media/resolve-assembly-references-copylocal.png)
97+
98+
If the `CopyLocal` metadata is missing entirely, it's assumed to be true by default. So `ResolveAssemblyReference` by default tries to copy dependencies to output unless it finds a reason not to. `ResolveAssemblyReference` records the reasons why it chose a particular reference to be `CopyLocal` or not.
99+
100+
All possible reasons for `CopyLocal` decision are enumerated in the following table. It's useful to know these strings to be able to search for them in build logs.
101+
102+
| CopyLocal state | Description |
103+
|-|-|
104+
| `Undecided` | The copy local state is undecided right now. |
105+
| `YesBecauseOfHeuristic` | The reference should have `CopyLocal='true'` because it wasn't 'no' for any reason. |
106+
| `YesBecauseReferenceItemHadMetadata` | The Reference should have `CopyLocal='true'` because its source item has Private='true' |
107+
| `NoBecauseFrameworkFile` | The reference should have `CopyLocal='false'` because it is a framework file. |
108+
| `NoBecausePrerequisite` | The reference should have `CopyLocal='false'` because it is a prerequisite file. |
109+
| `NoBecauseReferenceItemHadMetadata` | The reference should have `CopyLocal='false'` because the `Private` attribute is set to 'false' in the project. |
110+
| `NoBecauseReferenceResolvedFromGAC` | The reference should have `CopyLocal='false'` because it was resolved from the GAC. |
111+
| `NoBecauseReferenceFoundInGAC` | Legacy behavior, `CopyLocal='false'` when the assembly is found in the GAC (even when it was resolved elsewhere). |
112+
| `NoBecauseConflictVictim` | The reference should have `CopyLocal='false'` because it lost a conflict between a same-named assembly file. |
113+
| `NoBecauseUnresolved` | The reference was unresolved. It can't be copied to the bin directory because it wasn't found. |
114+
| `NoBecauseEmbedded` | The reference was embedded. It shouldn't be copied to the bin directory because it won't be loaded at runtime. |
115+
| `NoBecauseParentReferencesFoundInGAC` | The property `copyLocalDependenciesWhenParentReferenceInGac` is set to false and all the parent source items were found in the GAC. |
116+
| `NoBecauseBadImage` | The assembly file provided should not be copied because it is a bad image, possibly not managed, possibly not an assembly at all. |
117+
118+
## Private item metadata
119+
120+
An important part of determining `CopyLocal` is the `Private` metadata on all primary references. Each reference (primary or dependency) has a list of all primary references (source items) that have contributed to that reference being added to the closure.
121+
122+
- If none of the source items specify `Private` metadata, `CopyLocal` is set to `True` (or not set, which defaults to `True`)
123+
- If any of the source items specify `Private=true`, `CopyLocal` is set to `True`
124+
- If none of the source assemblies specify `Private=true` and at least one specifies `Private=false`, `CopyLocal` is set to `False`
125+
126+
## Which reference set Private to false?
127+
128+
The last point is an often used reason for `CopyLocal` being set to false:
129+
`This reference is not "CopyLocal" because at least one source item had "Private" set to "false" and no source items had "Private" set to "true".`
130+
131+
MSBuild doesn't tell us which reference has set `Private` to false, but the structured log viewer adds `Private` metadata to the items that had it specified above:
132+
133+
![Screenshot showing Private set to false in the structured log viewer.](media/resolve-assembly-references-private-false.png)
134+
135+
This simplifies investigations and tells you exactly which reference caused the dependency in question to be set with `CopyLocal=false`.
136+
137+
## Global Assembly Cache
138+
139+
The Global Assembly Cache (GAC) plays an important role in determining whether to copy references to output. This is unfortunate because the contents of the GAC is machine-specific and this results in problems for reproducible builds (where the behavior differs on different machine dependent on machine state, such as the GAC).
140+
141+
There were recent fixes made to `ResolveAssemblyReference` to alleviate the situation. You can control the behavior by these two new inputs to `ResolveAssemblyReference`:
142+
143+
```xml
144+
CopyLocalDependenciesWhenParentReferenceInGac="$(CopyLocalDependenciesWhenParentReferenceInGac)"
145+
DoNotCopyLocalIfInGac="$(DoNotCopyLocalIfInGac)"
146+
```
147+
148+
## AssemblySearchPaths
149+
150+
There are two ways to customize the list of paths `ResolveAssemblyReference` searches in attempting to locate an assembly. To fully customize the list, the property `AssemblySearchPaths` can be set ahead of time. The order matters; if an assembly is in two locations, `ResolveAssemblyReference` stops after it finds it at the first location.
151+
152+
By default, there are ten locations `ResolveAssemblyReference` searches (four if you use the .NET SDK), and each can be disabled by setting the relevant flag to false:
153+
154+
- Searching files from the current project is disabled by setting the `AssemblySearchPath_UseCandidateAssemblyFiles` property to false.
155+
- Searching the reference path property (from a `.user` file) is disabled by setting the `AssemblySearchPath_UseReferencePath` property to false.
156+
- Using the hint path from the item is disabled by setting the `AssemblySearchPath_UseHintPathFromItem` property to false.
157+
- Using the directory with MSBuild's target runtime is disabled by setting the `AssemblySearchPath_UseTargetFrameworkDirectory` property to false.
158+
- Searching assembly folders from AssemblyFolders.config is disabled by setting the `AssemblySearchPath_UseAssemblyFoldersConfigFileSearchPath` property to false.
159+
- Searching the registry is disabled by setting the `AssemblySearchPath_UseRegistry` property to false.
160+
- Searching legacy registered assembly folders is disabled by setting the `AssemblySearchPath_UseAssemblyFolders` property to false.
161+
- Looking in the GAC is disabled by setting the `AssemblySearchPath_UseGAC` property to false.
162+
- Treating the reference's Include as a real file name is disabled by setting the `AssemblySearchPath_UseRawFileName` property to false.
163+
- Checking the application's output folder is disabled by setting the `AssemblySearchPath_UseOutDir` property to false.
164+
165+
## There was a conflict
166+
167+
A common situation is MSBuild gives a warning about different versions of the same assembly being used by different references. The solution often involves adding a binding redirect to the app.config file.
168+
169+
A useful way to investigate these conflicts is to search in MSBuild Structured Log Viewer for "There was a conflict". It shows you detailed information about which references needed which versions of the assembly in question.
170+
171+
## Related content
172+
173+
- [ResolveAssemblyReference task](resolveassemblyreference-task.md)

docs/profiling/instrumentation.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: "Instrument your .NET application"
33
description: Explore how to use the dynamic Instrumentation tool for your .NET applications (C#, C++, Visual Basic, F#) in Visual Studio and analyze the report.
4-
ms.date: "01/31/2024"
4+
ms.date: "07/18/2024"
55
ms.topic: "conceptual"
66
author: "mikejo5000"
77
ms.author: "mikejo"
@@ -38,6 +38,8 @@ The tool is similar to the CPU Usage tool except it's based on wall clock time i
3838

3939
![Screenshot showing Select items to instrument dialog.](./media/vs-2022/instrumentation-select-items-to-instrument.png "Screenshot showing Select items to instrument dialog.")
4040

41+
Starting in Visual Studio 2022 version 17.11 Preview 1, the profiler persists the selected items for the next profiling run.
42+
4143
1. Select **OK**.
4244

4345
1. After the tool starts running, go through the scenario you want to profile in your app. Then select **Stop collection** or close the app to see your data.

0 commit comments

Comments
 (0)