dotnet安装
.NET6默认会安装一个SDK和几个runtime
- .NET SDK
- .NET Runtime
- ASP.NET Core Runtime
- .NET Windows Desktop Runtime
可以通过dotnet
命令行的--list-sdks
以及--list-runtimes
列举。
dotnet命令行
设置环境变量DOTNET_CLI_TELEMETRY_OPTOUT为1,避免信息采集。参考.NET SDK and .NET CLI telemetry。
dotnet workload
通过dotnet workload search
可以搜索到可用的workload。比如maui或者wasm-tools相关的。
dotnet new
dotnet new
用于创建工程。直接执行会列出几个工程模板让你选择。
dotnet new web --search
则会列出NuGet.org上的可用工程模板。
比如创建一个winforms模板的app:
dotnet new winforms -n winforms-app1
疑问:生成的工程文件中,哪些是需要纳入版本控制的? 回到:在csproj文件,比如
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.1.635-beta">
。
dotnet build
在winforms-app1
目录下执行dotnet build
可以构建此工程。
相关命令:
dotnet clean
,清理工程
dotnet run
在winforms-app1
目录下执行dotnet run
可以运行此工程生成的可执行文件。
dotnet add
通过dotnet add
可以从NuGet.org安装发布的软件包。比如:
dotnet add package Microsoft.Windows.CsWinRT
为了能够编译CsWinRT,需要在项目中开启
<PropertyGroup>
<CsWinRTEnabled >false</CsWinRTEnabled>
</PropertyGroup>
否则会出现错误 Version 1.2.2 or greater produces “Path ‘7.0’ is not a file or directory” error #822 。
添加一个prelease的包需要指定--prerelease
选项,如下所示:
dotnet add package --prerelease cswin32
其他相关命令:
dotnet list package
列出工程中的的NuGet包dotnet remove package
删除一个NuGet包dotnet pack
可以用于制作nuget包dotnet nuget
隐藏着一些其他nuget相关命令
Using the Win32 Api in a C# program with C#/Win32
C#9引入了叫做Code Generators的东东,可以编译的时候动态生成代码。(听着有点像C++的模板,不过适用面看起来广多了)。
传统的.NET需要通过PInvoke来调用第三方代码。但是PInvoke需要描述文件。有专门的网站http://pinvoke.net/提供这些描述文件。
Code Generator给了PInvoke之外的另一种可能,CsWin32就是基于这种可能的产物。
来实践以下CsWin32
dotnet new console -o win32-app1
cd win32-app1
dotnet add package Microsoft.Windows.CsWin32 --prerelease
注意,必须使用0.1.422-beta版的package Microsoft.Windows.CsWin32,当前最新的0.1.635-beta会报错
error CS0234: The type or namespace name 'Windows' does not exist in the namespace 'Microsoft'
。
创建一个名为NativeMethods.txt的文件,内容如下:
FindFirstFile
FindNextFile
FindClose
相应的代码如下:
using System;
using System.Linq;
using Microsoft.Windows.Sdk;
var handle = PInvoke.FindFirstFile("*.*", out var findData);
if (handle.IsInvalid)
return;
上述代码使用了C#9的Top Level Statements的功能。
文中还展示了文件回调的例子。具体看https://github.com/bsonnino/UseWin32
C#/Win32 P/Invoke Source Generator
部分功能需要用到C#9。目前.NET6提供的是C#10,需要在项目中设置:
<LangVersion>9</LangVersion>
既有的Win32 PInvoke项目:https://github.com/dotnet/pinvoke
注意不能将AllowUnsafeBlocks 设为false。
NativeMethods.txt
文件中列出所需要的Win32用编口,每行的内容可以是
- 导出的方法的名字,可能带有A、W后缀
- 一个命名空间,导出其中所有名字
- 模块名后跟
.*
,比如kernel32.*
- 结构、枚举、常量、接口等的名字
//
开头的行注释,会被忽略掉
上述导出的内容,会在Windows.Win32.PInvoke
下可见。
有一些选项来控制生成的代码。这些选项可以在NativeMethods.json
中指定,例如:
{
"$schema": "https://aka.ms/CsWin32.schema.json",
"emitSingleFile": false
}
许多生成的类型中带有partial修饰符,允许向类型中添加额外的代码。
可以更新Microsoft.Windows.SDK.Win32Metadata
NuGet包来获得更新的元数据。
也可以在工程文件中设置MicrosoftWindowsSdkWin32MetadataBasePath
,指向Windows.Win32.winmd
所在的目录。
小结
cswin32基于win32metadata,后者是通过扫描Win32的用编口头文件生成出来的。生成采用的工具是ClangSharp。 win32metadata也被xlang使用来生成rust的互操作描述文件。
项目地址:
- https://github.com/microsoft/cswin32
- https://github.com/microsoft/win32metadata
- https://github.com/dotnet/ClangSharp
- https://github.com/microsoft/xlang
NuGet包
- Microsoft.Windows.CsWin32
Microsoft.Windows.SDK.BuildTools
,竟然遇到错误 System.Environment Is64BitProcess isn’t available on MSBuildRuntimeType=Core #7329
其他参考
- Using the C#/Win32 code generator to enhance your WinUI 3 app
- Making Win32 APIs More Accessible to More Languages
- C# Win32 API programming using CsWin32 and VS Code
(完)