How to handle Mediadevices FriendlyName when null - c#

I was working with MediaDevice library , it went okay when the device name match the FriendlyName,
My problem is when i dont plug in my device into the PC or i change a simple letter in FriendlyName
var devicess = MediaDevice.GetDevices();
using (var device = devicess.First(d => d.FriendlyName == "MyCellPhone"))
{
device.Connect();
// get list of available storages (SD-Card, Internal Flash, ...)
var objects = device.FunctionalObjects(FunctionalCategory.Storage);
MediaStorageInfo infoss = GetStorageInfo(objects.First());
ulong size = infoss.FreeSpaceInBytes;
device.Disconnect();
}
for Example if my smartphone is named "samsung" an i put "samsam" in here
using (var device = devicess.First(d => d.FriendlyName == "samsam")) (instead of samsung)
the app crashes , the same thing if leave it empty or i run the code with no phone attached.
i tried some try {} catch{} but no result.
Can any one help me please .
Thank you.

Use FirstOrDefault instead of First:
var device = devicess.FirstOrDefault(d => d.FriendlyName == "MyCellPhone")
This will return null if it can't find a match, instead of throwing an exception.

Related

UWP AudioGraph setup not working in all devices, HRESULT: 0x88960001 thrown on AddOutgoingConnection

I'm having trouble with a AudioGraph in a UWP app. My trouble is that when I'm adding adding an Outgoing Connection to my input device node I get a Exception thrown with HRESULT: 0x88960001.
Using trial and error I figured out that the problem is with the MediaEncoding profile I set on both the input and output node... but I have now 2 settings only work on one machine and the other only works on another machine... I needed the audio to be Single Channel, 16bit sample with a 16K sample in PCM.
The code I'm using is fairly simple and was based on samples that exist online, the thing is it works only on some microphones and not others... I needed it to be generic and have always the same output so that I can input that to my service endpoint.
I left the 2 AudioEncodingProperties settings there (one of them commented out)
var result = await AudioGraph.CreateAsync(
new AudioGraphSettings(AudioRenderCategory.Media));
if (result.Status == AudioGraphCreationStatus.Success)
{
this.graph = result.Graph;
var microphone = await DeviceInformation.CreateFromIdAsync(
MediaDevice.GetDefaultAudioCaptureId(AudioDeviceRole.Default));
// Low gives us 1 channel, 16-bits per sample, 16K sample rate.
var outProfile = MediaEncodingProfile.CreateWav(AudioEncodingQuality.Low);
//outProfile.Audio = AudioEncodingProperties.CreatePcm(16000, 1, 16);
outProfile.Audio = AudioEncodingProperties.CreatePcm(44100, 2, 32);
var inProfile = MediaEncodingProfile.CreateWav(AudioEncodingQuality.Low);
//inProfile.Audio = AudioEncodingProperties.CreatePcm(16000, 1, 16);
inProfile.Audio = AudioEncodingProperties.CreatePcm(44100, 2, 32);
var outputResult = await this.graph.CreateFileOutputNodeAsync(file,
outProfile);
if (outputResult.Status == AudioFileNodeCreationStatus.Success)
{
this.outputNode = outputResult.FileOutputNode;
var inputResult = await this.graph.CreateDeviceInputNodeAsync(
MediaCategory.Speech,
inProfile.Audio,
microphone);
if (inputResult.Status == AudioDeviceNodeCreationStatus.Success)
{
//EXEPTION IS THROWN HERE
inputResult.DeviceInputNode.AddOutgoingConnection(
this.outputNode);
this.graph.Start();
}
}
}
else
{
throw new Exception("Could not create AudioGraph");
}
Thank you guys for our help
Instead of constructing the inputResult with the inProfile.Audio object, try using the default encoding properties for the graph:
var enc = graph.EncodingProperties;
CreateAudioDeviceInputNodeResult deviceInputNodeResult = await graph.CreateDeviceInputNodeAsync(MediaCategory.Media, enc, this.outputNode);
I had a similar issue and this cleared things up, and allowed the audio to be input from any device without specifying the encoding profile.

DeviceConnectionChangeTrigger - Value does not fall within the expected range

I'm developing an UWP app for Desktop and Mobile. I'd like using DeviceConnectionChangeTrigger to identify when my BT device is in range, but when i try using it, I cannot register background task cause it keeps return System.ArgumentException "Value does not fall within the expected range." when executing "Register" method of BackgroundTaskBuilder.
code is very simple
var current = BackgroundExecutionManager.GetAccessStatus();
if (current == BackgroundAccessStatus.Unspecified || current == BackgroundAccessStatus.Denied)
{
var result = await BackgroundExecutionManager.RequestAccessAsync();
if (result == BackgroundAccessStatus.Denied || result == BackgroundAccessStatus.Unspecified)
throw new Exception("You cannot register Access");
}
//I tested it with BT and BTLE device but no luck
//var devices = await DeviceInformation.FindAllAsync(BluetoothLEDevice.GetDeviceSelector());
var devices = await DeviceInformation.FindAllAsync(BluetoothDevice.GetDeviceSelector());
var device = devices.FirstOrDefault();
if (device == null) throw new Exception("Device not found");
var trigger = await DeviceConnectionChangeTrigger.FromIdAsync(device.Id);
//trigger.MaintainConnection = true;
var builder = new BackgroundTaskBuilder
{
Name = "BluetoothConnectionWatcher",
TaskEntryPoint = typeof(BluetoothConnectionWatcherTask).FullName
};
builder.SetTrigger(trigger);
//error on next line!
var r = builder.Register();
My project has Bluetooth capabilities and one background task registered with Bluetooth property flagged.
All Bluetooth functionalities work well and I can communicate with devices without problem.
I tried several BT and BTLE device and for all of them seems I have the same problem.
I tried on Desktop and Mobile version of Windows 10 (both last fast insider build). Same problem.
The device.Id returned by code is similar to "Bluetooth#Bluetooth00:1a:7d:da:71:0a-fc:58:fa:4c:17:0a" for every BT device i tried (of course 2nd MAC address change based on device...)
Any advice?
Thanks in advance
As far as I know, with BLE you should use the Triggers designed for it. Thus if it is characteristics change you would want to get knowledge about, then you should use GattCharacteristicNotificationTrigger, and example on using it can be found from my blog.
Then if it just BLE device availability, and you can detect yours via scanrecord data, then do use the BluetoothLEAdvertisementWatcherTrigger instead. My Friend Juhana has example fro this in his blog.

Is there a way to check if a printing process was successful?

I have an application where I need to print a ticket. Each ticket must be unique. The application is windows forms and written entirely in c#. For our application we're using Samsung ML- 2525 laser monochromatic printers.
The flow is basically the following, the operator picks a product/ticket (which is unique) and then it presses a button that does 2 things:
Connects to a database and updates the product as used
Prints the ticket (this is done using System.Drawing and GDI+)
For some reason, every once in a while, the image that needs to be printed is not sent to the printer. It's a rare case, but it happens.
I tried to connect to the printer using Win32_Printer ( http://msdn.microsoft.com/en-us/library/Aa394363 ) but I can't get to get the current printer's state (online, offline, low toner, paper jam, etc). I can only check if the printer exists and that the paper size is installed correctly. I tried code similar to the following but it didn't work
private string MonitorPrintJobWmi()
{
var jobMessage = String.Empty;
var scope = new ManagementScope(ManagementPath.DefaultPath);
scope.Connect();
var selectQuery = new SelectQuery { QueryString = #"select * from Win32_PrintJob" };
var objSearcher = new ManagementObjectSearcher(scope, selectQuery);
var objCollection = objSearcher.Get();
foreach (var job in objCollection)
{
if (job != null)
{
jobMessage += String.Format("{0} \r\n", job["Name"].ToString());
jobMessage += String.Format("{0} \r\n", job["JobId"].ToString());
_jobId = Convert.ToInt32(job["JobId"]);
jobMessage += String.Format("{0} \r\n", job["JobStatus"].ToString());
jobMessage += String.Format("{0} \r\n", job["Status"].ToString());
}
}
return jobMessage;
}
I tried to get an API for the printer but I couldn't get a hold of it. By the way, the printer's software do indicate different errors in the windows toolbar.
My question is if anyone can lead me in the right direction as to how to connect to a printer and check if printing was successful.
Also, it would be helpful if someone know of some other specific printer in which I may accomplish this ie, changing hardware.
Thanks,
To get a list of print queues on the local machine, try PrintServer's GetPrintQueues method.
Once you have an instance of the PrintQueue object associated with the relevant printer, you can use it to access the printer's status (IsOffline, IsPaperOut, etc.). Also, you can use it to get a list of the jobs in the given queue (GetPrintJobInfoCollection) which then will allow you to get job-specific status information (IsInError, IsCompleted, IsBlocked, etc.).
Hope this helps!
After try to print your PrintDocument (System.Drawing.Printing), try to check status of printjobs.
First step: Initialize your printDocument.
Second step: Get your printer Name From System.Drawing.Printing.PrinterSettings.InstalledPrinters.Cast<string>();
And copy it into your printerDocument.PrinterSettings.PrinterName
Third step: Try to print and dispose.
printerDocument.Print();
printerDocument.Dispose();
Last step: Run the check in a Task (do NOT block UI thread).
Task.Run(()=>{
if (!IsPrinterOk(printerDocument.PrinterSettings.PrinterName,checkTimeInMillisec))
{
// failed printing, do something...
}
});
Here is the implementation:
private bool IsPrinterOk(string name,int checkTimeInMillisec)
{
System.Collections.IList value = null;
do
{
//checkTimeInMillisec should be between 2000 and 5000
System.Threading.Thread.Sleep(checkTimeInMillisec);
// or use Timer with Threading.Monitor instead of thread sleep
using (System.Management.ManagementObjectSearcher searcher = new System.Management.ManagementObjectSearcher("SELECT * FROM Win32_PrintJob WHERE Name like '%" + name + "%'"))
{
value = null;
if (searcher.Get().Count == 0) // Number of pending document.
return true; // return because we haven't got any pending document.
else
{
foreach (System.Management.ManagementObject printer in searcher.Get())
{
value = printer.Properties.Cast<System.Management.PropertyData>().Where(p => p.Name.Equals("Status")).Select(p => p.Value).ToList();
break;
}
}
}
}
while (value.Contains("Printing") || value.Contains("UNKNOWN") || value.Contains("OK"));
return value.Contains("Error") ? false : true;
}
Good luck.

Get Safe sender list in Outlook 2007 C# Add in

I have created an Outlook 2007 add-in in C#.NET 4.0.
I want to read the safe sender list in my C# code.
if (oBoxItem is Outlook.MailItem)
{
Outlook.MailItem miEmail = (Outlook.MailItem)oBoxItem;
OlDefaultFolders f = Outlook.OlDefaultFolders.olFolderContacts;
if (miEmail != null)
{
string body = miEmail.Body;
double score = spamFilterObject.CalculateSpamScore(body);
if (score <= 0.9)
{
miEmail.Move(mfJunkEmail);
}
}
}
So, the above code moves all email to spam, even though they are present in the safe sender list. Thus I want to get the safe sender list so that I can avoid this spam checking.
Could anybody please help me on this?
The Outlook object model doesn't expose these lists (for more or less obvious reasons). The safe sender list can be read straight from the registry at:
HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\Profiles\[PROFILE NAME]\0a0d020000000000c000000000000046\001f0418
This binary registry key contains double-byte characters, separated by a semicolon (;).
The MAPI property mapping onto this registry key is
PR_SPAM_TRUSTED_SENDERS_W, documented here.
Chavan, I assume since this hasn't been updated in over 4 years, you don't need any more information, but this question and the answer helped me find what I was looking for (it was very hard to find) and enabled me to write the code below that may help if you're still looking for an answer.
This code runs in LINQPad, so if you aren't a LINQPad user, remove the .Dump() methods and replace with Console.WriteLine or Debug.WriteLine.
Cheers!
const string valueNameBlocked = "001f0426";
const string valueNameSafe = "001f0418";
// Note: I'm using Office 2013 (15.0) and my profile name is "Outlook"
// You may need to replace the 15.0 or the "Outlook" at the end of your string as needed.
string keyPath = #"Software\Microsoft\Office\15.0\Outlook\Profiles\Outlook";
string subKey = null;
var emptyBytes = new byte[] { };
var semi = new[] { ';' };
string blocked = null, safe = null;
// I found that my subkey under the profile was not the same on different machines,
// so I wrote this block to look for it.
using (var key = Registry.CurrentUser.OpenSubKey(keyPath))
{
var match =
// Get the subkeys and all of their value names
key.GetSubKeyNames().SelectMany(sk =>
{
using (var subkey = key.OpenSubKey(sk))
return subkey.GetValueNames().Select(valueName => new { subkey = sk, valueName });
})
// But only the one that matches Blocked Senders
.FirstOrDefault(sk => valueNameBlocked == sk.valueName);
// If we got one, get the data from the values
if (match != null)
{
// Simultaneously setting subKey string for later while opening the registry key
using (var subkey = key.OpenSubKey(subKey = match.subkey))
{
blocked = Encoding.Unicode.GetString((byte[])subkey.GetValue(valueNameBlocked, emptyBytes));
safe = Encoding.Unicode.GetString((byte[])subkey.GetValue(valueNameSafe, emptyBytes));
}
}
}
// Remove empty items and the null-terminator (sometimes there is one, but not always)
Func<string, List<string>> cleanList = s => s.Split(semi, StringSplitOptions.RemoveEmptyEntries).Where(e => e != "\0").ToList();
// Convert strings to lists (dictionaries might be preferred)
var blockedList = cleanList(blocked).Dump("Blocked Senders");
var safeList = cleanList(safe).Dump("Safe Senders");
byte[] bytes;
// To convert a modified list back to a string for saving:
blocked = string.Join(";", blockedList) + ";\0";
bytes = Encoding.Unicode.GetBytes(blocked);
// Write to the registry
using (var key = Registry.CurrentUser.OpenSubKey(keyPath + '\\' + subKey, true))
key.SetValue(valueNameBlocked, bytes, RegistryValueKind.Binary);
// In LINQPad, this is what I used to view my binary data
string.Join("", bytes.Select(b => b.ToString("x2"))).Dump("Blocked Senders: binary data");
safe = string.Join(";", safeList) + ";\0"; bytes = Encoding.Unicode.GetBytes(safe);
string.Join("", bytes.Select(b => b.ToString("x2"))).Dump("Safe Senders: binary data");
PST and IMAP4 (ost) stores keep the list in the profile section in the registry. Profile section guid is {00020D0A-0000-0000-C000-000000000046}. To access the data directly, you will need to know the Outlook version and the profile name.
Exchange store keeps this data as a part of the server side rule that processes incoming messages on the server side. You can see the rule data in OutlookSpy (I am its author) - go to the Inbox folder, "Associated Contents" tab, find the entry named (PR_RuleMsgName) == "Junk E-mail Rule", double click on it, take a look at the PR_EXTENDED_RULE_CONDITION property.
Outlook Object Model does not expose Junk mail settings. If using Redemption (I am also its author) is an option, it exposes the RDOJunkEmailOptions.TrustedSenders collection (works both for the PST and Exchange stores):
set Session = CreateObject("Redemption.RDOSession")
Session.MAPIOBJECT = Application.Session.MAPIOBJECT
set Store = Session.Stores.DefaultStore
set TrustedSenders = Store.JunkEmailOptions.TrustedSenders
for each v in TrustedSenders
debug.print v
next

32Feet API with C# .NET - Stuck

I am trying to pair my Wiimotes using 32Feet API and I am successfully in doing so by following code.
var client = new InTheHand.Net.Sockets.BluetoothClient();
var devices = client.DiscoverDevices();
var count = (from d in devices
where d.DeviceName.Contains("Nintendo")
select d).Count();
foreach (var device in devices)
{
if (device.DeviceName.Contains("Nintendo"))
{
if (device.InstalledServices.Length > 0)
{
InTheHand.Net.Bluetooth.BluetoothSecurity.RemoveDevice(device.DeviceAddress);
//while it's being removed
Thread.Sleep(2000);
}
device.SetServiceState(InTheHand.Net.Bluetooth.BluetoothService.HumanInterfaceDevice, false);
device.SetServiceState(InTheHand.Net.Bluetooth.BluetoothService.HumanInterfaceDevice, true);
//Here I am confused! What to do to read from stream?
}
}
The line which I have commented as "Here I am confused!..." is what messing all the time. Can someone help me how to connect to all the wiimotes one by one and then to read from their stream please?
Don't try to reinvent the wheel, use an existing library: http://wiimotelib.codeplex.com/

Categories

Resources