【问题标题】:How to programatically obtain the emulator's model being used如何以编程方式获取正在使用的仿真器模型
【发布时间】:2013-04-10 07:19:14
【问题描述】:

我正在开发一个应用程序来处理不同分辨率的许多设备和模拟器,所以我有代码可以知道是真实设备还是模拟器,但我想知道模拟器(型号、类型)是什么正在执行以以正确的分辨率显示应用程序。

实际上,我使用的是代码方法 GetOemInfo(),它返回一个值为“Emulator”或设备型号的字符串,我只知道它是一个模拟器,而不是什么。

private static string GetOemInfo()
    {
        string oemInfo = new string(' ', 50);
        int result = SystemParametersInfo(SPI_GETOEMINFO, 50, oemInfo, 0);
        oemInfo = oemInfo.Substring(0, oemInfo.IndexOf('\0'));
        return oemInfo;
    }

【问题讨论】:

    标签: c# visual-studio-2008 mobile windows-mobile compact-framework


    【解决方案1】:

    如果屏幕尺寸不是您所追求的,这是我用来获取设备信息的一种方法。它从注册表中读取一些数据,并从...读取一些数据。好吧,你会看到的。

    private static string getName() {
      string name = null;
      using (RegistryKey key = Registry.LocalMachine.OpenSubKey("Ident", true)) {
        var name = key.GetValue("Name", [Unnamed]) as string;
      }
      if (String.IsNullOrEmpty(name)) {
        name = getDeviceID();
      }
      return name;
    }
    

    所以,现在你需要我的getDeviceID()。啊。好的。

    private const string COREDLL = "coredll.dll";
    [DllImport(COREDLL)]
    private static extern bool KernelIoControl(Int32 IoControlCode, IntPtr InputBuffer, Int32 InputBufferSize, byte[] OutputBuffer, Int32 OutputBufferSize, ref Int32 BytesReturned);
    
    private static string getDeviceID() {
      // Reference: http://msdn.microsoft.com/en-us/library/aa446562.aspx
      byte[] data = new byte[256];
      Int32 OutputBufferSize = data.Length;
      Int32 BytesReturned = 0;
      // Call KernelIoControl passing the previously defined IOCTL_HAL_GET_DEVICEID parameter
      // We don’t need to pass any input buffers to this call
      // so InputBuffer and InputBufferSize are set to their null values
      bool retVal = KernelIoControl(IOCTL_HAL_GET_DEVICEID, IntPtr.Zero, 0, data, OutputBufferSize, ref BytesReturned);
      // If the request failed, exit the method now
      if (retVal) {
        // Examine the OutputBuffer byte array to find the start of the 
        // Preset ID and Platform ID, as well as the size of the PlatformID. 
        // PresetIDOffset – The number of bytes the preset ID is offset from the beginning of the structure
        // PlatformIDOffset - The number of bytes the platform ID is offset from the beginning of the structure
        // PlatformIDSize - The number of bytes used to store the platform ID
        // Use BitConverter.ToInt32() to convert from byte[] to int
        Int32 PresetIDOffset = BitConverter.ToInt32(data, 4);
        Int32 PlatformIDOffset = BitConverter.ToInt32(data, 0xc);
        Int32 PlatformIDSize = BitConverter.ToInt32(data, 0x10);
    
        // Convert the Preset ID segments into a string so they can be 
        // displayed easily.
        StringBuilder sb = new StringBuilder();
        sb.Append(String.Format("{0:X8}-{1:X4}-{2:X4}-{3:X4}-",
             BitConverter.ToInt32(data, PresetIDOffset),
             BitConverter.ToInt16(data, PresetIDOffset + 4),
             BitConverter.ToInt16(data, PresetIDOffset + 6),
             BitConverter.ToInt16(data, PresetIDOffset + 8)));
    
        // Break the Platform ID down into 2-digit hexadecimal numbers
        // and append them to the Preset ID. This will result in a 
        // string-formatted Device ID
        for (int i = PlatformIDOffset; i < PlatformIDOffset + PlatformIDSize; i++) {
          sb.Append(String.Format("{0:X2}", data[i]));
        }
        // return the Device ID string
        return sb.ToString();
      }
      return null;
    }
    

    【讨论】:

      【解决方案2】:

      有几种方法可以获得屏幕尺寸,如果你只需要这样的话。

      最完整的方法是使用SystemMetrics,必须从“coredll.dll”中P/Invoked。

      [DllImport("coredll.dll")]
      public static extern int GetSystemMetrics(SYSTEM_METRICS nIndex);
      

      接下来,创建一个枚举类型,如下所示:

      public enum SYSTEM_METRICS : int
      {
        SM_CXSCREEN = 0,
        SM_CYSCREEN = 1,
        SM_CXVSCROLL = 2,
        SM_CYHSCROLL = 3,
        SM_CYCAPTION = 4,
        SM_CXBORDER = 5,
        SM_CYBORDER = 6,
        SM_CXDLGFRAME = 7,
        SM_CYDLGFRAME = 8,
        SM_CXICON = 11,
        SM_CYICON = 12,
        SM_CYMENU = 15,
        SM_CXFULLSCREEN = 16,
        SM_CYFULLSCREEN = 17,
        SM_MOUSEPRESENT = 19,
        SM_CYVSCROLL = 20,
        SM_CXHSCROLL = 21,
        SM_DEBUG = 22,
        SM_CXDOUBLECLK = 36,
        SM_CYDOUBLECLK = 37,
        SM_CXICONSPACING = 38,
        SM_CYICONSPACING = 39,
        SM_CXEDGE = 45,
        SM_CYEDGE = 46,
        SM_CXSMICON = 49,
        SM_CYSMICON = 50,
        SM_XVIRTUALSCREEN = 76,
        SM_YVIRTUALSCREEN = 77,
        SM_CXVIRTUALSCREEN = 78,
        SM_CYVIRTUALSCREEN = 79,
        SM_CMONITORS = 80,
        SM_SAMEDISPLAYFORMAT = 81,
        SM_CXFIXEDFRAME = 7,
        SM_CYFIXEDFRAME = 8
      }
      

      有了这个框架,你可以简单的得到宽度,例如,如下:

      int screenWidth = GetSystemMetrics(SYSTEM_METRICS.SM_CXSCREEN);
      Console.WriteLine(String.Format("Screen X-res is {0}", screenWidth));
      

      如果您想偷懒,简单的解决方案是在项目加载完毕后读取主窗体的宽度和高度。

      当然,如果你只是在调整表单之前读取宽度和高度,屏幕上显然会有一些闪烁。

      【讨论】:

      • 感谢@jp2code,它有效,这就是我需要的原因,不是因为懒惰:) 而是因为解决方案的简单性,谢谢!
      【解决方案3】:

      模拟器没有任何“OEM 信息”来提供您所追求的东西。您必须通过检查操作系统版本、屏幕分辨率甚至可能某些 API 的可用性来推断它(如果您正在考虑区分 Pro 和 Standard 目标)。

      【讨论】:

      • 感谢@ctacke 的回答,你知道我可以用什么来检查屏幕分辨率或类似的东西吗?
      猜你喜欢
      • 2014-05-26
      • 2019-10-19
      • 1970-01-01
      • 1970-01-01
      • 2010-12-22
      • 2016-06-26
      • 1970-01-01
      • 2011-03-26
      • 2010-10-10
      相关资源
      最近更新 更多