英文:
Roslyn fails to compile a trivial project
问题
我正在尝试使用Roslyn来编译一个简单的项目,但它失败了。
考虑以下设置(假设c:\temp存在并且已安装.NET 6):
-
创建目录 c:\temp\TestLib
-
使用记事本打开 c:\temp\TestLib\TestLib.csproj 文件
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net6.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup> </Project>
-
使用记事本打开 c:\temp\TestLib\SomeClass.cs 文件
namespace TestLib { public class SomeClass { void DoThings() { Console.WriteLine("Things!"); } } }
-
切换到目录 c:\temp\TestLib
-
运行命令 dotnet build
结果:构建成功
-
创建目录 c:\temp\RoslynTrouble
-
使用记事本打开 c:\temp\RoslynTrouble\RoslynTrouble.csproj 文件
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net6.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.Build.Locator" Version="1.5.5" /> <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="3.8.0" /> <PackageReference Include="Microsoft.CodeAnalysis.Workspaces.MSBuild" Version="3.8.0" /> </ItemGroup> </Project>
-
使用记事本打开 c:\temp\RoslynTrouble\Program.cs 文件
using Microsoft.Build.Locator; using Microsoft.CodeAnalysis.MSBuild; class TestProgram { public static async Task Main(string[] args) { string csprojPath = args[0]; var instance = MSBuildLocator.RegisterDefaults(); Console.WriteLine(instance.Name + ": " + instance.Version); var workspace = MSBuildWorkspace.Create(); var project = await workspace.OpenProjectAsync(csprojPath); var compilation = await project.GetCompilationAsync(); if (compilation == null) { Console.WriteLine("Error: unexpected null compilation"); return; } foreach (var diagnostic in compilation.GetDiagnostics()) { Console.WriteLine(diagnostic); } } }
-
切换到目录 c:\temp\RoslynTrouble
-
运行命令 dotnet run c:\temp\TestLib\TestLib.csproj
- 期望结果:无错误
- 实际结果:出现许多编译错误
你遇到的问题是因为在 TestLib 项目的 GlobalUsings.g.cs 文件中存在错误。这个文件包含了全局的 using 指令,但它看起来有问题。你可以尝试将 TestLib 项目的 GlobalUsings.g.cs 文件删除,然后重新构建 TestLib 项目,再运行 RoslynTrouble 项目,看看是否仍然有编译错误。
另外,请确保你的环境中有.NET 6 SDK 安装,并且路径设置正确。如果问题仍然存在,请提供更多详细信息,以便更好地帮助你解决问题。
英文:
I am trying to use Roslyn to compile a trivial project but it fails.
Consider the following setup (assuming c:\temp exists and you have .NET 6 installed):
-
mkdir c:\temp\TestLib
-
notepad c:\temp\TestLib\TestLib.csproj
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net6.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup> </Project>
-
notepad c:\temp\TestLib\SomeClass.cs
namespace TestLib { public class SomeClass { void DoThings() { Console.WriteLine("Things!"); } } }
-
cd c:\temp\TestLib
-
dotnet build
Result: Build succeeded
-
mkdir c:\temp\RoslynTrouble
-
notepad c:\temp\RoslynTrouble\RoslynTrouble.csproj
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net6.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.Build.Locator" Version="1.5.5" /> <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="3.8.0" /> <PackageReference Include="Microsoft.CodeAnalysis.Workspaces.MSBuild" Version="3.8.0" /> </ItemGroup> </Project>
-
notepad c:\temp\RoslynTrouble\Program.cs
using Microsoft.Build.Locator; using Microsoft.CodeAnalysis.MSBuild; class TestProgram { public static async Task Main(string[] args) { string csprojPath = args[0]; var instance = MSBuildLocator.RegisterDefaults(); Console.WriteLine(instance.Name + ": " + instance.Version); var workspace = MSBuildWorkspace.Create(); var project = await workspace.OpenProjectAsync(csprojPath); var compilation = await project.GetCompilationAsync(); if (compilation == null) { Console.WriteLine("Error: unexpected null compilation"); return; } foreach (var diagnostic in compilation.GetDiagnostics()) { Console.WriteLine(diagnostic); } } }
-
cd c:\temp\RoslynTrouble
-
dotnet run c:\temp\TestLib\TestLib.csproj
- Expected result: no errors
- Actual result: lots of compilation errors:
.NET Core SDK: 6.0.203
c:\open\prototypes\TestLib\obj\Debug\net6.0\TestLib.GlobalUsings.g.cs(2,1): error CS0116: A namespace cannot directly contain members such as fields or methods
c:\open\prototypes\TestLib\obj\Debug\net6.0\TestLib.GlobalUsings.g.cs(3,1): error CS0116: A namespace cannot directly contain members such as fields or methods
c:\open\prototypes\TestLib\obj\Debug\net6.0\TestLib.GlobalUsings.g.cs(4,1): error CS0116: A namespace cannot directly contain members such as fields or methods
c:\open\prototypes\TestLib\obj\Debug\net6.0\TestLib.GlobalUsings.g.cs(5,1): error CS0116: A namespace cannot directly contain members such as fields or methods
c:\open\prototypes\TestLib\obj\Debug\net6.0\TestLib.GlobalUsings.g.cs(6,1): error CS0116: A namespace cannot directly contain members such as fields or methods
c:\open\prototypes\TestLib\obj\Debug\net6.0\TestLib.GlobalUsings.g.cs(7,1): error CS0116: A namespace cannot directly contain members such as fields or methods
c:\open\prototypes\TestLib\obj\Debug\net6.0\TestLib.GlobalUsings.g.cs(8,1): error CS0116: A namespace cannot directly contain members such as fields or methods
c:\open\prototypes\TestLib\SomeClass.cs(7,13): error CS0103: The name 'Console' does not exist in the current context
c:\open\prototypes\TestLib\obj\Debug\net6.0\TestLib.GlobalUsings.g.cs(2,8): hidden CS8019: Unnecessary using directive.
c:\open\prototypes\TestLib\obj\Debug\net6.0\TestLib.GlobalUsings.g.cs(8,8): hidden CS8019: Unnecessary using directive.
c:\open\prototypes\TestLib\obj\Debug\net6.0\TestLib.AssemblyInfo.cs(11,1): hidden CS8019: Unnecessary using directive.
c:\open\prototypes\TestLib\obj\Debug\net6.0\TestLib.GlobalUsings.g.cs(7,8): hidden CS8019: Unnecessary using directive.
c:\open\prototypes\TestLib\obj\Debug\net6.0\TestLib.GlobalUsings.g.cs(6,8): hidden CS8019: Unnecessary using directive.
c:\open\prototypes\TestLib\obj\Debug\net6.0\.NETCoreApp,Version=v6.0.AssemblyAttributes.cs(2,1): hidden CS8019: Unnecessary using directive.
c:\open\prototypes\TestLib\obj\Debug\net6.0\TestLib.GlobalUsings.g.cs(3,8): hidden CS8019: Unnecessary using directive.
c:\open\prototypes\TestLib\obj\Debug\net6.0\TestLib.AssemblyInfo.cs(12,1): hidden CS8019: Unnecessary using directive.
c:\open\prototypes\TestLib\obj\Debug\net6.0\TestLib.GlobalUsings.g.cs(4,8): hidden CS8019: Unnecessary using directive.
c:\open\prototypes\TestLib\obj\Debug\net6.0\TestLib.GlobalUsings.g.cs(5,8): hidden CS8019: Unnecessary using directive.
c:\open\prototypes\TestLib\obj\Debug\net6.0\.NETCoreApp,Version=v6.0.AssemblyAttributes.cs(3,1): hidden CS8019: Unnecessary using directive.
What am I missing and how can I fix those errors?
答案1
得分: 0
以下是已翻译的内容:
mkdir c:\temp\TestLib
notepad c:\temp\TestLib\TestLib.csproj
- 单击
Yes
TestLib.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
-
另存为(使用 "UTF-8" 编码保存)
-
notepad c:\temp\TestLib\SomeClass.cs
-
单击
Yes
SomeClass.cs:
Note: 将方法更改为 public
- 拥有一个方法的类并将其设为 private
没什么意义。
namespace TestLib
{
public class SomeClass
{
public void DoThings()
{
Console.WriteLine("Things!");
}
}
}
-
另存为(使用 "UTF-8" 编码保存)
-
mkdir c:\temp\RoslynTrouble
-
notepad c:\temp\RoslynTrouble\RoslynTrouble.csproj
-
单击
Yes
RoslynTrouble.csproj:
Note: 使用版本 4.4.0
适用于 Microsoft.CodeAnalysis.CSharp.Workspaces
和 Microsoft.CodeAnalysis.Workspaces.MSBuild
。
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Build.Locator" Version="1.5.5" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.4.0" />
<PackageReference Include="Microsoft.CodeAnalysis.Workspaces.MSBuild" Version="4.4.0" />
</ItemGroup>
</Project>
-
另存为(使用 "UTF-8" 编码保存)
-
notepad c:\temp\RoslynTrouble\Program.cs
-
单击
Yes
Program.cs:
Note: 添加命名空间 RoslynTrouble
。将类名更改为 Program
以匹配文件名(Program.cs)。
using Microsoft.Build.Locator;
using Microsoft.CodeAnalysis.MSBuild;
namespace RoslynTrouble
{
public class Program
{
public static async Task Main(string[] args)
{
string csprojPath = args[0];
var instance = MSBuildLocator.RegisterDefaults();
Console.WriteLine(instance.Name + ": " + instance.Version);
var workspace = MSBuildWorkspace.Create();
var project = await workspace.OpenProjectAsync(csprojPath);
var compilation = await project.GetCompilationAsync();
if (compilation == null)
{
Console.WriteLine("Error: unexpected null compilation");
return;
}
foreach (var diagnostic in compilation.GetDiagnostics())
{
Console.WriteLine(diagnostic);
}
}
}
}
-
另存为(使用 "UTF-8" 编码保存)
-
cd c:\temp\RoslynTrouble
-
dotnet run "C:\temp\TestLib\TestLib.csproj"
Note: 上述命令中的双引号是可选的,因为路径中没有空格。
Result:
Note: 结果中有警告,但没有错误。
.NET Core SDK: 6.0.301
C:\temp\TestLib\obj\Debug\net6.0\.NETCoreApp,Version=v6.0.AssemblyAttributes.cs(2,7): hidden CS8933: The using directive for 'System' appeared previously as global using
C:\temp\TestLib\obj\Debug\net6.0\TestLib.AssemblyInfo.cs(10,7): hidden CS8933: The using directive for 'System' appeared previously as global using
C:\temp\TestLib\obj\Debug\net6.0\TestLib.GlobalUsings.g.cs(5,1): hidden CS8019: Unnecessary using directive.
C:\temp\TestLib\obj\Debug\net6.0\TestLib.GlobalUsings.g.cs(3,1): hidden CS8019: Unnecessary using directive.
C:\temp\TestLib\obj\Debug\net6.0\TestLib.GlobalUsings.g.cs(4,1): hidden CS8019: Unnecessary using directive.
C:\temp\TestLib\obj\Debug\net6.0\TestLib.AssemblyInfo.cs(11,1): hidden CS8019: Unnecessary using directive.
C:\temp\TestLib\obj\Debug\net6.0\.NETCoreApp,Version=v6.0.AssemblyAttributes.cs(2,1): hidden CS8019: Unnecessary using directive.
C:\temp\TestLib\obj\Debug\net6.0\TestLib.GlobalUsings.g.cs(8,1): hidden CS8019: Unnecessary using directive.
C:\temp\TestLib\obj\Debug\net6.0\.NETCoreApp,Version=v6.0.AssemblyAttributes.cs(3,1): hidden CS8019: Unnecessary using directive.
C:\temp\TestLib\obj\Debug\net6.0\TestLib.AssemblyInfo.cs(10,1): hidden CS8019: Unnecessary using directive.
C:\temp\TestLib\obj\Debug\net6.0\TestLib.GlobalUsings.g.cs(7,1): hidden CS8019: Unnecessary using directive.
C:\temp\TestLib\obj\Debug\net6.0\TestLib.GlobalUsings.g.cs(6,1): hidden CS8019: Unnecessary using directive.
如果希望避免显示警告,可以使用以下 Program.cs
的替代代码:
using Microsoft.Build.Locator;
using Microsoft.CodeAnalysis.MSBuild;
namespace RoslynTrouble
{
public class Program
{
public static async Task Main(string[] args)
{
bool errorsExist = false;
string csprojPath = args[0];
var instance = MSBuildLocator.RegisterDefaults();
Console.WriteLine(instance.Name + ": " + instance.Version);
var workspace = MSBuildWorkspace.Create();
var project = await workspace.OpenProjectAsync(csprojPath);
var compilation = await project.GetCompilationAsync();
if (compilation == null)
{
Console.WriteLine("Error: unexpected null compilation");
return;
}
foreach (Microsoft.CodeAnalysis.Diagnostic diagnostic in compilation.GetDiagnostics())
{
if (diagnostic.Severity != Microsoft.CodeAnalysis.DiagnosticSeverity.Hidden &&
diagnostic.Severity != Microsoft.CodeAnalysis.DiagnosticSeverity.Warning)
{
Console.WriteLine(diagnostic);
errorsExist = true;
}
}
if (!errorsExist)
Console.WriteLine($"
<details>
<summary>英文:</summary>
Below you'll find the modifications described in a `Note`. Try the following:
1. `mkdir c:\temp\TestLib`
2. `notepad c:\temp\TestLib\TestLib.csproj`
3. Click `Yes`
[![enter image description here][1]][1]
**TestLib.csproj**:
```
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
```
4. Save As (save with "UTF-8" encoding)
5. `notepad c:\temp\TestLib\SomeClass.cs`
6. Click `Yes`
[![enter image description here][2]][2]
**SomeClass.cs**:
**Note**: Made the method `public` - not much point in having a class with one method and making it `private`.
```
namespace TestLib
{
public class SomeClass
{
public void DoThings()
{
Console.WriteLine("Things!");
}
}
}
```
7. Save As (save with "UTF-8" encoding)
----------
8. `mkdir c:\temp\RoslynTrouble`
9. `notepad c:\temp\RoslynTrouble\RoslynTrouble.csproj`
10. Click `Yes`
[![enter image description here][3]][3]
**RoslynTrouble.csproj**:
**Note**: Use version `4.4.0` for `Microsoft.CodeAnalysis.CSharp.Workspaces` and `Microsoft.CodeAnalysis.Workspaces.MSBuild`.
```
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Build.Locator" Version="1.5.5" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.4.0" />
<PackageReference Include="Microsoft.CodeAnalysis.Workspaces.MSBuild" Version="4.4.0" />
</ItemGroup>
</Project>
```
11. Save As (save with "UTF-8" encoding)
12. `notepad c:\temp\RoslynTrouble\Program.cs`
13. Click `Yes`
[![enter image description here][4]][4]
**Program.cs**:
**Note**: Added namespace `RoslynTrouble`. Changed class name to `Program` to match the filename (Program.cs).
```
using Microsoft.Build.Locator;
using Microsoft.CodeAnalysis.MSBuild;
namespace RoslynTrouble
{
public class Program
{
public static async Task Main(string[] args)
{
string csprojPath = args[0];
var instance = MSBuildLocator.RegisterDefaults();
Console.WriteLine(instance.Name + ": " + instance.Version);
var workspace = MSBuildWorkspace.Create();
var project = await workspace.OpenProjectAsync(csprojPath);
var compilation = await project.GetCompilationAsync();
if (compilation == null)
{
Console.WriteLine("Error: unexpected null compilation");
return;
}
foreach (var diagnostic in compilation.GetDiagnostics())
{
Console.WriteLine(diagnostic);
}
}
}
}
```
14. Save As (save with "UTF-8" encoding)
----------
15. `cd c:\temp\RoslynTrouble`
16. `dotnet run "C:\temp\TestLib\TestLib.csproj"`
**Note**: The double-quotes in the command above are optional since there aren't any spaces in the path.
----------
**Result**:
**Note**: The result has warnings, but no errors.
.NET Core SDK: 6.0.301
C:\temp\TestLib\obj\Debug\net6.0.NETCoreApp,Version=v6.0.AssemblyAttributes.cs(2,7): hidden CS8933: The using directive for 'System' appeared previously as global using
C:\temp\TestLib\obj\Debug\net6.0\TestLib.AssemblyInfo.cs(10,7): hidden CS8933: The using directive for 'System' appeared previously as global using
C:\temp\TestLib\obj\Debug\net6.0\TestLib.GlobalUsings.g.cs(5,1): hidden CS8019: Unnecessary using directive.
C:\temp\TestLib\obj\Debug\net6.0\TestLib.GlobalUsings.g.cs(3,1): hidden CS8019: Unnecessary using directive.
C:\temp\TestLib\obj\Debug\net6.0\TestLib.GlobalUsings.g.cs(4,1): hidden CS8019: Unnecessary using directive.
C:\temp\TestLib\obj\Debug\net6.0\TestLib.AssemblyInfo.cs(11,1): hidden CS8019: Unnecessary using directive.
C:\temp\TestLib\obj\Debug\net6.0.NETCoreApp,Version=v6.0.AssemblyAttributes.cs(2,1): hidden CS8019: Unnecessary using directive.
C:\temp\TestLib\obj\Debug\net6.0\TestLib.GlobalUsings.g.cs(8,1): hidden CS8019: Unnecessary using directive.
C:\temp\TestLib\obj\Debug\net6.0.NETCoreApp,Version=v6.0.AssemblyAttributes.cs(3,1): hidden CS8019: Unnecessary using directive.
C:\temp\TestLib\obj\Debug\net6.0\TestLib.AssemblyInfo.cs(10,1): hidden CS8019: Unnecessary using directive.
C:\temp\TestLib\obj\Debug\net6.0\TestLib.GlobalUsings.g.cs(7,1): hidden CS8019: Unnecessary using directive.
C:\temp\TestLib\obj\Debug\net6.0\TestLib.GlobalUsings.g.cs(6,1): hidden CS8019: Unnecessary using directive.
----------
If one would like to avoid displaying warnings, one could use the following alternative code for `Program.cs`:
using Microsoft.Build.Locator;
using Microsoft.CodeAnalysis.MSBuild;
namespace RoslynTrouble
{
public class Program
{
public static async Task Main(string[] args)
{
bool errorsExist = false;
string csprojPath = args[0];
var instance = MSBuildLocator.RegisterDefaults();
Console.WriteLine(instance.Name + ": " + instance.Version);
var workspace = MSBuildWorkspace.Create();
var project = await workspace.OpenProjectAsync(csprojPath);
var compilation = await project.GetCompilationAsync();
if (compilation == null)
{
Console.WriteLine("Error: unexpected null compilation");
return;
}
foreach (Microsoft.CodeAnalysis.Diagnostic diagnostic in compilation.GetDiagnostics())
{
if (diagnostic.Severity != Microsoft.CodeAnalysis.DiagnosticSeverity.Hidden &&
diagnostic.Severity != Microsoft.CodeAnalysis.DiagnosticSeverity.Warning)
{
Console.WriteLine(diagnostic);
errorsExist = true;
}
}
if (!errorsExist)
Console.WriteLine($"Successfully compiled '{args[0]}'.");
}
}
}
----------
**Resources**:
- [Roslyn Code Analysis returns false build errors from an error free solution][5]
[1]: https://i.stack.imgur.com/uLmGF.png
[2]: https://i.stack.imgur.com/BNEj3.png
[3]: https://i.stack.imgur.com/8U36E.png
[4]: https://i.stack.imgur.com/5I5Cy.png
[5]: https://stackoverflow.com/questions/58698247/roslyn-code-analysis-returns-false-build-errors-from-an-error-free-solution
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论