Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Microsoft not provide for C# a static Win32 class with the most native functions and structures inside like windows.h?

Everybody who used P/Invoke of Windows API knows a long list of declarations of static functions with attributes like

 [DllImport ("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]

The declaration of structures copied from Windows headers like WinNT.h or from web sites like www.pinvoke.net take also a lot of place in our programs.

Why we all have to spend our time for this? Why Microsoft not give us a simple way to include a line like in old unmanaged programs

#include <windows.h>

and we would be have access to a static class Native with all or the most Windows functions and structures inside?

UPDATED based on some answers:

It you will be honest with yourself, which part of your .NET programs are running not under Windows? 5%? 1%? If you use WMI, Process, Registry or ServiceProcess.ServiceBase classes etc. in .NET is your program so “platform independent” and more “compatible” if you not use native API? Has Thread.ApartmentState everywhere sense out of Windows?

Usage of SafeHandle or try {…} finally is of cause required. I would be happy to have a standard definition of Native API in any of these forms.

I know that some structures in windows.h have different versions 32/64 or XP/Vista etc. I think it would be enough to have also different version of Native structures like MIB_IPADDRROW_XP and MIB_IPADDRROW_W2K or IMAGE_NT_HEADERS32 and IMAGE_NT_HEADERS64 (see the same names in windows headers).

One should of cause use managed .NET classes and methods if there are exist. It’s a pity, but the implementation of some the most powerful features of Windows come in managed .NET too late and a lot of there are accessed till now only in unmanaged world. 10 year ago at one of the first Microsoft conference about .NET I asked about my favor Memory Mapped Files. Only .NET 4 has now MemoryMappedFile class implemented (see http://blogs.msdn.com/salvapatuel/archive/2009/06/08/working-with-memory-mapped-files-in-net-4.aspx). The same problems exist permanently if one writes utilities for administrative purpose. For example, opening file with CreateFile and Flag FILE_FLAG_BACKUP_SEMANTICS or RegCreateKeyEx with REG_OPTION_BACKUP_RESTORE or REG_OPTION_CREATE_LINK. Hard Links and Junctions (see http://msdn.microsoft.com/en-us/library/aa365006(v=VS.85).aspx) are next examples. One more example: working with Job Objects instead of Process (see http://msdn.microsoft.com/en-us/library/ms684161(VS.85).aspx and http://www.microsoft.com/msj/0399/jobkernelobj/jobkernelobj.aspx). If you want to start a process and wait not till this process, but also untill all it’s child processes be ended, job is very useful. One can use CreateJobObject and AssignProcessToJobObject and then use TerminateJobObject or WaitHandle like .NET version of (WaitForSingleObject).

Only in .NET 4.0 System.IntPtr und System.UIntPtr classes supports Add and Subtract methods.

I can continue the examples, but I hope you understand what I mean. So I want to write a program in .NET because of a lot of advantages but I can do this not always without usage of native API. Moreover, there are sometimes customer's requirement to the language of software implementation and I choose the required way.

UPDATED 2: Microsoft improved the interoperability with COM in .NET 4.0, but not with C-like Windows API. I see some ways to makes working with P/Invoke easier. What way to do this you see? I suggest three directions which I see:

  1. One makes an assembly with declaration of all (or the most important) not yet fully implemented in .NET Windows API. This assemble can has only (or almost only) metadata of static Native class with static functions and corresponding classes / structures. This assembly can be placed in GAC and everybody could use it. (This way I tested. It works very well.)
  2. One implements a collection of snippets with declaration and samples of using of different native Windows API.
  3. One start an open source project on www.codeplex.com where one create .NET classes and extension methods to some most important native Windows API which are not yet implemented in .NET.

I am sure that exist more ways to make easier for developer the usage of native Windows API. Other suggestions are welcome.

like image 241
Oleg Avatar asked May 08 '10 00:05

Oleg


People also ask

Is C used in Microsoft?

Microsoft WindowsMicrosoft's Windows kernel is developed mostly in C, with some parts in assembly language.

Does Windows come with C?

Unfortunately, there is no in-built compiler. You need to install one.

What C compiler does Microsoft use?

CMake, Clang, mingw, and more Use MSBuild with the Microsoft Visual C++ compiler or a 3rd party toolset like CMake with Clang or mingw to build and debug your code right in the IDE.

Is C available in Visual Studio?

Microsoft Visual C++ (MSVC) refers to the C++, C, and assembly language development tools and libraries available as part of Visual Studio on Windows.


2 Answers

I don't know why MSFT made that decision, but here are a few reasons why I think the decision was the correct one:

  • The Windows SDK header files (windows.h et al) make extensive use of conditional compilation based on things like the target Windows version and architecture to determine what functions get declared and how data structures are laid out. None of this would be possible in any of the .NET languages, as one does not target Windows versions but rather framework versions, with the resulting binaries able to run natively on 32- and 64-bit architectures across many versions and editions of Windows

  • Many Windows API calls and data structures cannot be fully expressed via P/Invoke. One that comes immediately to mind is DeviceIoControl. Another are the many so-called 'variable length' structures, containing arrays with an unknown (at compile time) number of elements in them

  • P/Invoke has evolved over time, particularly in the way handles are exposed (IntPtr in early versions of the framework; SafeHandle classes later); if MSFT maintained a single static class with most or all Win32 API functions, they would also be obligated to maintain compatibility with previous versions of this class, locking themselves in to however P/Invoke was implemented originally

  • Even MSFT themselves do not maintain a single Native class in the framework internals. Now that the .NET Framework 3.5 source code is available, you can see for yourself how ad-hoc use of P/Invoke is, even within the very framework we are supposed to use in lieu of P/Invoke. For example, System.Net and System.IO have their own separate P/Invoke declarations.

  • The .NET Framework and managed code were designed from the beginning as a new way of building software for Windows. How stupid would it be to provide this new way while at the same time requiring use of the old way for many tasks?

I say this as someone who makes extensive use of P/Invoke for things like IOCTLs and volume-level I/O operations. The more I use P/Invoke, the more I hate it. It's hard to work with, error prone, and slow. Every time I use P/Invoke, it's because I've exhausted all other options. If you find yourself with a problem whose solution requires a lot of direct Windows API calls, you probably:

a) Are missing some feature within the Framework that will do what you want

b) Are taking the wrong approach to solving the problem, particularly if you are used to the native Windows API and still think in those terms

c) Should write your low-level code in C++/CLI, and expose chunky higher-level interfaces for your .NET code to consume

like image 80
anelson Avatar answered Oct 09 '22 08:10

anelson


I'm sure the thought crossed your minds but I think there should be an open source project that did this. Rather than waiting on Microsoft to do this, we can collect all of the knowledge that people who've actually used P/Invoke day in day out so that others don't have to reinvent the wheel.

Keep collecting the API as people use them, need them.

Any volunteers? :)

pinvoke.net doesn't count - it's not readily pluggable to your solution.

like image 34
Jiho Han Avatar answered Oct 09 '22 09:10

Jiho Han