首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >检查安装了哪个版本的DirectX

检查安装了哪个版本的DirectX
EN

Stack Overflow用户
提问于 2013-06-16 06:24:34
回答 2查看 5.8K关注 0票数 4

根据标题,如何检查用户安装了哪个版本的DirectX?仅检查FeatureLevel是不够的,因为我的应用程序可以在10.0功能级别上运行,但需要安装DirectX 11.1。

为什么这不是一个重复:

  • How to code to get direct X version on my machine in C#?
    • 这个问题的第一个答案是“如果Windows7,DirectX = 11,如果Windows,DirectX = 10”。这是错误的,因为Vista同时支持DirectX 10和11,Windows 7支持DirectX 11和11.1。
    • 第二个答案引用一个仅适用于DirectX 9和更低级别的注册表项。即使在安装了DirectX 11.1的Windows7系统上,此注册表项也不会指示安装的版本大于9.0c

我需要一个适用于DirectX 10安装和向上的答案。这意味着确定它们的版本是10、10.1、11还是11.1。

EN

回答 2

Stack Overflow用户

发布于 2019-02-22 22:06:09

另一种可能是直接使用IDxDiagProvider COM对象并浏览它生成的IDxDiagContainer层次结构--这是dxdiag.exe内部所做的。它也需要一段时间来完成,所以它也不是一个快速的解决方案,但至少您不需要创建或解析一个原始文件。

显然,此功能以前包装在Microsoft.DirectX.Diagnostics中的托管Microsoft.DirectX.Diagnostics程序集中,因为它们具有与COM对象提供的非常相似的接口,但是这些程序集已经过时,不能在.NET核心中工作,所以让我们自己包装这些COM对象吧!有关方法的文档,仍然可以参考上面链接的文档。

首先,您需要IDxDiagProvider接口和DxDiagProvider coclass以及传递给提供程序的DXDIAG_INIT_PARAMS

代码语言:javascript
运行
复制
[ComImport]
[Guid("A65B8071-3BFE-4213-9A5B-491DA4461CA7")]
public class DxDiagProvider { }

[Guid("9C6B4CB0-23F8-49CC-A3ED-45A55000A6D2")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IDxDiagProvider
{
    void Initialize(ref DXDIAG_INIT_PARAMS pParams);
    void GetRootContainer(out IDxDiagContainer ppInstance);
}

[StructLayout(LayoutKind.Sequential)]
public struct DXDIAG_INIT_PARAMS
{
    public int dwSize;
    public uint dwDxDiagHeaderVersion;
    public bool bAllowWHQLChecks;
    public IntPtr pReserved;
};

还需要包装IDxDiagContainer类:

代码语言:javascript
运行
复制
[Guid("7D0F462F-4064-4862-BC7F-933E5058C10F")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IDxDiagContainer
{
    void EnumChildContainerNames(uint dwIndex, string pwszContainer, uint cchContainer);
    void EnumPropNames(uint dwIndex, string pwszPropName, uint cchPropName);
    void GetChildContainer(string pwszContainer, out IDxDiagContainer ppInstance);
    void GetNumberOfChildContainers(out uint pdwCount);
    void GetNumberOfProps(out uint pdwCount);
    void GetProp(string pwszPropName, out object pvarProp);
}

现在,我们可以使用包装器,并且必须执行以下操作来检索版本信息:

  • 通过创建coclass并将其转换到接口,实例化提供程序。
  • 使用初始化参数初始化提供程序。
  • 把根容器拿来。
  • 获取DxDiag_SystemInfo子容器。
  • 读取DirectX版本属性。

正确清理COM资源的代码如下所示:

代码语言:javascript
运行
复制
IDxDiagProvider provider = null;
IDxDiagContainer rootContainer = null;
IDxDiagContainer systemInfoContainer = null;
try
{
    // Instantiate and initialize the provider.
    provider = (IDxDiagProvider)new DxDiagProvider();
    DXDIAG_INIT_PARAMS initParams = new DXDIAG_INIT_PARAMS
    {
        dwSize = Marshal.SizeOf<DXDIAG_INIT_PARAMS>(),
        dwDxDiagHeaderVersion = 111
    };
    provider.Initialize(ref initParams);

    // Get the Root\SystemInfo container.
    provider.GetRootContainer(out rootContainer);
    rootContainer.GetChildContainer("DxDiag_SystemInfo", out systemInfoContainer);

    // Read the DirectX version info.
    int versionMajor = GetProperty<int>(container, "dwDirectXVersionMajor");
    int versionMinor = GetProperty<int>(container, "dwDirectXVersionMinor");
    string versionLetter = GetProperty<string>(container, "szDirectXVersionLetter");
    bool isDebug = GetProperty<bool>(container, "bDebug");
}
finally
{
    if (provider != null)
        Marshal.ReleaseComObject(provider);
    if (rootContainer != null)
        Marshal.ReleaseComObject(rootContainer);
    if (systemInfoContainer != null)
        Marshal.ReleaseComObject(systemInfoContainer);
}

如您所见,我创建了一个小的实用程序GetProperty方法,用于从COM接口返回的VARIANT值中检索一个正确类型的属性:

代码语言:javascript
运行
复制
private static T GetProperty<T>(IDxDiagContainer container, string propName)
{
    container.GetProp(propName, out object variant);
    return (T)Convert.ChangeType(variant, typeof(T));
}
票数 4
EN

Stack Overflow用户

发布于 2013-06-16 09:28:36

编辑:删除注册表检查方法,因为它只适用于Dx <=9 (thx @Telanor)

这种方法非常,非常慢,但只有我想出的一种方法是100%准确的。

代码语言:javascript
运行
复制
private static int checkdxversion_dxdiag()
{
    Process.Start("dxdiag", "/x dxv.xml");
    while (!File.Exists("dxv.xml"))
        Thread.Sleep(1000);
    XmlDocument doc = new XmlDocument();
    doc.Load("dxv.xml");
    XmlNode dxd = doc.SelectSingleNode("//DxDiag");
    XmlNode dxv = dxd.SelectSingleNode("//DirectXVersion");

    return Convert.ToInt32(dxv.InnerText.Split(' ')[1]);
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17130764

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档