为什么 .net 中不包含窗口常量?



每次我看到代码调用kernel32.dll或User32.dll时,即使在MSDN上,代码片段也总是要求开发人员将任何必需的常量(例如WM_SETREDRAW=11)硬编码到例程中。既然这些常数永远不会根据定义而改变,而且总是有一个标准定义,为什么.net不在某个地方提供它们呢?我觉得我们最终都会根据需要创建自己的常量库和标准的Windows dll调用。这种重复工作似乎是浪费,而且容易出错。

也许我看得不够仔细,他们都在那里的某个地方,如果是的话,有人能提供他们的位置吗?

我认为只有.Net团队才能提供实际答案,我们只能做出假设。

原因可能有很多。以下是一些猜测:

  • Win32 API错误太多。许多Win32方法要求开发人员操作不安全的句柄(通常表示为IntPtr对象),这不是.Net的操作方式(例如,应该使用FileStream而不是CreateFile/ReadFile/WriteFile/CloseHandle
  • 在mscorlib中添加整个Win32 API是没有意义的,只有0.1%的开发人员实际使用它
  • Microsoft更喜欢开发人员编写托管代码
  • .Net框架被设计为与平台无关。这就是为什么您会找到例如Environment.NewLineA string containing "rn" for non-Unix platforms, or a string containing "n" for Unix platforms.)。因此,添加整个Win32 API毫无意义

Microsoft在Microsoft.Win32命名空间中添加了一些特定于Windows的类,但它非常有限,而且这些功能是必不可少的(注册表操作、文件对话框…)

关于pinvoke.net,我不会太依赖它。我经常看到写得不好的方法声明会在x64系统上崩溃(int而不是IntPtr,结构布局问题…)。另一个例子是:WriteFile方法声明不一致。SafeHandleIntPtr。。。等等

原因不止一个,还有很多。我可以想到以下任何一个因素在决定不包括它们的过程中发挥了作用:

  • 即使是处理框架程序集的团队也没有共享一组共同的pinvoke声明,每个团队都编写了自己的声明
  • 微软只维护winapi的单一来源,即Windows SDK
  • SDK的维护者是一个不同的小组,与任何在.NET上工作的小组都没有密切的关系
  • 不仅仅有一个winapi,它在很大程度上依赖于目标Windows版本,这是您在构建C/C++程序时指定的。这严重违背了.NET的思想,它与版本无关
  • winapi是巨大的,没有人会对仅仅部分版本感到满意
  • winapi函数的pinvoke声明通常从其原始形式重写,以使使用更加简单。特别是在使用不透明指针的函数的情况下,SendMessage()是典型的例子
  • .NET旨在确保您不必依赖winapi。无论如何,您可以使用自己的pinvoke声明来填补缺失的部分,但这将在任何可以运行.NET程序的Windows版本上运行的保证已经丢失。Windows 98和2000仍然是2.0的官方支持

您可以使用Pinvoke Interop Assistant工具。它提供的声明是从Windows SDK标头自动生成的。

.NET被设计成一个完整的生态系统。进入Windows API是一种破解,而不包括常量是微软阻止它的方法。

最新更新