4

I would like to find out from .NET code whether DirectX 10 is supported on the machine, preferably without using managed DirectX or XNA assemblies.

Thank you in advance!

ShdNx
  • 3,172
  • 5
  • 40
  • 47
  • 1
    possible duplicate of [Check which version of DirectX is installed](http://stackoverflow.com/questions/17130764/check-which-version-of-directx-is-installed) – Peter O. Jun 16 '13 at 22:01

3 Answers3

2

It's actually very simple: If you are on Windows Vista / Server 2008 or later, you have "DirectX 10" the API. If you are on Windows Vista / Server 2008 Service Pack 1 or later, you have "DirectX 10.1" the API.

Neither of these answer the more useful question of: does the system have a DirectX 10 compatible video device and driver?

Really the only sure way to detect this is to create the device. If you can (a) find the D3D10.DLL and (b) a call to D3D10CreateDevice succeeds, then you have both the DirectX 10 API and a 10 compatible device.

Similarly, if you can (a) find the D3D10_1.DLL and (b) a call to D3D10CreateDevice1 succeeds, then you have both the DirectX 10.1 API and a 10.0 or 10.1 compatible device.

DirectX 11.0 or later is always present on Windows 7 / Server 2008 R2 or later. Again, if you can (a) find the D3D11.DLL and (b) a call to D3D11CreateDevice succeeds, then you have both the DirectX 11 API and a 11 compatible device of some feature level. The parameters to the create device will determine what feature levels are allowed. This procedure will also work to detect the case that you are on a Windows Vista / Server 2008 Service Pack 2 system with the KB97644 update applied.

Once you have a ID3D11Device you can QueryInterface for ID3D11Device1 to see if the system has DirectX 11.1 (Windows 8 / Server 2012 or Windows 7 / Server 2008 R2 with KB2670838, or ID3D1Device2 to see if the system has DirectX 11.2 (Windows 8.1 / Server 2012 R2)

See Direct3D 11 Deployment for Game Developers

The concept of "What version of DirectX is installed" is antiquated and dates back to the era of Windows 9x/ME. Running the "DirectX End-User Runtime Redist" does some stuff, but it never installs a new version of DirectX. See Not So DirectSetup. The DirectX runtime is purely a function of OS patch level and has been since ~2004. See What's in a version number? as well.

Chuck Walbourn
  • 38,259
  • 2
  • 58
  • 81
1

To check DirectX10, we're actually calling the D3DX10CheckVersion function via platform invoke.

This requires presence of the D3DX10 DLLs in the C:\Windows\System32 or C:\Windows\SysWow64 folders (platform dependent). If these are not present, then you need to install the DirectX10 Runtime on the target PC.

The actual support DirectX version / DirectX SDK version can be determined from the parameters to the P/Invoke call.

Here is the P/Invoke call:

// DX10 Supported Function
// See D3DX10CheckVersion http://msdn.microsoft.com/en-us/library/windows/desktop/bb172639(v=vs.85).aspx
[DllImport("d3dx10_43.dll", EntryPoint = "D3DX10CheckVersion", CallingConvention = CallingConvention.StdCall, SetLastError = false)]
private static extern HResult D3DX10CheckVersion(
        uint D3DSdkVersion,
        uint D3DX10SdkVersion);

public enum HResult : int
{
    S_OK = 0x0000,
    S_FALSE = 0x0001,
    E_NOTIMPL = 0x0002,
    E_INVALIDARG = 0x0003,
    E_FAIL = 0x0004,
};

bool SupportsDirectX10()
{
    // Values taken from d3d10.h to check DirectX version
    const uint D3D10_SDK_VERSION = 29;
    const uint D3DX10_SDK_VERSION = 43;

    // Checks DirectX 10 GPU compatibility with the DirectX10 runtime
    // Assumes D3DX10 DLLs present in C:\Windows\System32 or
    // C:\Windows\SysWow64 folders (platform dependent)
    HResult hResult = D3DX10CheckVersion(D3D10_SDK_VERSION, D3DX10_SDK_VERSION);
    return hResult == HResult.S_OK; 
}
Dr. Andrew Burnett-Thompson
  • 20,980
  • 8
  • 88
  • 178
  • Nice, also seems it works for DirectX 11 with minor changes. – Waldo Alvarez Jan 02 '16 at 05:34
  • Just be advised you will need to check for presence of D3DX10_43.dll on target machine before calling this P/Invoke function. It's usually found in C:\Windows\System or System32 depending on platform version. – Dr. Andrew Burnett-Thompson Jan 02 '16 at 11:19
  • Thanks. I suppose calling this wrapped in try catch would do the trick right? – Waldo Alvarez Jan 04 '16 at 03:54
  • It'll work, but its far easier to just check for presence of D3DX10_43.dll in System or System32. Also note: not having these files does *not* mean that your computer doesn't support DirectX10. D3DX10_43.dll is part of the June 2010 DirectX SDK and must be redistributed to end-user PCs. Take a look at this link (http://support.scichart.com/index.php?/Knowledgebase/Article/View/17262/0/creating-and-deploying-applications-with-the-direct3d10rendersurface) to see how we solve this problem. – Dr. Andrew Burnett-Thompson Jan 04 '16 at 10:30
  • Another way of solving it without D3DX10_43.dll is to try to create a device using platform invoke and wrap in Try/Catch https://msdn.microsoft.com/en-us/library/windows/desktop/ff476082%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396 – Dr. Andrew Burnett-Thompson Jan 04 '16 at 10:31
  • What I am trying to do is to notify user during installation if DirectX 11 (I disassembled the dll to check for values) is usable beforehand so he/she knows if the game is gonna work or not. I want it to be robust. I mean code won't crash even if Directx is completely inexistent. – Waldo Alvarez Jan 04 '16 at 10:57
-1

You can have a look at the DirectX version installed on your machine using this key hive

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\DirectX

Here's a sample

[assembly: RegistryPermissionAttribute(SecurityAction.RequestMinimum,All = "HKEY_LOCAL_MACHINE")]
class Test
{
    public int DxLevel
    {
        get
        {
            using(RegistryKey key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\DirectX"))
            {
                string versionStr = key.GetValue("Version") as string;

                if (!string.IsNullOrEmpty(versionStr))
                {
                    var versionComponents = versionStr.Split('.');
                    if (versionComponents.Length > 1)
                    {
                        int directXLevel;
                        if (int.TryParse(versionComponents[1], out directXLevel))
                            return directXLevel;
                    }
                }
                return -1;
            } 
                     }
    }
}

Now if you want to know whether your video card supports DirectX, this is going to require XNA or DirectX interop.

Just a note, I couldn't test that code on my machine right now but that should get you started :)

Florian Doyon
  • 4,146
  • 1
  • 27
  • 37