So far I have struggled to get MbnInterfaceManager working (see hresult from IMbnInterfaceManager::GetInterfaces when no MBN device exists), so instead I built and debugged an application with no problems from within Visual Studio 2015 that executed this WMI query in C# (see also the Win32_PerfFormattedData_Tcpip_NetworkInterface documentation):
string query = "SELECT * FROM Win32_PerfRawData_Tcpip_NetworkInterface";
ManagementObjectSearcher moSearch = new ManagementObjectSearcher(query);
ManagementObjectCollection moCollection = moSearch.Get();
But then when I deployed the application to Windows 8.1, I receive this error every time the query is executed:
System.Management.ManagementException: Invalid query
at System.Management.ManagementException.ThrowWithExtendedInfo(ManagementStatus errorCode)
at System.Management.ManagementObjectCollection.ManagementObjectEnumerator.MoveNext()
Does anyone have any suggestions on how to resolve this issue? How can I deploy an application so that it is able to use queries like this?
UPDATE:
Please note that I can build and run the above code (as part of a larger WPF application) from within Visual Studio 2015 on either Windows 7 or Windows 8.1, and I can deploy the same application using ClickOnce onto Windows 7 where it runs successfully. For some reason when I deploy this application using ClickOnce onto Windows 8.1, I get that Invalid query message.
I think what I have to do is make sure that the System.Management reference is set to "Copy Local" but I'm not able to test that right now. If anyone has any better ideas please feel free to let me know.
UPDATE:
It is not possible to use System.Management.dll on Windows 8.1 in the same way it is used on Windows 7 or Windows 10.
I've found that to perform operations similar to the ones I mentioned in my question on Windows 8.1 and Windows 8 phone you need to either get a Windows 8.1 developer license or on Windows 10 set your computer to "Developer Mode" so you can use the Windows.Networking.Connectivity namespace:
string connectionProfileInfo = string.Empty;
ConnectionProfile InternetConnectionProfile = NetworkInformation.GetInternetConnectionProfile();
if (InternetConnectionProfile == null)
{
rootPage.NotifyUser("Not connected to Internet\n", NotifyType.StatusMessage);
}
else
{
connectionProfileInfo = GetConnectionProfile(InternetConnectionProfile);
OutputText.Text = connectionProfileInfo;
rootPage.NotifyUser("Success", NotifyType.StatusMessage);
}
// Which calls this function, that allows you to determine how strong the signal is and the associated bandwidth
string GetConnectionProfile(ConnectionProfile connectionProfile)
{
// ...
if (connectionProfile.GetSignalBars().HasValue)
{
connectionProfileInfo += "====================\n";
connectionProfileInfo += "Signal Bars: " + connectionProfile.GetSignalBars() + "\n";
}
// ...
}
Please note that you have to make sure your project is either a Window 8.1 PCL or a Windows 8.1 app to be able to reference the namespace.
For details please see https://code.msdn.microsoft.com/windowsapps/network-information-sample-63aaa201
UPDATE 2:
To be able to get bandwidth on Windows 7, 8.1 and 10, I ended up using this code:
private int GetMaxBandwidth()
{
int maxBandwidth = 0;
NetworkInterface[] networkIntrInterfaces = NetworkInterface.GetAllNetworkInterfaces();
foreach (var networkInterface in networkIntrInterfaces)
{
IPv4InterfaceStatistics interfaceStats = networkInterface.GetIPv4Statistics();
int bytesSentSpeed = (int)(interfaceStats.BytesSent);
int bytesReceivedSpeed = (int)(interfaceStats.BytesReceived);
if (bytesSentSpeed + bytesReceivedSpeed > maxBandwidth)
{
maxBandwidth = bytesSentSpeed + bytesReceivedSpeed;
}
}
}
Related
Windows 11, released yesterday, reports itself as Windows 10.0 just about everywhere - RtlGetVersion says 10.0, and if you ask VerifyVersionInfo if you are 11.0 or greater, it says no.
There seems to be no new GUID to shove into app.manifest to say "hey I support Windows 11" like there was for Windows 7, 8, 8.1, and 10.
Currently I rely on HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProductName to tell me what the current version of Windows is, but on my machine that I've upgraded, it still says "Windows 10 Enterprise", not "Windows 11 Enterprise".
There appears to only be a single place in the registry that contains the text "Windows 11" and that is the BCD section (boot configuration), which can also be renamed so I don't want to touch that.
So far I have only identified a handful of methods to tell if I am running on Windows 11:
Invoke WMI to query Win32_OperatingSystem and check the Name property, which simply says "Windows 11". This is incomplete (it does not include the SKU such as "Enterprise"), and WMI is relatively slow and slightly brittle, so it's not an acceptable solution for my use-case.
Check the build number to see if it is above 21996 (beta builds) or 22000 (first public release). As above, this won't include the SKU, and would require some manual jiggery-pokery in order to build the full string.
Run sysinfo and parse the output. This is quite slow, and possibly brittle (I haven't checked but the output might be localised into different languages).
winver knows, but it's a GUI application so I can't exactly query it programmatically.
Does anyone have any other ideas on how to get the string "Windows 11 Enterprise" (or "Windows 11 Pro", etc. as the case may be) out of my operating system in a performant and complete manner? Where do WMI, sysinfo, and winver get it from?
I need to do this from a .NET library, but P/Invokes / native function calls are acceptable solutions.
Leaving this here so that I can find it later:
It seems that Windows itself (e.g. winver) gets this information from Windows branding - specifically from the resource table in %WinDir%\Branding\Basebrd\en-US\basebrd.dll.mui.
To access this one could use the private APIs in %WinDir%\System32\winbrand.dll. Specifically, the function BrandingFormatString which accepts a wide string (LPW[C]STR) and returns a wide string.
e.g. BrandingFormatString("%WINDOWS_LONG%") returns "Windows 11 Pro" on my home PC.
I do not know the lifecycle semantics of the resulting string, i.e. if/when/how it should be freed.
The following code serves as a functional proof-of-concept (C# 9.0):
using System;
using System.Runtime.InteropServices;
[DllImport("winbrand.dll", CharSet = CharSet.Unicode)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
static extern string BrandingFormatString(string format);
Console.WriteLine(BrandingFormatString("Hello World from %WINDOWS_LONG%!"));
tldr - Using the EditionID and the CurrentBuild from the CurrentVersion in the registry seems to be a reliable way to determine Win10 vs Win11 and the "edition" of the software. EditionID is "Professional" on Windows 10 Pro and Windows 11 Pro, and CurrentBuild >= ~22000 tells you if it is 10 or 11.
The collection of registry values in the HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion reveals what feels like a lack of planning on Microsoft's part. There's ReleaseId, which is a number that changed with each Windows 10 release (e.g., 1903, 1909, 2004,...) until its last change for Windows 10 20H2, where it changed to 2009. At the same time, DisplayVersion was added, and was set to 20H2.
Then Windows 10 21H1 released, and ReleaseId inexplicably stayed at 2009.
The fact that both current Windows 10 and Windows 11 releases can have the same DisplayVersion (e.g., 21H2 when Windows 10 21H2 releases soon) and ProductName (e.g., Windows 10 Pro) is really head-scratching. (Thanks #yaakov for catching my mistake saying it was 21H1.)
The following code has been tested on Windows XP, 7, 10, 11. It works on 32 bit and 64 bit operating systems. It works inside 32 bit and 64 bit applications.
The following strings will be generated:
"Microsoft Windows XP, Build 2600, 32 bit"
"Windows 7 Ultimate, Build 7601, 64 bit"
"Windows 10 Enterprise LTSC 2019, Version 1809, Build 17763, 64 bit"
"Windows 10 Pro, Version 1909, Build 18362, 64 bit"
"Windows 11 Professional, Version 21H2, Build 22000, 64 bit"
Put the code into a static constructor so it executes only once and writes the version into a static variable.
static String ms_OperatingSystem;
static Constructor()
{
try
{
String s_KernelPath = Path.Combine(Environment.SystemDirectory,"Kernel32.dll");
FileVersionInfo k_Kernel = FileVersionInfo.GetVersionInfo(s_KernelPath);
// on 32 bit Windows this will read the 32 bit hive instead
using (RegistryKey i_HKLM = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64))
{
using (RegistryKey i_RegVer = i_HKLM.OpenSubKey(#"Software\Microsoft\Windows NT\CurrentVersion", false))
{
// Kernel32.dll on Windows 11 has Product Version 10.0.22000.120
if (k_Kernel.ProductMajorPart == 10 && k_Kernel.ProductBuildPart >= 22000)
{
ms_OperatingSystem = "Windows 11";
Object o_Edition = i_RegVer.GetValue("EditionID"); // "Professional"
if (o_Edition is String)
ms_OperatingSystem += " " + o_Edition;
}
else
{
// "Microsoft Windows XP"
// "Windows 7 Ultimate"
// "Windows 10 Pro" (same string on Windows 11. Microsoft SUCKS!)
ms_OperatingSystem = (String)i_RegVer.GetValue("ProductName");
}
// See: https://en.wikipedia.org/wiki/Windows_10_version_history
// Windows 10 older releases --> "2009" (invalid if DisplayVersion exists)
Object o_ReleaseID = i_RegVer.GetValue("ReleaseId");
// Windows 10 latest release --> "21H1"
// Windows 11 first release --> "21H2"
Object o_DispVer = i_RegVer.GetValue("DisplayVersion");
// Use ReleaseID ONLY if DisplayVersion does not exist in registry!
if (o_DispVer is String) ms_OperatingSystem += ", Version " + o_DispVer;
else if (o_ReleaseID is String) ms_OperatingSystem += ", Version " + o_ReleaseID;
ms_OperatingSystem += ", Build " + k_Kernel.ProductBuildPart;
if (Environment.Is64BitOperatingSystem) ms_OperatingSystem += ", 64 bit";
else ms_OperatingSystem += ", 32 bit";
}
}
}
catch (Exception Ex)
{
ms_OperatingSystem = Ex.Message;
}
}
I created a remote support tool for desktop admins (see http://www.appslife-rdt.appspot.com) In VB.Dot.Net i used a call to the WMI space Win32_OperatingSystem and got the "Name" value back. This then needs to be split to get the first object which is what you require. i.e.
Dim query2 As New SelectQuery("SELECT * FROM Win32_OperatingSystem")
Dim searcher2 As New ManagementObjectSearcher(objManagementScope2, query2, QueryOptions)
For Each mo As ManagementObject In searcher2.[Get]()
OSname = mo("Name")
Next
Dim array1 As Array = Nothing
array1 = Split(OSname, "|")
OSname = array1(0).ToString
OSname then gives you the "Windows 11 Pro" or "Windows XP Professional" that you require.
I also get the OSVersion with the latest patch update info from registry as follows if needed...
THIS IS FOR CLIENT VERSIONS 10/11 :-
.SetPropertyValue("sSubKeyName", "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Update\TargetingInfo\Installed\Client.OS.rs2.amd64")
.SetPropertyValue("sValueName", "Version")
THIS IS FOR SERVER VERSIONS 2019 :-
.SetPropertyValue("sSubKeyName", "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Update\TargetingInfo\Installed\Server.OS.amd64")
.SetPropertyValue("sValueName", "Version")
Hope this is of help.
I like to check if the running window is windows 8 or windows 8.1.
With the Windows Major Check
6.2 -> Win 8
6.3 -> Win 8.1
That doesn't work, because with the release of Windows 8.1, the behavior of the GetVersion API has changed in the value it will return for the operating system version.
How can I still get the Version correctly?
You could find that info in the registry of Windows. For example, if you have installed Windows 8.1 Pro Edition and execute this lines:
using Microsoft.Win32;
//...
var windowsName= Registry.GetValue(#"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\", "ProductName","");
var version= Registry.GetValue(#"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\", "CurrentVersion", "");
var build= Registry.GetValue(#"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\", "CurrentBuild", "");
You will get Windows 8.1 Pro, 6.3 and 9600 respectively.
Also you could use the WMI to get the Windows name, check the answer in this post:
public static string GetOSFriendlyName()
{
string result = string.Empty;
ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT Caption FROM Win32_OperatingSystem");
foreach (ManagementObject os in searcher.Get())
{
result = os["Caption"].ToString();
break;
}
return result;
}
try this
it concats the major version no followed by the minor version
there are many methods to play with according here Environment Class (System)
string ver = Environment.OSVersion.Version.Major + "." + Environment.OSVersion.Version.Minor;
and the output would be:
6.2
The question in title is not the real problem. I went through many sites and blogs and go to know that Environment.OSVersion gives you the current OS version of the phone using our app. But the problem is, There is no OSVersion under the class Environment. Please refer the screenshot for better understanding.
My question why I am not able to see the OSVersion property under Environment class? Am I missing something?
Universal/WinRT apps only work in wp 8.1, so the OS version can only be 8.1. When they make wp8.2 or wp9, they'll probably add a way to check what OS version is installed...
If you're looking for the firmware version, you can get it with:
Windows.Security.ExchangeActiveSyncProvisioning.EasClientDeviceInformation deviceInfo = new Windows.Security.ExchangeActiveSyncProvisioning.EasClientDeviceInformation();
var firmwareVersion = deviceInfo.SystemFirmwareVersion;
Copied from duped question:
Windows Phone 8.1 Silverlight apps can use the .NET version APIs. There is no supported mechanism to get a version number in Universal 8.1 apps, but you can try using reflection to get the Windows 10 AnalyticsInfo class, which will at least tell you the version number if you are running on Windows 10.
Note: Checking the OS version is almost always the wrong thing to do, unless you're simply displaying it to the user (eg, in an "About" box) or sending it to your back-end analytics server for number crunching. It should not be used to make any run-time decisions, because in general it's a poor proxy for whatever-you're-actually-trying-to-do.
Here is a sample:
var analyticsInfoType = Type.GetType(
"Windows.System.Profile.AnalyticsInfo, Windows, ContentType=WindowsRuntime");
var versionInfoType = Type.GetType(
"Windows.System.Profile.AnalyticsVersionInfo, Windows, ContentType=WindowsRuntime");
if (analyticsInfoType == null || versionInfoType == null)
{
Debug.WriteLine("Apparently you are not on Windows 10");
return;
}
var versionInfoProperty = analyticsInfoType.GetRuntimeProperty("VersionInfo");
object versionInfo = versionInfoProperty.GetValue(null);
var versionProperty = versionInfoType.GetRuntimeProperty("DeviceFamilyVersion");
object familyVersion = versionProperty.GetValue(versionInfo);
long versionBytes;
if (!long.TryParse(familyVersion.ToString(), out versionBytes))
{
Debug.WriteLine("Can't parse version number");
return;
}
Version uapVersion = new Version((ushort)(versionBytes >> 48),
(ushort)(versionBytes >> 32),
(ushort)(versionBytes >> 16),
(ushort)(versionBytes));
Debug.WriteLine("UAP Version is " + uapVersion);
Obviously you can update this to return the version etc. rather than print it to the debug console.
You cannot get the OS Version in Windows 8.1 .Check the following link for the same - https://social.msdn.microsoft.com/Forums/windowsapps/en-US/2b455331-3bad-4d26-b615-a59d0e05d0dd/how-to-get-os-version-on-window-phone?forum=wpdevelop
I found a tricky way to detect if a device is running a Windows Phone 8.1 or Windows Phone 10. I compared 3 different devices, a Nokia Lumia 925 ( wp 8.1 ) a Nokia Lumia 735 ( wp 10 ) and a Nokia Lumia 930 ( wp 10 ). I noticed that on wp8.1 there is no device info id ( it causes a not implemented exception ) but it exists on windows phone 10 on both tested devices. Morover the system firmware version format seems different between wp 8.1 and wp 10 ( the first is xxxx.xxxxx.xxxx.xxxx while the second is xxxxx.xxxxx.xxxxx.xxxxx ). Below my function:
/// <summary>
/// Indicates if this device is running a version of Windows Phone 8.1. It use a dirty trick for detecting the OS major version
/// based on the system firmware version format (8.1 is xxxx.xxxxx.xxxx.xxxx while 10 is xxxxx.xxxxx.xxxxx.xxxxx )
/// moreover, the "deviceInfo.id" is not implemented on Windows Phone 8.1, but it is on Windows Phone 10
/// </summary>
/// <returns></returns>
public static bool liIsWindowsPhone81(bool basedOnDeviceInfoId)
{
EasClientDeviceInformation deviceInfo = new Windows.Security.ExchangeActiveSyncProvisioning.EasClientDeviceInformation();
bool isWin81 = false;
if (basedOnDeviceInfoId)
{
try
{
var deviceInfoId = deviceInfo.Id;
}
catch
{
isWin81 = true;
}
}
else
{
string firmwareVersion = deviceInfo.SystemFirmwareVersion.Trim();
string[] parts = firmwareVersion.Split('.');
if (parts[0].Length == 4 && parts[1].Length == 5 && parts[2].Length == 4 && parts[3].Length == 4)
{
isWin81 = true;
}
}
return isWin81;
}
I haven't had the opportunity to test this on further devices, but so far seems to work. I use it to distinguish the code for the app rating function between Windows Phone 8.1 and Windows Phone 10, that in my specific case are not UWP
Hope this helps
If your app is Silverlight based, you can use System.Environment.OSVersion.Version across Windows Phone 8.0 and 8.1 as well as Windows Mobile 10.
Here is an example of a method we utilize when determining whether to display our own opt-in dialog for geo-tracking or let the Windows Mobile 10 present its own opt-in dialog.
public static bool IsWindowsPhone8x()
{
try
{
Version version = System.Environment.OSVersion.Version;
return version.Major > 8 ? false : true;
}
catch (Exception)
{
return false;
}
}
Simply use this line to get the Application Name and Id, publisher name etc...
string name = Windows.ApplicationModel.Package.Current.DisplayName;
today I am here to ask you how you can "understand" if a given application is emitting sound.
On windows 7 and 8 I use the following code (library CSCore Audio )
[...]
AudioSessionManager2 sessionManager = GetDefaultAudioSessionManager2(DataFlow.Render);
AudioSessionEnumerator sessionEnumerator = sessionManager.GetSessionEnumerator();
AudioSessionControl2 sessionControl;
foreach (AudioSessionControl session in sessionEnumerator)
{
sessionControl = session.QueryInterface<AudioSessionControl2>();
if (sessionControl.Process.MainWindowTitle.StartsWith("my_test"))
{
sessione = sessionControl;
audio = session.QueryInterface<AudioMeterInformation>();
break;
}
}
control.Text = sessione.Process.MainWindowTitle + "[" + audio.PeakValue + "]";
[...]
It works well, but not on Windows XP.
Is there a way "universal" to do it?
If there would be a way to do this in Java would be even better, so work on Linux (which for the moment I do not need, but maybe in the future)
I am sorry, but Windows XP does not querying the audio peak of a process. You can also take a look at the Windows XP Audio Mixer. There is no peak displayed.
I have an application that requires to control mobile broadband API.
I am struggling on correctly installing the api on my devices.
I've been follow the instructions in this document:
http://www.google.be/url?sa=t&rct=j&q=&esrc=s&frm=1&source=web&cd=1&cad=rja&ved=0CC0QFjAA&url=http%3A%2F%2Fdownload.microsoft.com%2Fdownload%2F7%2FE%2F7%2F7E7662CF-CBEA-470B-A97E-CE7CE0D98DC2%2FMB_ManagedCode.docx&ei=kyvmUs7jE4e60QWbooHYDg&usg=AFQjCNG6yaGf4sRhdbWI99fE7tmQX8cmnA&sig2=2Fg-_DRYBIselKR19wTq2Q
and trying to combine the steps with this stackoverflow explanation
C# Read Windows Mobile Broadband connection properties
I have been able to lay a reference from visual studio to mbnapi.tlb in V7.0/lib. and I automatically now have a interop.mbnapi.tlb in my obj/debug folder.
When trying to "check the SIM is inserted and working / activated". => my code crashes on the following line
IMbnInterface[] mobileInterfaces = mbnInfMgrInterface.GetInterfaces() as IMbnInterface[];
When I run it on windows 8, mbnInfMgrInterface == null
I have already tried to install the same SDK on windows 8 as stated in the requirements of the document but the SDK is only meant for windows 7...
I have tried to register the mbnapi in windows 8 by performing
Regtlibv12 Mbnapi.tlb
no luck whatsoever...
what do I need to do to get this to work please?
anyone has some experience in this?
EDIT. on windows 7 (my development machine), I get the message "Device not ready", I think this is normal because I don't have mobile broadband on it, on windows 8 I do, but there the mobile interface manager is null => mbnInfMgrInterface == null.
thank you,
Not sure exactly what you are after, but after struggling with IMbnInterface and GetSignalStrength() (see https://msdn.microsoft.com/en-us/library/windows/desktop/dd323166(v=vs.85).aspx) and being unsuccessful, I found that you can obtain a lot of info using WMI:
int maxBandwidth = 0;
string query = "SELECT * FROM Win32_PerfRawData_Tcpip_NetworkInterface";
ManagementObjectSearcher moSearch = new ManagementObjectSearcher(query);
ManagementObjectCollection moCollection = moSearch.Get();
foreach (ManagementObject mo in moCollection)
{
if (Convert.ToInt32(mo["CurrentBandwidth"]) > maxBandwidth)
{
// Instead of CurrentBandwidth you may want to use BytesReceivedPerSec
maxBandwidth = Convert.ToInt32(mo["CurrentBandwidth"]);
}
}
Please see answer here: Determining the network connection link speed and here is the list of properties you can obtain: https://msdn.microsoft.com/en-us/library/aa394293(VS.85).aspx
UPDATE:
Please note that I can build and debug the above code (as part of a larger WPF application) from within Visual Studio 2015 on either Windows 7 or Windows 8.1, and I can deploy the same application onto Windows 7 where it runs successfully. For some reason when I deploy this application on Windows 8.1, I get an Invalid query message.
UPDATE 2:
Please note that I found you cannot get the network info in Windows 8.1 in the same way as you do in Windows 7, in that the System.Management namespace is not available on Windows 8.1. See https://code.msdn.microsoft.com/windowsapps/network-information-sample-63aaa201
string connectionProfileInfo = string.Empty;
ConnectionProfile InternetConnectionProfile = NetworkInformation.GetInternetConnectionProfile();
if (InternetConnectionProfile == null)
{
rootPage.NotifyUser("Not connected to Internet\n", NotifyType.StatusMessage);
}
else
{
connectionProfileInfo = GetConnectionProfile(InternetConnectionProfile);
OutputText.Text = connectionProfileInfo;
rootPage.NotifyUser("Success", NotifyType.StatusMessage);
}
// Which calls this function, that allows you to determine how strong the signal is and the associated bandwidth
string GetConnectionProfile(ConnectionProfile connectionProfile)
{
// ...
if (connectionProfile.GetSignalBars().HasValue)
{
connectionProfileInfo += "====================\n";
connectionProfileInfo += "Signal Bars: " + connectionProfile.GetSignalBars() + "\n";
}
// ...
}