How to check whether DirectX is available? - c#

Currently I develop a projekt in C#. In this project I use the DirectX API. Now I want to implement a function to check whether DirectX is available or not?
Do you have an idea how to do this?
Thank you for your help!

Do you need to detect if there's DirectX compatible GPU in the system, so that Direct3D9 device can be created, which is not the case with some virtual operating systems etc? That one can be tested simply by creating a device instance and catching the exception it possibly throws.
DirectX install existence itself can be checked by looking into Windows\System32 folder. For example, check d3d9d.dll, and D3DX9_43.dll.

Another way to get the DirectX - Version:
void CheckDirectXMajorVersion()
{
int directxMajorVersion = 0;
var OSVersion = Environment.OSVersion;
// if Windows Vista or later
if (OSVersion.Version.Major >= 6)
{
// if Windows 7 or later
if (OSVersion.Version.Major > 6 || OSVersion.Version.Minor >= 1)
{
directxMajorVersion = 11;
}
// if Windows Vista
else
{
directxMajorVersion = 10;
}
}
// if Windows XP or earlier.
else
{
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))
{
directxMajorVersion = directXLevel;
}
}
}
}
}
Console.WriteLine("DirectX Version: " + directxMajorVersion.ToString());
Console.ReadKey();
}

Related

How to get Windows 10 version (e.g. 1809, 1903, 1909, ...) in a UWP app (C# or WinJS)?

I read a lot of stackoverflow post, but there was no solution for my problem.
I want to get the version number of the running Windows 10 installation (e.g. 1809 or 1909) in C# or WinJS
I develop an UWP app with Cordova (Javascript) and I have also a Cordova plugin (winmd) in C# which I can use, but there is no api to get this 4 digit version number.
I have a WinJS/Javascript code which was working fine till version 1903:
var ApiInformation = Windows.Foundation.Metadata.ApiInformation;
if (ApiInformation.isApiContractPresent("Windows.Foundation.UniversalApiContract", 9)) {
return 9999; // TODO: fix this build number, when it is released
} else if (ApiInformation.isApiContractPresent("Windows.Foundation.UniversalApiContract", 8)) {
return 1903;
} else if (ApiInformation.isApiContractPresent("Windows.Foundation.UniversalApiContract", 7)) {
return 1809;
} else if (ApiInformation.isApiContractPresent("Windows.Foundation.UniversalApiContract", 6)) {
return 1803;
} else if (ApiInformation.isApiContractPresent("Windows.Foundation.UniversalApiContract", 5)) {
return 1709
} else if (ApiInformation.isApiContractPresent("Windows.Foundation.UniversalApiContract", 4)) {
return 1703;
} else if (ApiInformation.isApiContractPresent("Windows.Foundation.UniversalApiContract", 3)) {
return 1607;
} else if (ApiInformation.isApiContractPresent("Windows.Foundation.UniversalApiContract", 2)) {
return 1511;
} else if (ApiInformation.isApiContractPresent("Windows.Foundation.UniversalApiContract", 1)) {
return 1507;
} else {
return 0;
}
But because Windows 10 1909 is only a bugfix version with no own SDK, there is also no new UniversalApiContract version. So on a Windows 1909 installation the check for UniversalApiContract "9" returns "false" and so it returns "1903" instead "1909".
Are there some developers out there, who find out something in version 1909, which is new or unique to 1909, so we can check for this and say that this is version 1909?
Important: I am developing an UWP app and Windows has a sandbox concept for UWP apps, so there are some limitations, e.g. UWP apps cannot access the registry or the whole filesystem.
[UPDATE]
Thanks Peter! It works now.
I use it in UWP Cordova WinJS/Javascript with this code:
var v = Windows.System.Profile.AnalyticsInfo.versionInfo.deviceFamilyVersion;
var major = (v & 0xFFFF000000000000) >> 48;
var minor = (v & 0x0000FFFF00000000) >> 32;
var build = (v & 0x00000000FFFF0000) >> 16;
var release = v & 0x000000000000FFFF;
if (build == 18363)
return 1909;
if (build == 18362)
return 1903;
I had to use Windows.System.Profile.AnalyticsInfo.versionInfo.deviceFamilyVersion, because Windows.System.Profile.AnalyticsVersionInfo.deviceFamilyVersion was "undefined" with the hint "Permission denied"? But the code above works.
You can use AnalyticsInfo.VersionInfo.DeviceFamilyVersion to get the version number.
The property is a string which contains some digits. Parse the string into a 32-bit number, and then each byte of that 32-bit number forms part of a standard A.B.C.D version.
It looks like most of the information is available from Environment.OSVersion, except for the release number. Adapting technique from the other answers and combining, you can do this:
using System;
using Windows.System.Profile;
public static Version GetWindowsVersion()
{
var v = Environment.OSVersion.Version;
var release = (int) ulong.Parse(AnalyticsInfo.VersionInfo.DeviceFamilyVersion) & 0xffff;
return new Version(v.Major, v.Minor, v.Build, release);
}

How to create fast duplex scanning with WIA C#?

i am new to WIA. And i have been asked to make scaning service scan faster and duplex. My current service scan one page, then put it in pdf and so on untill there is less then 20 pages(this number just a crutch used before me, will be glad if someone explane how to get "if there is any paper in there" variable). I started to dig and found docs on MSDN describing properties and after found this post describing duplex sanning, but with mysterious 5 in set. After I found this and figured out what i need WIA_DPS_DOCUMENT_HANDLING_SELECT to set to 0x205(FEEDER + DUPLEX + AUTO_ADVANCE). So I tried to setup them like this:
private static void SetProperty(Property property, int value)
{
IProperty x = (IProperty)property;
Object val = value;
x.set_Value(ref val);
}
...some code...
foreach (Property prop in device.Properties)
{
//LOGGER.Warn(prop.Name);
//LOGGER.Warn(prop.PropertyID);
switch ((Int32)prop.PropertyID)
{
// Document Handling Select
case 3088:
SetProperty(prop, 517);
break;
// Pages
case 3096:
SetProperty(prop, 1);
break;
}
}
And it did't worked for me... It just stuck on setting... Can Somebody explain how to setup AUTO_ADVANCE and DUPLEX props? Or maybe "make scanning faster and duplex" need something more then just AUTO_ADVANCE and DUPLEX and my perception about them is wrong? Or I should considering "ISIS / TWAIN (Windows XP / Vista / 7 / 8 / 8.1 / 10)" string in my scan description and use other libraries?
(Window 10, Canon DR-M160||, DR-M160 & DR-M160II Driver for Windows)
and also here is the current fetch function:
public List<ImageFile> FetchImageList()
{
List<ImageFile> imageList = new List<ImageFile>();
//bool hasMorePages = true;
int testcount = 0;
while (testcount >= 0)
{
testcount--;
WIA.Device device = FindDevice(_deviceId);
if (device == null)
{
LOGGER.Warn("Scanner device not found");
return null;
}
// get item
WIA.Item scanItem = device.Items[1] as WIA.Item;
LOGGER.Debug($"ScanItem: {scanItem.ItemID}");
try
{
foreach (Property prop in device.Properties)
{
//LOGGER.Warn(prop.Name);
//LOGGER.Warn(prop.PropertyID);
switch ((Int32)prop.PropertyID)
{
// Document Handling Select
case 3088:
LOGGER.Warn("here");
SetProperty(prop, 517);
LOGGER.Warn("here");
break;
// Pages
case 3096:
SetProperty(prop, 1);
break;
}
}
// scan image
WIA.ICommonDialog wiaCommonDialog = new WIA.CommonDialog();
WIA.ImageFile image = (WIA.ImageFile)scanItem.Transfer(WIA.FormatID.wiaFormatPNG);
imageList.Add(image);
LOGGER.Warn("Front");
//get back side
image = (WIA.ImageFile)scanItem.Transfer(WIA.FormatID.wiaFormatPNG);
imageList.Add(image);
LOGGER.Warn("Back");
}
catch (Exception e)
{
throw (e);
}
}
return imageList;
}
Well... I tried to make duplex scan without AUTO_ADVANCE and got HRESULT: 0x8000FFFF (E_UNEXPECTED) on Transfer call. According to this post(even though that was on Windows 7) I guess there is no way to solve this for me by using WIA, still hope there will other suggestions...
Solved problem
I used saraff.twain and it worked for me:
- git page :https://github.com/saraff-9EB1047A4BEB4cef8506B29BA325BD5A/Saraff.Twain.NET
good library with grate wiki page.(Also have similar library for .net 4.6.1)

How can I detect if Microsoft Edge is installed?

I'm writing a windows form application (c#) and I need to detect whether the user have "Microsoft-Edge" installed in his/her machine or not.
I'm currently using this registry location:
[HKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\CurrentVersion\AppModel\PackageRepository\Packages\Microsoft.MicrosoftEdge_20.10240.16384.0_neutral__8wekyb3d8bbwe]
"Path"="C:\\Windows\\SystemApps\\Microsoft.MicrosoftEdge_8wekyb3d8bbwe"
With a regex after the "Microsoft.MicrosoftEdge". If the "path" exist then I know edge is installed.
Is there a better way to detect edge? would it be better if I detect that I'm running on Windows 10 and by default Win10 come with edge? What is the best way for that?
In case you want to have a small program getting that version number:
static void Main(string[] args)
{
string EdgeVersion = string.Empty;
//open the registry and parse through the keys until you find Microsoft.MicrosoftEdge
RegistryKey reg = Registry.ClassesRoot.OpenSubKey(#"Local Settings\Software\Microsoft\Windows\CurrentVersion\AppModel\PackageRepository\Packages");
if (reg != null)
{
foreach (string subkey in reg.GetSubKeyNames())
{
if (subkey.StartsWith("Microsoft.MicrosoftEdge"))
{
//RegEx: (Microsoft.MicrosoftEdge_)(\d +\.\d +\.\d +\.\d +)(_neutral__8wekyb3d8bbwe])
Match rxEdgeVersion = null;
rxEdgeVersion = Regex.Match(subkey, #"(Microsoft.MicrosoftEdge_)(?<version>\d+\.\d+\.\d+\.\d+)(_neutral__8wekyb3d8bbwe)");
//just after that value, you need to use RegEx to find the version number of the value in the registry
if ( rxEdgeVersion.Success )
EdgeVersion = rxEdgeVersion.Groups["version"].Value;
}
}
}
Console.WriteLine("Edge Version(empty means not found): {0}", EdgeVersion);
Console.ReadLine();
}
Thank you for the registry link for finding the version number.
If you're on the desktop or mobile version of Windows 10 then Edge is pre-installed and can't be uninstalled.
To detect if running on Windows 10 use the System.Environment.OSVersion property or the Version Helper functions. (See also https://msdn.microsoft.com/en-us/library/windows/desktop/ms724832(v=vs.85).aspx)
If you want to detect the default browser you should see How to determine the Windows default browser (at the top of the start menu)
Relevant to 15.11.2016:
The only way that I found working is to use this registry location:
[HKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\CurrentVersion\AppModel\PackageRepository\Packages\Microsoft.MicrosoftEdge_20.10240.16384.0_neutral__8wekyb3d8bbwe]
"Path"="C:\\Windows\\SystemApps\\Microsoft.MicrosoftEdge_8wekyb3d8bbwe"
With a regex after the "Microsoft.MicrosoftEdge".
If the "path" exist then I know edge is installed.
In reference to other answers: my installation of Windows 10 does not have this key: Microsoft.MicrosoftEdge_20.10240.16384.0_neutral__8wekyb3d8bbwe
In:
[HKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\CurrentVersion\AppModel\PackageRepository\Packages\]
Instead, it has the following keys:
Microsoft.MicrosoftEdge_38.14393.0.0_neutral__8wekyb3d8bbwe
Microsoft.MicrosoftEdge_40.15063.674.0_neutral__8wekyb3d8bbwe
The following code could be used to detect if Edge is installed:
class Program
{
static void Main(string[] args)
{
var edgeFound = false;
using (var key = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(#"Local Settings\Software\Microsoft\Windows\CurrentVersion\AppModel\PackageRepository\Packages\"))
{
if (key != null)
{
foreach (var subkey in key.GetSubKeyNames())
{
if (subkey.StartsWith("Microsoft.MicrosoftEdge_"))
{
edgeFound = true;
break;
}
}
}
}
Console.Write(edgeFound);
Console.ReadLine();
}
}

Detecting current device in Windows Universal App

I am trying out released VS 2013 Update 2 and building a sample Universal Application.
I have created a user control and on both MainPages added GridViews (on Windows Phone and Windows 8).
I want to change some things via code when app is running on Windows Phone.
Is there a way to do something like:
if(<deviceType> == "WindowsPhone")
{
}
else
{
}
Normally when building your app, you can use preprocessor directives. When building app for windows phone, VS as default defines WINDOWS_PHONE_APP (take a look at Project Properties -> Build -> Conditional compilation symbols). Therefore anywhere in your code you can put such a statement:
#if WINDOWS_PHONE_APP
// do when this is compiled as Windows Phone App
#else
// not for windows phoen
#endif
More information you can get at MSDN.
I would advise to use this approach, hence in most cases you know exactly when you will use specific code for Phone (ARM) or other platform. Of course if you need you can define more symbols for specific build configurations/platforms.
Remarks: Since W10, where you need to check the platform in Run-Time, then you can use ApiInformation class and check if specific type exists in the api. For example like this:
if (ApiInformation.IsApiContractPresent("Windows.Phone.PhoneContract", 1))
// do code for mobile
else
// do code for other
That's what worked for me in Universal Windows (Windows 10) project
public static Platform DetectPlatform()
{
bool isHardwareButtonsAPIPresent =
ApiInformation.IsTypePresent("Windows.Phone.UI.Input.HardwareButtons");
if (isHardwareButtonsAPIPresent)
{
return Platform.WindowsPhone;
}
else
{
return Platform.Windows;
}
}
If you want an in-code method of determining the current device, you could try this:
public Windows.Foundation.Metadata.Platform DetectPlatform()
{
try
{
//Calls an unsupported API.
Windows.Networking.BackgroundTransfer.BackgroundDownloader.RequestUncontrainedDownloadsAsync(null);
}
catch (NotImplementedException)
{
//The API isn't supported on Windows Phone. Thus, the current platform is Windows Phone.
return Windows.Foundation.Metadata.Platform.WindowsPhone;
}
catch(Exception)
{
//Otherwise, this is Windows (desktop/RT).
return Windows.Foundation.Metadata.Platform.Windows;
}
}
Source: https://gist.github.com/Amrykid/2fd65ae1815a928fe753
OR you can do this
Add this to
App.Xaml.Cs
public static bool IsMobile
{
get
{
var qualifiers = Windows.ApplicationModel.Resources.Core.ResourceContext.GetForCurrentView().QualifierValues;
return (qualifiers.ContainsKey("DeviceFamily") && qualifiers["DeviceFamily"] == "Mobile");
}
}
From GitHub
public static class DeviceTypeHelper
{
public static DeviceFormFactorType GetDeviceFormFactorType()
{
switch (AnalyticsInfo.VersionInfo.DeviceFamily)
{
case "Windows.Mobile":
return DeviceFormFactorType.Phone;
case "Windows.Desktop":
return UIViewSettings.GetForCurrentView().UserInteractionMode == UserInteractionMode.Mouse
? DeviceFormFactorType.Desktop
: DeviceFormFactorType.Tablet;
case "Windows.Universal":
return DeviceFormFactorType.IoT;
case "Windows.Team":
return DeviceFormFactorType.SurfaceHub;
default:
return DeviceFormFactorType.Other;
}
}
}
public enum DeviceFormFactorType
{
Phone,
Desktop,
Tablet,
IoT,
SurfaceHub,
Other
}
https://gist.githubusercontent.com/wagonli/40d8a31bd0d6f0dd7a5d/raw/f6175de5fcad40cc257edc3748c0e349495d17f6/DeviceTypeHelper.cs
It's a workaround
//PC customization
if(ApiInformation.IsTypePresent("Windows.UI.ViewManagement.ApplicationView"))
{
}
//Mobile customization
if(ApiInformation.IsTypePresent("Windows.UI.ViewManagement.StatusBar"))
{
}

How to find the windows dialing rules in .NET

This should be simple, but isn't apparently. Since..Windows 3 or so, there is a control panel called Phone or Phone & Modem. In that control panel is a bunch of information about how a modem would dial up, assuming you have a modem hooked up. For example, do you need to dial 9 to get out, what is the area code, and so forth. How can i access this information programmatically? I am using C# .NET 2010.
You are going to need to use Tapi in Windows or pull the information from the registry. According to Microsoft Tapi 3.0 was not designed to be used from managed code, though the first link seems to have done it.
Some articles to look at:
Tapi3.0 Application Development
VB.Net accessing TAPI Dialing Rules
From Link #2
Take a look at these TAPI functions:
lineGetTranslateCaps
lineTranslateAddress
lineTranslateDialog
lineSetCurrentLocation
lineGetCountry
tapiGetLocationInfo
The info is stored in the Registry at: HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Telephony\Locations
I couldn't find a way to access it through a .Net TAPI wrapper (after a not so long search) so I fired up procmon an found where it was stored in the registry, and here's the code that accesses it (you can adapt it to your specific needs):
RegistryKey locationsKey =
Registry.LocalMachine.OpenSubKey(#"SOFTWARE\Microsoft\Windows\CurrentVersion\Telephony\Locations");
if (locationsKey == null) return;
string[] locations = locationsKey.GetSubKeyNames();
foreach (var location in locations)
{
RegistryKey key = locationsKey.OpenSubKey(location);
if (key == null) continue;
Console.WriteLine("AreaCode {0}",key.GetValue("AreaCode"));
Console.WriteLine("Country {0}",(int) key.GetValue("Country"));
Console.WriteLine("OutsideAccess {0}", key.GetValue("OutsideAccess"));
}
Note :
I recommend to use an official API if there is a .net compatible one.
This code is not guaranteed to work on other OSes than Win 7
If you need to prompt the user to fill in these details you can start the configuration tool using :
Process.Start(#"C:\Windows\System32\rundll32.exe",#"C:\Windows\System32\shell32.dll,Control_RunDLL C:\Windows\System32\telephon.cpl");
Bit more code to get the prefix
class Program
{
static void Main(string[] args)
{
string rootLocation = #"SOFTWARE\Microsoft\Windows\CurrentVersion\Telephony\Locations";
getRegistryValues(rootLocation);
Console.ReadLine();
}
public static void getRegistryValues(string rootLocation)
{
RegistryKey locationsKey =
Registry.LocalMachine.OpenSubKey(rootLocation);
if (locationsKey == null) return;
string[] locations = locationsKey.GetSubKeyNames();
Console.WriteLine(locations.Length.ToString());
foreach (var location in locations)
{
Console.WriteLine(location.ToString());
RegistryKey key = locationsKey.OpenSubKey(location);
if (key == null) continue;
foreach (string keyName in key.GetValueNames())
{
if (keyName.Equals("Prefixes"))
{
string[] Prefixes = ((string[])(key.GetValue(keyName)));
Console.Write("Prefixes ");
foreach (string prefix in Prefixes)
{
Console.Write(prefix);
}
}
else
{
Console.WriteLine(keyName + " {0}", key.GetValue(keyName));
}
}
getRegistryValues(rootLocation+#"\"+location);
}
}

Categories

Resources