Mute/unmute, Change master volume in Windows 7 x64 with C# - c#

How can I adjust master volume in Windows 7 with C#?
I have seen an excellent implementation using winmm.dll here, but it works with XP and not with Windows 7.

I used the nuget package Naudio successfully with this code:
public void SetVolume(int level)
{
try
{
//Instantiate an Enumerator to find audio devices
NAudio.CoreAudioApi.MMDeviceEnumerator MMDE = new NAudio.CoreAudioApi.MMDeviceEnumerator();
//Get all the devices, no matter what condition or status
NAudio.CoreAudioApi.MMDeviceCollection DevCol = MMDE.EnumerateAudioEndPoints(NAudio.CoreAudioApi.DataFlow.All, NAudio.CoreAudioApi.DeviceState.All);
//Loop through all devices
foreach (NAudio.CoreAudioApi.MMDevice dev in DevCol)
{
try
{
if (dev.State == NAudio.CoreAudioApi.DeviceState.Active)
{
var newVolume = (float)Math.Max(Math.Min(level, 100),0) / (float)100;
//Set at maximum volume
dev.AudioEndpointVolume.MasterVolumeLevelScalar = newVolume;
dev.AudioEndpointVolume.Mute = level == 0;
//Get its audio volume
_log.Info("Volume of " + dev.FriendlyName + " is " + dev.AudioEndpointVolume.MasterVolumeLevelScalar.ToString());
}
else
{
_log.Debug("Ignoring device " + dev.FriendlyName + " with state " + dev.State);
}
}
catch (Exception ex)
{
//Do something with exception when an audio endpoint could not be muted
_log.Warn(dev.FriendlyName + " could not be muted with error " + ex);
}
}
}
catch (Exception ex)
{
//When something happend that prevent us to iterate through the devices
_log.Warn("Could not enumerate devices due to an excepion: " + ex.Message);
}
}

CodeProject has a very good sample here. Note that it relies on COM interop completely (check COM interface like IAudioEndpointVolume and IAudioMeterInformation on MSDN if you are interested in implementation details), and works ONLY for Vista/Win7 and higher.
Minimum supported client: Windows Vista
Minimum supported server: Windows Server 2008

Related

MSFT_Volume Format Method, in WinPE

I hope there may be some insight and maybe help in relation to my query.
I am trying to write the last module to a customised Windows Recovery environment, based on WinPE for Windows 10.
The solution currently utilises DiskPart to create the Disk Partitions (inline with Microsoft advice here), with the change of not providing for the WinRE partition.
After a fair amount of research and tinkering with a project found on MSDN, I managed to get a working project that would clear/partition and format a disk using WMI (MSFT_Disk,MSFT_Partition & MSFT_Volume). That is fully working within Windows 10 on a virtual disk of 15 GiB size.
When I tried it in WinPE (as this will be the OS that it will be used on), it failed on multiple elements, even though the Methods were reported as there). (MSFT_Disk::Clear, MSFT_Volume::Format).
On inspecting the result of my work in DiskPart, I noticed that even though MSFT_Volume::Format had a return value of 2 "Unknown Error" it had actually formatted the data partition (NTFS, ClusterSize 4096). However, when when the Format method is applied to the ESP (FAT32, cluster size 512/1024/4096)it fails fully, with the FileSystem still being reported as RAW, but will apply an AccessPath. "ExtendedStatus" only returns Error 2 (unless I am not accessing it correctly).
Has anyone else had this problem and managed to rectify the problem? Multiple Google searches have thrown out the idea that there maybe a WMI error, but within PowerShell, not as coded in C#/C++. Below are some code snippets and screen shots:
Creating the Partition:
try
{
parameters = disk.GetMethodParameters("CreatePartition");
}
catch (Exception e)
{
Console.WriteLine("Exception in Line 88: " + e.Message);
}
if (PartitionType != "PRIMARY")
{
FillInvocationParameters(parameters, new Dictionary<string, object> { { "Size", _partitionSize.ToString() },
{ "AssignDriveLetter", false },
{ "GpTType", _partitionType} });
}
else
{
FillInvocationParameters(parameters, new Dictionary<string, object> { { "UseMaximumSize", true },
{ "AssignDriveLetter", false },
{ "GpTType", _partitionType} });
}
try
{
res = disk.InvokeMethod("CreatePartition", parameters, null);
objresult = res["ReturnValue"]; //write error handliong routine for the objResult.
Int32.TryParse(objresult.ToString(), out intRes);
}
catch (Exception e)
{
Console.WriteLine("Exception in Line 146: " + e.Message);
ErrorID = Marshal.GetLastWin32Error();
return false;
}
if (intRes != 0)
{
Console.Write("CreatePartition {0} failed with the result: {1} Line 111.", PartitionType, objresult.ToString());
Console.ReadKey();
ErrorID = Marshal.GetLastWin32Error();
return false;
}
//this is the format point for EFI System Disk.. MSFTPARTITIONtoVOLUME MSFT VOLUME::FORMAT
Console.Write($"{PartitionType} Partition has been created\r\n");
string partition = ((ManagementBaseObject)res["CreatedPartition"])["__PATH"] as string;
var MSFT_Partition = new ManagementObject(#"root\Microsoft\Windows\Storage", partition, null);
var partitionIndex = partition.IndexOf(#"ObjectId=\");
partition = partition.Substring(partitionIndex);
partitionIndex = partition.IndexOf(#"}\\");
partitionIndex = partitionIndex + 1;
partition = partition.Substring(0, partitionIndex);
var strMSFTPartition = partition;
partition = partition.Replace("root", "ROOT");
var partitionGuid = MSFT_Partition["Guid"] as string;
Console.WriteLine("Line 138: New Partition GUID: " + partitionGuid);
Parameters is declared as:
ManagementBaseObject parameters = null;
FillInvokationParamters:
private static void FillInvocationParameters(ManagementBaseObject InvocationParameters, IDictionary<string, object> parameters)
{
foreach (var pair in parameters)
{
string stringParamValue;
var managementObjectParam = pair.Value as ManagementObject;
var arrayParam = pair.Value as string;
if (managementObjectParam != null)
{
stringParamValue = managementObjectParam.GetText(TextFormat.CimDtd20);
InvocationParameters[pair.Key] = stringParamValue;
}
else if (arrayParam != null)
InvocationParameters[pair.Key] = arrayParam;
else if (pair.Value != null)
{
stringParamValue = pair.Value.ToString();
InvocationParameters[pair.Key] = stringParamValue;
}
}
}
And the Format Method call:
try
{
Console.Write("Line 174: Attempting to Format with MSFT_Volume::Format FileSystem {0}, Label: {1}, ClusterSize: {2}\r\n", _FileSystem, _VolumeLable, _allocationUnit.ToString());
parameters = MSFTVolume.GetMethodParameters("Format");
FillInvocationParameters(parameters, new Dictionary<string, object>{ { "FileSystem", _FileSystem },
{ "AllocationUnitSize", _allocationUnit },
{ "FileSystemLabel", _VolumeLable },
{ "Full", false} });
res = MSFTVolume.InvokeMethod("Format", parameters, null);
objresult = res["ReturnValue"];
Int32.TryParse(objresult.ToString(), out intReslt);
}
catch (Exception e)
{
Console.WriteLine("Line: 189 The Following error occured while attmpeting to Format the Volume: " + e.Message);
ErrorID = Marshal.GetLastWin32Error();
return false;
}
For the ESP the following applies:
switch(PartitionType)
{
case "EFI":
{
_partitionType = "{c12a7328-f81f-11d2-ba4b-00a0c93ec93b}";
_partitionSize = 260 /*bytes*/ *1024 /*Kilobytes*/ *1024 /*Megabytes*/;
_FileSystem = "FAT32";
_allocationUnit = 1024;
_VolumeLable = "System";
break;
}
}
Screenshots of my console app and diskpart results:
Format Disk Console output
DiskPart Results
Any help/insights will be gratefully appreciated.
Regards
Richie
Note that there are several builds of the ADK for newer builds of Windows 10...be sure to use the latest and greatest. We had issues similar to yours with both dism.exe and diskpart.exe. At one point, (on early win 10 adks) we got dism.exe and diskpart.exe from an 8.1 adk. Hacky as heck, but you gotta do what you gotta do :-)
Update:
Checked with the support group...turns out, I got the versions mixed up. The very first win 10 adk had a working dism and diskpart (adk for windows 10 1503)...and we've been unable to use newer ones from within PE since...and so we're still deploying a new winpe from new ADK - but copying in the diskpart and dism saved off from the 1503 adk. We never deployed 8.1 versions - my bad. Still - hacky as all git out.
Best we can recollect, it only presented a problem in one side of the house...either BIOS+MBR or UEFI+GPT...but none of us remember which.

Sending SCPI/GPIB commands over USB from C#

I'm trying to communicate with some test equipment from C# over SCPI. I managed to communicate with one device that is connected through TCP/IP by using this code example.
However, my other devices are connected through USB and I haven't find how to communicate with them over USB.
BTW, I found this question, and the link from the answer to the IVI-COM programming examples in C# document, but I couldn't apply the code samples (e.g. in section 5.4) because all of the IVI and VISA COM libraries I found (e.g. VisaComLib 5.5) has only interfaces and enums in it, and no concrete class that I can use...
If you install the visa driver from either NationalInstruments or Keysight, they do implement classes:
The one from NI:
FormattedIO488Class
ResourceManagerClass
VisaConflictTableManagerClass
To get a connection, you only need 1 and 2
As soon as you try to embed the interoptypes, you need to remove the 'Class' suffix, as described here
Here comes a sample snippet from Keysight (Application Note: 5989-6338EN)
Ivi.Visa.Interop.ResourceManager rm = new Ivi.Visa.Interop.ResourceManager();
Ivi.Visa.Interop.FormattedIO488 ioobj = new Ivi.Visa.Interop.FormattedIO488();
try
{
object[] idnItems;
ioobj.IO = (Ivi.Visa.Interop.IMessage)rm.Open("GPIB2::10::INSTR",
Ivi.Visa.Interop.AccessMode.NO_LOCK, 0, "");
ioobj.WriteString("*IDN ?", true);
idnItems = (object[])ioobj.ReadList(Ivi.Visa.Interop.IEEEASCIIType.ASCIIType_Any, ",");
foreach(object idnItem in idnItems)
{
System.Console.Out.WriteLine("IDN Item of type " + idnItem.GetType().ToString());
System.Console.Out.WriteLine("\tValue of item is " + idnItem.ToString());
}
}
catch(Exception e)
{
System.Console.Out.WriteLine("An error occurred: " + e.Message);
}
finally
{
try { ioobj.IO.Close(); }
catch { }
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(ioobj);
}
catch { }
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(rm);
}
catch { }
}
I'm using National Instruments VISA.
Add a reference to NationalInstruments.VisaNS and NationalInstruments.Common to your project.
Create a MessageBasedSession, see the following code:
string resourceName = "USB0::0x0957::0x0118::US56070667::INSTR"; // See NI MAX for resource name
var visa = new NationalInstruments.VisaNS.MessageBasedSession(resourceName);
visa.Write("*IDN?"); // write to instrument
string res = visa.ReadString(); // read from instrument
See as well https://stackoverflow.com/a/49388678/7556646.

Load achievements from Google Play without any Unity plugins only native code

It is possible to use this code from Unity samples:
//C#
Social.LoadAchievements (achievements => {
if (achievements.Length > 0) {
Debug.Log ("Got " + achievements.Length + " achievement instances");
string myAchievements = "My achievements:\n";
foreach (IAchievement achievement in achievements)
{
myAchievements += "\t" +
achievement.id + " " +
achievement.percentCompleted + " " +
achievement.completed + " " +
achievement.lastReportedDate + "\n";
}
Debug.Log (myAchievements);
}
else
Debug.Log ("No achievements returned");
});
and get Google Play achievements. Or it's works only for iOs devices and for Android I have to use some plugins?
This script as I understood works only for iOs devise not for Android.
Why don't use standard Unity Google plugin?
- Because they don't teach it to load achievements.
/// <summary>
/// Not implemented yet. Calls the callback with an empty list.
/// </summary>
public void LoadAchievements(Action<IAchievement[]> callback) {
Logger.w("PlayGamesPlatform.LoadAchievements is not implemented.");
if (callback != null) {
callback.Invoke(new IAchievement[0]);
}
}
Why not to use the official Google Play Services plugin for Unity?
Here's a Link to an official Google Developer web site, where you can find all the information you need to set it up correctly.
This plugin works on both Android and iOS Devices!

Get RSSI from an iBeacon estimote in c#

I'm trying to locate the distance from my computer and an iBeacon using bluetooth connection and getting the rssi. It's my first time using bluetooth in my apps and I'm something lost.
I downloaded the "32 feet" library (http://32feet.codeplex.com/) to use bluetooth functions, but I can't do this to work... This is the code I have:
BluetoothClient b = new BluetoothClient();
BluetoothDeviceInfo[] devices = b.DiscoverDevices();
BluetoothDeviceInfo info = devices.ElementAt(0);
// the first element it's the estimote
System.Windows.Forms.MessageBox.Show("Device name: " + info.DeviceName+"\n");
if (info.Connected)
{
System.Windows.Forms.MessageBox.Show("Connected\n");
}
else
{
System.Windows.Forms.MessageBox.Show("Not connected\n");
}
if (info.Authenticated)
{
System.Windows.Forms.MessageBox.Show("Authenticated\n");
}
else
{
System.Windows.Forms.MessageBox.Show("Not Authenticated\n");
}
System.Windows.Forms.MessageBox.Show("RSSI: " + info.Rssi + "\n");
The output is: Device name: estimote. Not connected. Authenticated. RSSI: -2147483648 (the minimum int?)
Thanks for your help.
This is Wojtek Borowicz, I'm a community evangelist at Estimote.
Unfortunately, RSSI is currently still not available for most of the Windows Bluetooth stacks.

Media player in Windows Phone 7

I am using the media player in Windows Phone 7 to play the music in the phone song collection. But when it play the music they will be an exception and the error is stating
FrameworkDispatcher.Update has not been called. Regular FrameworkDispatcher.Update calls are necessary for fire and forget sound effects and framework events to function correctly.
How should i go about modifying my code?
private void songBtn_Click(object sender, RoutedEventArgs e)
{
using (var ml = new MediaLibrary())
{
foreach (var song in ml.Songs)
{
System.Diagnostics.Debug.WriteLine(song.Artist + " " + song.Name);
MessageBox.Show(song.Artist + " " + song.Name);
}
MediaPlayer.Play(ml.Songs[0]);
}
}
You have to call
FrameworkDispatcher.Update()
whenever you make a call to an XNA media library
so your code should look like this
using (var ml = new MediaLibrary())
{
foreach (var song in ml.Songs)
{
System.Diagnostics.Debug.WriteLine(song.Artist + " " + song.Name);
MessageBox.Show(song.Artist + " " + song.Name);
}
FrameworkDispatcher.Update();
MediaPlayer.Play(ml.Songs[0]);
}
The error is occouring because you're using the XNA Framework in a regular Windows Phone 7 application.
If you read the error description, you would gotten this link to MSDN: Enable XNA Framework Events in Windows Phone Applications , which explains precisely what to do.

Categories