Monday, May 07, 2012

How to make sure FolderPicker.SuggestedStartLocation work every time ?

Windows Metro style application provide a class : FolderPicker for application to select a target folder, it provide a standard interface for end user to select a folder for further operation.

By assign SuggestedStartLocation, we could ask FolderPicker to default at an assigned location for user to browse.

However, by default, FolderPicker will remember where user selected last time, and start at last location, ignore the assignment of  SuggestedStartLocation.


Check MSDN documents, it seems that the property of settingsidentifier could do some trick :

http://msdn.microsoft.com/en-us/library/windows/apps/windows.storage.pickers.folderpicker.settingsidentifier.aspx


After I assign this property before call PickSingleFolderAsync, the problem solved, FolderPicker start at suggestedStartLocation each time when it show up :

folderPicker.SettingsIdentifier = DateTime.Now.ToString("HH:mm:ss tt");
StorageFolder folder = await folderPicker.PickSingleFolderAsync();


Use DatTime.Now.ToString just to make sure the string assigned is different every time, should be easy to replace with another solution.

Friday, May 04, 2012

Use WinRT API to get device information inside Metro style application

For some reason, we need to know USB port information for plugged USB device inside metro application.

Refer to MSDN :

It provides two set of namespace for access device information. By calling PnpObject.FindAllAsync, we could create a collection of device (filtered or not) :

PnpObjectCollection oo = await PnpObject.FindAllAsync(PnpObjectType.Device, properites );
foreach (PnpObject o in oo)
{
Debug.WriteLine(o.Id);
var pt = o.Properties.GetEnumerator();
while (pt.MoveNext())
{
if( pt.Current.Value != null )
Debug.WriteLine(pt.Current.Key + "=" + pt.Current.Value);
}
Debug.WriteLine(" ");
}

The secret here is how you assign those properties that you want in the second parameter of FindAllAsync . MSDN list some of them inside their pages :

System.Devices.InterfaceClassGuid
DEVPKEY_DeviceInterface_ClassGuid
Class GUID of the interface.
System.ItemNameDisplay
                DEVPKEY_NAME
                           The friendly name of the device interface.

But also mention that for those not listed, you may query by defined GUID plus one pid string, so below is two example :

string[] properites = { 
"System.ItemNameDisplay",
"System.Devices.ContainerId", 
"{a45c254e-df1c-4efd-8020-67d146a850e0},15", // location info
"{540B947E-8B40-45BC-A8A2-6A0B894CBDA2},10"  // bios device name
};


Below is the output result :

DISPLAY\ACI22FC\4&10c0f544&0&UID16843008
System.ItemNameDisplay=Generic PnP Monitor
{540B947E-8B40-45BC-A8A2-6A0B894CBDA2} 10=\_SB.PCI0.GFX0.DD01

DISPLAY\LGD2297\4&10c0f544&0&UID67568640
System.ItemNameDisplay=Generic PnP Monitor
{540B947E-8B40-45BC-A8A2-6A0B894CBDA2} 10=\_SB.PCI0.GFX0.DD03

USB\VID_0A12&PID_0001\6&18d9f06f&0&3
System.ItemNameDisplay=Generic Bluetooth Radio
System.Devices.ContainerId=29fb1cf5-7950-11e1-a117-806e6f6e6963
{A45C254E-DF1C-4EFD-8020-67D146A850E0} 15=Port_#0003.Hub_#0005
{540B947E-8B40-45BC-A8A2-6A0B894CBDA2} 10=\_SB.PCI0.EHC1.HUBN.PR01.PR13

USB\VID_093A&PID_2510\6&18d9f06f&0&1
System.ItemNameDisplay=USB Input Device
System.Devices.ContainerId=29fb1cf3-7950-11e1-a117-806e6f6e6963
{A45C254E-DF1C-4EFD-8020-67D146A850E0} 15=Port_#0001.Hub_#0005
{540B947E-8B40-45BC-A8A2-6A0B894CBDA2} 10=\_SB.PCI0.EHC1.HUBN.PR01.PR11

So that I got what I want, the monitor's BIOS device name, and port information of USB device.

Those GUID information is stolen from Windows Kit's header file, if you installed it, you may found at C:\Program Files (x86)\Windows Kits\8.0\Include\shared\devpkey.h

Basically, all those properties that displayed at Device Manager could be dump by this way.