Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c#如何使用新版本的Helper API_C#_C++_.net_Windows_Dllimport - Fatal编程技术网

c#如何使用新版本的Helper API

c#如何使用新版本的Helper API,c#,c++,.net,windows,dllimport,C#,C++,.net,Windows,Dllimport,由于Windows 10已发布,因此现在不可靠(此函数报告Windows 8 for Windows 10),因此我尝试在我的C#应用程序中使用新版本的Helper API函数。是的 如果这只是我的DLL导入的一个问题,我很抱歉,但是我尝试引入这些新方法来正确检测操作系统 [DllImport("kernel32.dll", CharSet = CharSet.Auto)] public static extern bool IsWindows7OrGreater(); [DllImport(

由于Windows 10已发布,因此现在不可靠(此函数报告Windows 8 for Windows 10),因此我尝试在我的C#应用程序中使用新版本的Helper API函数。是的

如果这只是我的DLL导入的一个问题,我很抱歉,但是我尝试引入这些新方法来正确检测操作系统

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern bool IsWindows7OrGreater();

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern bool IsWindows8OrGreater();

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern bool IsWindows8Point1OrGreater();

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern bool IsWindows10OrGreater();
无论何时调用这些方法,我都会得到:

异常为:EntryPointNotFoundException-在DLL“kernel32.DLL”中找不到名为“IsWindows7OrCreater”的入口点

我做错什么了吗?有人有什么想法吗?谢谢你的帮助


编辑:请查看已接受的答案,并查看将这些方法移植到C#上的良好开端。

不幸的是,这有点复杂。“函数”实际上是
VersionHelpers.h
中定义的宏

如果你想一想,那是唯一的办法——他们不能追溯到旧的Windows版本中添加功能


您必须将宏移植到C#。

VersionHelpers函数不会在任何dll中导出,而是在VersionHelpers.h文件中定义, 为了利用C代码中的功能,您可以从头文件复制该功能

导入这两个功能:

[DllImport("kernel32.dll")]
static extern ulong VerSetConditionMask(ulong dwlConditionMask, uint dwTypeBitMask, byte dwConditionMask);

[DllImport("kernel32.dll")]
static extern bool VerifyVersionInfo([In] ref OsVersionInfoEx lpVersionInfo, uint dwTypeMask, ulong dwlConditionMask);
定义以下结构:

[StructLayout(LayoutKind.Sequential)]
struct OsVersionInfoEx
{
    public uint OSVersionInfoSize;
    public uint MajorVersion;
    public uint MinorVersion;
    public uint BuildNumber;
    public uint PlatformId;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
    public string CSDVersion;
    public ushort ServicePackMajor;
    public ushort ServicePackMinor;
    public ushort SuiteMask;
    public byte ProductType;
    public byte Reserved;
}
然后使用以下功能:

static bool IsWindowsVersionOrGreater(uint majorVersion, uint minorVersion, ushort servicePackMajor)
{
    OsVersionInfoEx osvi = new OsVersionInfoEx();
    osvi.OSVersionInfoSize = (uint)Marshal.SizeOf(osvi);
    osvi.MajorVersion = majorVersion;
    osvi.MinorVersion = minorVersion;
    osvi.ServicePackMajor = servicePackMajor;
    // These constants initialized with corresponding definitions in
    // winnt.h (part of Windows SDK)
    const uint VER_MINORVERSION = 0x0000001;
    const uint VER_MAJORVERSION = 0x0000002;
    const uint VER_SERVICEPACKMAJOR = 0x0000020;
    const byte VER_GREATER_EQUAL = 3;
    ulong versionOrGreaterMask = VerSetConditionMask(
       VerSetConditionMask(
           VerSetConditionMask(
               0, VER_MAJORVERSION, VER_GREATER_EQUAL),
           VER_MINORVERSION, VER_GREATER_EQUAL),
       VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
    uint versionOrGreaterTypeMask = VER_MAJORVERSION |VER_MINORVERSION | VER_SERVICEPACKMAJOR;
    return VerifyVersionInfo(ref osvi, versionOrGreaterTypeMask, versionOrGreaterMask);

}

您的代码必须有一个包含

  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
    <application>
        <!-- A list of all Windows versions that this application is designed to work with. Windows will automatically select the most compatible environment.--> 
        <!-- Windows 10 -->
        <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
        <!-- Windows 8.1 -->
        <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
        <!-- Windows Vista -->
        <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
        <!-- Windows 7 -->
        <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
        <!-- Windows 8 -->
        <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
        <!-- If your application is designed to work with Windows 7, uncomment the following supportedOS node-->
      <!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>-->

    </application>
  </compatibility>

无需使用互操作/非托管代码或添加目标清单


正如本文和文档中已经提到的,Windows 8.1的行为/可用性发生了变化。(对于.NET<5.0,反映了这一点) 这同样适用于函数。如果您使用.NET 5或Core,您可以再次使用,顺便说一句,我的核心项目同事排除了使用with指令查询WMI的代码,因为它没有为Core编译)

另一种方法是将其他答案中的PInvoke与这些函数的Windows SDK对应项(来自ntdll.dll)一起使用

  • (可以使用a结构,这是非SDK对应项的别名。只需确保在调用之前设置dwOSVersionInfoSize,以便它知道您引用的是哪一个。)
它们与kernel23.dll中的函数使用相同的结构,并且可以以相同的方式使用(也可以使用该函数替代已记录的宏,但只有Unicode版本可用,因此请确保将结构注释为设置为.Unicode,因为C#默认为ANSI)

因此,如果使用以下导入,则已发布的代码应给出可靠的结果:

(如果您不能或不想使用WMI或注册表)


啊,我明白了。这是有道理的。非常感谢您的快速回复。下面是我发现的一个代码项目,它为在上面移植这些代码提供了一个良好的开端:@Krumelur一个例子可能会对这个答案有很大帮助。据报道,VerifyVersionInfo在Windows 10中不受欢迎。Windows 10中是否还有任何未弃用的API可以提供操作系统版本?@FrancisLitterio他使用的是
VerifyVersionInfo
,而不是
VerifyVersionInfo
,但即便如此,他也包括了帮助函数,而且,仅仅因为某些东西被弃用并不意味着它不起作用-它通常意味着微软已经取代了它(即包括这些帮助函数)。这两个都应该仍然可以运行,但是您想使用上面的
IsWindows10OrGreater()
函数。我们能够在没有清单的情况下在Windows 7上运行这些函数,因此我认为如果它可以在7上运行这些函数,那么如果没有清单,它在10上运行时不会也出现任何问题吗?它不应该已经有了相同的
VerifyVersionInfo()
函数,只需要将10的数字作为
ushort wMajorVersion
发送到
isWindowsVersionOrCreater()
就可以了,看看当传递给它时它是否得到了10?很好,运行没有任何障碍或清单文件(至少在Windows 7上)!
using System;
using System.Runtime.InteropServices;

namespace VersionHelper
{
    public static class VersionHelper
    {
        const byte VER_EQUAL = 1;
        const byte VER_GREATER = 2;
        const byte VER_GREATER_EQUAL = 3;
        const byte VER_LESS = 4;
        const byte VER_LESS_EQUAL = 5;
        const byte VER_AND = 6;
        const byte VER_OR = 7;

        const byte VER_CONDITION_MASK = 7;
        const byte VER_NUM_BITS_PER_CONDITION_MASK = 3;

        //
        // RtlVerifyVersionInfo() type mask bits
        //

        const uint VER_MINORVERSION = 0x0000001;
        const uint VER_MAJORVERSION = 0x0000002;
        const uint VER_BUILDNUMBER = 0x0000004;
        const uint VER_PLATFORMID = 0x0000008;
        const uint VER_SERVICEPACKMINOR = 0x0000010;
        const uint VER_SERVICEPACKMAJOR = 0x0000020;
        const uint VER_SUITENAME = 0x0000040;
        const uint VER_PRODUCT_TYPE = 0x0000080;

        // wProductType    
        // Any additional information about the system.This member can be one of the following values.
        const byte VER_NT_DOMAIN_CONTROLLER = 0x0000002;
        const byte VER_NT_SERVER = 0x0000003;
        const byte VER_NT_WORKSTATION = 0x0000001;

        //
        // _WIN32_WINNT version constants
        //
        const ushort _WIN32_WINNT_NT4 = 0x0400;
        const ushort _WIN32_WINNT_WIN2K = 0x0500;
        const ushort _WIN32_WINNT_WINXP = 0x0501;
        const ushort _WIN32_WINNT_WS03 = 0x0502;
        const ushort _WIN32_WINNT_WIN6 = 0x0600;
        const ushort _WIN32_WINNT_VISTA = 0x0600;
        const ushort _WIN32_WINNT_WS08 = 0x0600;
        const ushort _WIN32_WINNT_LONGHORN = 0x0600;
        const ushort _WIN32_WINNT_WIN7 = 0x0601;
        const ushort _WIN32_WINNT_WIN8 = 0x0602;
        const ushort _WIN32_WINNT_WINBLUE = 0x0603;
        const ushort _WIN32_WINNT_WINTHRESHOLD = 0x0A00; /* ABRACADABRA_THRESHOLD*/
        const ushort _WIN32_WINNT_WIN10 = 0x0A00; /* ABRACADABRA_THRESHOLD*/

        const bool FALSE = false;

        static byte LOBYTE(ushort w)
        {
            return ((byte)(w & 0xff));
        }

        static byte HIBYTE(ushort w)
        {
            return ((byte)(w >> 8 & 0xff));
        }


        [DllImport("kernel32.dll")]
        static extern ulong VerSetConditionMask(ulong ConditionMask, uint TypeMask,   byte  Condition );

        [DllImport("kernel32.dll")]
        static extern bool VerifyVersionInfoW(ref OSVERSIONINFOEXW lpVersionInformation, uint dwTypeMask, ulong dwlConditionMask);


        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        struct OSVERSIONINFOEXW
        {
            public int dwOSVersionInfoSize;
            public int dwMajorVersion;
            public int dwMinorVersion;
            public int dwBuildNumber;
            public int dwPlatformId;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
            public string szCSDVersion;
            public UInt16 wServicePackMajor;
            public UInt16 wServicePackMinor;
            public UInt16 wSuiteMask;
            public byte wProductType;
            public byte wReserved;
        }


        public static bool
        IsWindowsVersionOrGreater(ushort wMajorVersion, ushort wMinorVersion, ushort wServicePackMajor)
        {
            var osvi = new OSVERSIONINFOEXW
            {
                dwOSVersionInfoSize = Marshal.SizeOf(typeof(OSVERSIONINFOEXW))
            };

            var dwlConditionMask = VerSetConditionMask(
                VerSetConditionMask(
                VerSetConditionMask(
                    0, VER_MAJORVERSION, VER_GREATER_EQUAL),
                       VER_MINORVERSION, VER_GREATER_EQUAL),
                       VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);

            osvi.dwMajorVersion = wMajorVersion;
            osvi.dwMinorVersion = wMinorVersion;
            osvi.wServicePackMajor = wServicePackMajor;

            return VerifyVersionInfoW(ref osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE;
        }

        public static bool
        IsWindowsXPOrGreater()
        {
            return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 0);
        }

        public static bool
        IsWindowsXPSP1OrGreater()
        {
            return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 1);
        }

        public static bool
        IsWindowsXPSP2OrGreater()
        {
            return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 2);
        }

        public static bool
        IsWindowsXPSP3OrGreater()
        {
            return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 3);
        }

        public static bool
        IsWindowsVistaOrGreater()
        {
            return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 0);
        }

        public static bool
        IsWindowsVistaSP1OrGreater()
        {
            return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 1);
        }

        public static bool
        IsWindowsVistaSP2OrGreater()
        {
            return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 2);
        }

        public static bool
        IsWindows7OrGreater()
        {
            return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), LOBYTE(_WIN32_WINNT_WIN7), 0);
        }

        public static bool
        IsWindows7SP1OrGreater()
        {
            return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), LOBYTE(_WIN32_WINNT_WIN7), 1);
        }

        public static bool
        IsWindows8OrGreater()
        {
            return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN8), LOBYTE(_WIN32_WINNT_WIN8), 0);
        }

        public static bool
        IsWindows8Point1OrGreater()
        {
            return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINBLUE), LOBYTE(_WIN32_WINNT_WINBLUE), 0);
        }

        public static bool
        IsWindowsThresholdOrGreater()
        {
            return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINTHRESHOLD), LOBYTE(_WIN32_WINNT_WINTHRESHOLD), 0);
        }

        public static bool
        IsWindows10OrGreater()
        {
            return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINTHRESHOLD), LOBYTE(_WIN32_WINNT_WINTHRESHOLD), 0);
        }

        public static bool
        IsWindowsServer()
        {
            var osvi = new OSVERSIONINFOEXW
            {
                dwOSVersionInfoSize = Marshal.SizeOf(typeof(OSVERSIONINFOEXW)),
                wProductType = VER_NT_WORKSTATION
            };

            var dwlConditionMask = VerSetConditionMask(0, VER_PRODUCT_TYPE, VER_EQUAL);

            return !VerifyVersionInfoW( ref osvi, VER_PRODUCT_TYPE, dwlConditionMask);
        }
    }
}
            [DllImport("kernel32.dll")]
            private static extern ulong VerSetConditionMask(ulong dwlConditionMask, uint dwTypeBitMask, byte dwConditionMask);

            [DllImport("ntdll.dll")]
            private static extern uint RtlGetVersion(ref OSVERSIONINFOW lpVersionInformation);

            [DllImport("ntdll.dll")]
            private static extern uint RtlGetVersion(ref OSVERSIONINFOEXW lpVersionInformation);

            [DllImport("ntdll.dll")]
            private static extern bool RtlVerifyVersionInfo([In] ref OSVERSIONINFOEXW lpVersionInformation, uint dwTypeMask, ulong dwlConditionMask);