Consuming the Contents of Windows 7 Libraries

This is the fifth post about Windows 7 Libraries. By now, you should be familiar with Windows 7 Libraries (Understanding Windows 7 Libraries) and understand the internal structure of Libraries and how they integrate into the Windows Shell (Libraries Under the Hood). In the previous post, we explained the different programming models and ways to work with Windows 7 Libraries. In this post, we focus on the Windows Shell Programming model that you can use to access libraries even without using the latest IShellLibrray APIs.

In the previous post, we talked about the importance of using the right version of the Common File Dialog (CFD) to enable the complete Libraries user experience in Windows 7. In this post we will further explorer the opportunities to let users select and consume Libraries as if they where regular folders. Let’s imagine the case of a slideshow application that presents users' pictures. By using the Pictures Library, users are essentially telling the system that their important pictures are stored in the Pictures Library, and therefore, our slideshow application can simply be pointed directly to the Pictures Library and show the users' entire pictures collections. Furthermore, from developers’ point of view, using the Libraries system can eliminate the need to maintain a separate configuration file or database, since developers can rely on the Libraries System. But before we dive into the Shell Libraries programming APIs, we need to understand the few concepts regarding the Shell Programming Model.

Shell Programming Model

  • IShellItem, commonly referred to as an item, is the currency of the Shell UI model and its programming model. Items are individual, self-contained content sources. Take for example the above-mentioned Common File Dialogs. Quite few of the interface methods used for controlling the file dialogs use Shell items to refer to folders instead of file system paths. This is important because the CFD can communicate information about both file system folders and other virtual folders that you find in the shell, such as the Control Panel or the Computer folder.
  • IShellFolder interface represents shell folder objects from the shell namespace. Using IShellFolder you can traverse through the contents of a folder, to retrieve the display name of an item in a folder, parse a display name relative to the folder, and obtain an item ID list.
  • IShellLink interface represents a link, usually to a file, folder, or an executable.
  • IPropertyStore interface can be used to manage the property store associated with various shell objects.
  • IShellLibrary interface represents a Windows 7 Library, which we will cover in depth in future posts.

Now that we have defined the different players in the Shell Programming Model, we can see how Libraries fit into this model. Since Libraries are not file system locations, you cannot use file system-specific APIs. Therefore, you have two main options to consume library contents - the Shell Programming Model and the new IShellLibrary API.

Using the Shell Programming Model

You can use the IShellItem and IShellFolder interfaces and a bunch of helper functions to enumerate the contents of Libraries just as if they were regular folders. This means that applications can consume Libraries contents without using the new Libraries API and with very little change to their existing code.

The following code snippet shows how to use the IShellFolder interface to enumerate through the entire contents of the Picture library.

IShellItem *psi;
HRESULT hr = SHGetKnownFolderItem(
FOLDERID_PicturesLibrary,
KF_FLAG_CREATE,
NULL,
IID_PPV_ARGS(&psi));
if(SUCCEEDED(hr))
{
IShellFolder *psf;
hr = psi->BindToHandler(NULL, BHID_SFObject, IID_PPV_ARGS(&psf));
if(SUCCEEDED(hr))
{
IEnumIDList *penumIDList;
psf->EnumObjects(NULL,
SHCONTF_FOLDERS | SHCONTF_NONFOLDERS,
IID_PPV_ARGS(&penumIDList));
//use penumIDList to enumerate the content of the folder
}
}

Here you can see that by using the helper function SHGetKnownFolderItem, we can retrieve the correct library location by passing the FOLDERID_PicturesLibrary, which is a GUID representing the known folder, in our case the Pictures Library.The SHGetKnownFolderItem is a Shell Helper function and is part of a larger group of helper functions that can be found in the shlobj.h header file in the Windows 7 SDK. A successful call will fill the IShellItem *psi with the correct information about the Library represented as a Shell Item. From this point the rest of the code is standard Windows Shell programming, where we use the BindToHandler to bind the previously obtained Shell Item to a Shell folder. Next, we enumerate through the different items in the Shell folder, which in case of a library can be either files or folders. Note the SHCONTF_FOLDERS | SHCONTF_NONFOLDERS flags that we are passing, this is telling the shell folder that we want to return all of the files and folders in a library. We could pass SHCONTF_NAVIGATION_ENUM to get the library locations instead of the library

Using the New IShellLibrary API

You can achieve the same functionality as the code above by using the new Windows 7 IShellLibrary API as shown by the next code snippet.

IShellLibrary *pslLibrary;
HRESULT hr = SHLoadLibraryFromKnownFolder(
FOLDERID_PicturesLibrary,
STGM_READ,
IID_PPV_ARGS(&pslLibrary));
if(SUCCEEDED(hr))
{
IShellItemArray *psiaFolders;
hr = pslLibrary->GetFolders(
LFF_STORAGEITEMS,
IID_PPV_ARGS(&psiaFolders));
IEnumShellItems *penumShellItems;
psiaFolders->EnumItems(&penumShellItems);
//work with penumShellItem to enumerate the library locations.
}

Here you can see that we used another helper function SHLoadLibraryFromKnownFolder to create the IShellLibrary object from which we can call the GetFolders method to return an IShellItemArray that contains the library locations. This is the same as using SHCONTF_NAVIGATION_ENUM in the above Shell programming model example. You can directly enumerate the contents of each of the library locations using the shell programming model or get the path of each of the locations.

In the next post we will focus more on the rest of the IShellLibrary API.


Test Your Application on Windows 7 at TechEd 2009

In this post we will deviate from our normal routine of writing about Windows 7 features, APIs, and code samples, and will instead talk a little about an amazing opportunity to test your application for Windows 7 application compatibility. We will focus on Application Compatibility as part of the Windows 7 Developers' Blog, but, right now we want to let you know about a great offer we have for you.

Are you planning to attend Microsoft TechEd 2009? Well, here is another good reason for you to consider attending: the Windows 7 ‘Bring Your Own Apps’ Lab. This lab will allow you to test your applications for compatibility with Windows 7, and will be offered free of charge. This is an amazing opportunity to test your applications on Windows 7 and work with Microsoft engineers on specific Windows 7 compatibility issues.

You must be asking yourself, “So how exactly does this lab work?

Simple! We are setting up a secure Windows 7 test platform in a private developer lab environment for testing and debugging your applications. Just bring your applications and we will load them on the test platform, and our dedicated consultants will help you investigate any application compatibility issues and offer architectural guidance.

By now you should be saying, “OK, I am in! How do I register?”

Pre-register for the 75-minute lab sessions by emailing srglabs@microsoft.com with your company name, list of developers, and list of application names and versions you wish to check. You can also register upon arrival at TechEd by signing up at the reception station located in the lab (Room 410). As an added convenience, the lab will also be available on May 10th, the Sunday prior to TechEd 2009, and is open for registration then as well.

This is a great opportunity to test your applications on Windows 7, but there is limited availability, so be sure to register early.

If you are not able to attend TechEd, check out these other resources to help you ensure that your applications are Windows 7 compatible. You can find all the relevant resources in the Windows Application Compatibility page on MSDN. But I want to highlight few key resources:

  • Windows 7 Application Quality Cookbook is your one-stop shop for information about any breaking changes from Windows Vista to Windows 7
  • However, there are still a few applications that are not Windows Vista compatible, which means they are probably not Windows 7 compatible. The Windows Vista Application Compatibility Cookbook is a great place to learn more about compatibility topics like UAC, Session 0 Isolation, and others.

See you at TechEd


Light Up with Windows 7 Libraries

OK, it is time we to dive into the gist of Windows 7 Libraries. This is the fourth post in a series of Windows 7 Libraries posts. So far, we discussed what Windows 7 Libraries are (Understanding Windows 7 Libraries) and we reviewed the internal structure of Libraries and how they integrate into the Windows Shell Libraries Under The Hood. In this post, we review the different programming models developers can use when integrating Libraries into their applications.

Libraries are the new entry points for user’s data In Windows 7. Libraries are an integral part of the Shell and are promoted across Windows in Windows Explorer, Start Menu, and Common File Dialog. Windows 7 Users will use Libraries in their day-to-day activities. As such, they will expect applications that are running on Windows 7 to work properly with their Libraries and provide the same user experience as Windows Explorer. It is therefore important that, as developers, we know how to work with libraries and make our applications Libraries-aware.

But before we start, I want to note that while most applications should just work fine with Windows 7 Libraries, there is an opportunity to tap into the Windows 7 Libraries environment to provide a richer user experiences.

 Making an application Libraries-aware

One may wonder what would happen if “my application does not support Libraries.” Let’s imagine an application that, as part of its functionality, needs to save a file to the disk. The application prompts the user with the option to select a location for the file. The user may pick the Documents Library as his save "folder" since this is where the user usual goes when he needs to work on a document. However, if the application doesn’t recognize that the user selected the Documents Library and not a regular folder, the application may try to save to the Documents Library. This is a problem, since by now, as we already know, that Libraries are non –file system location and therefore can’t be address as regular folders.

A Library-aware application should include mechanisms for handling situations where users inadvertently try to pick libraries as if they are folder for either saving files to a Library or loading the contents of a Library. Furthermore, most applications allow users to interact with the file system as part of the application experience. An application should provide users with the same familiar entry points and UI offered by the Windows 7 Libraries. By including folders in a Library, users designate where their important data is stored, and thus applications should promote these locations by enabling Library browsing.

Developers have three integration points with Windows 7 that can help applications become Library-aware. You should review and become familiar with all three points and choose according to your needs.

  1. The most basic integration method is simply to use the new Common File Dialog (CFD) for picking files and folders while performing either save or load operations
  2. The second integration point offers applications the opportunity to Light Up on Windows 7 by enabling applications to select Libraries and consume Libraries contents.
  3. The last and most advanced integration point is to stay in sync with Library contents and directly manipulate Libraries by using the new IShellLibrary API that allows full control over libraries, including creating new libraries.

 

Let’s start by looking at the basic integration point, which can also be viewed as the bare minimum requirement for application compatibility when working with Windows 7 Libraries.

Using the Common File Dialog (CFD)

The good news is that Windows 7 Libraries are first class citizens in the CFD, allowing users to browse through Libraries, search Libraries, and even pick a specific Library as a save location, not an actual folder in the Library, but rather the Library itself!

But (there is always a but), we highly recommended that you use the new CFD interfaces that was introduced with Windows Vista, and not older or customized versions of the CFD. It is very important to note that the APIs for using the legacy CFD have not changed since Windows Vista, and XP to support application compatibility. However, the legacy version of the CFD (as is displayed in the next image) doesn’t directly support Libraries or the full new user experience offered in Windows 7.

image 

Even if Libraries are presented in the right navigation pane, they require an extra click to save into one of the folders rather than just the Library. Also the legacy CFD doesn’t expose the search and arrangement views functionality that libraries offer. Finally, the legacy CFD doesn’t support the multiple selections of files across several folders, a basic functionality promoted in Libraries.

Therefore, it is important to use the proper APIs to show the correct CFD version. When using .NET, developers can use either the System.Windows.Forms.FileDialog or the Microsoft.Win32.FileDialog namespace. The latter uses the legacy version of the CFD; therefore, .NET developers should always use the WinForms namespace to show the new CFD. The following is a code snippet that prompts the user to choose a save location by showing the common save file dialog as shown in the next image.

System.Windows.Forms.SaveFileDialog _fd = 
new System.Windows.Forms.SaveFileDialog();
_fd.Title = "Please choose a location to save your file";
_fd.FileName = "[Get Folder…]";
_fd.Filter = "Library|no.files";
if (_fd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
string dir_path = System.IO.Path.GetDirectoryName(_fd.FileName);
if (dir_path != null && dir_path.Length > 0)
{
//this returns the path to the default save location
lblResult.Content = dir_path;
}
}

image

Native code developers should use the new family of IFileDialog native APIs (IFileDialog, IFileOpenDialog, IFileSaveDialog, IFileDialogCustomize, IFileDialogEvents, IFileDialogControlEvents) that are replacing the legacy GetOpenFileName and GetSaveFileName APIs from earlier Windows versions.

The Shell native APIs are COM-based; therefore, before using any COM object we must remember to initialize the COM object by calling CoCreateInstance. As an example, the following code snippet prompts the user to choose a Library or a folder to save the file to, by showing the common save file dialog.

*ppsi = NULL;
IFileSaveDialog *pfod;
hr = CoCreateInstance(
CLSID_FileSaveDialog,
NULL,
CLSCTX_INPROC,
IID_PPV_ARGS(&pfod));

if (SUCCEEDED(hr))
{
hr = pfod->SetOptions(FOS_PICKFOLDERS);
if (SUCCEEDED(hr))
{
hr = pfod->Show(hWndParent);
if (SUCCEEDED(hr))
{
hr = pfod->GetResult(ppsi);
}
}
pfod->Release();
}

After initializing the *pfod IFileSaveDialog variable, we set the dialog options to pick folders by passing the FOS_PICKFOLDERS flag to the IFileOpenDialog.SetOptions(). This code tells the Open dialog to enable the user to choose folders rather than files, and allows the user to choose a Library. If choosing a library, the CFD will then return the default save location folder that is associated with the chosen Library.

The two above code snippets are very simple and don’t show any new code; however, it is important to promote consistency among applications running on Windows 7 and supporting Windows 7 Libraries.

In the next post, we will (finally) show the new Windows 7 library API, as well as how to consume Library contents with the existing Shell APIs.



Libraries Under the Hood

By now, you should have a better understanding of what Windows 7 libraries represent and how they can benefit users as well as developers. This is the third post in a series of Windows 7 Libraries posts. In the previous post, Understanding Windows 7 Libraries, we explained what libraries are and the important role they play in users’ day-to-day work. In this post, we explain the underlying architecture that supports libraries.

As usual, let’s start with a quick historic review of Libraries' ancestors. Windows Vista introduced a new storage scenario and a new user profile namespace called the “Known Folders.” This represented the next evolutionary step from “standard folders” that were based on a constant special item ID list (CSIDL). The CSIDL values provide a system-independent way to identify special folders used frequently by applications. In Windows Vista, we replaced these values with the Known Folders system where a KNOWNFOLDERID constant identifies each special folder.

Both CSIDL and Known Folders included support for users’ specific content types such as Document, Music, Pictures and Videos – these folders are part of the user storage profile. In Windows 7, Libraries extend some of the common user Known Folders, like My Documents, into the Documents Library. If you review the KNOWNFOLDERID in Windows 7 Beta SDK, you will find that the default Libraries are Known Folders themselves, which make sense since we want a unified programmatic way to access user’s content. By default, each Library contains two physical file locations:

  • The user's personal folder by type (Documents, Pictures, Video…), which is represented by the default Known Folder that is included in a Library (that is, My Documents in the Documents Library), and it is also the default save location.
  • The public folder by type

For custom Libraries, the default save location is the first folder added.

In some ways, a Library is similar to a folder. From a user's point of view, a library looks and behaves just like a regular folder. However, unlike a folder, a Library gathers files that are stored in several locations into a single view. This is a subtle, but important difference. Libraries don't actually store users’ items, they only monitor folders that contain items, and let users access and arrange these items in different ways. They also let users and developers access the list of folders and their contents. For example, if you try to save a text document (from Notepad) directly to the Documents Library, the file will be saved. However, we just said that Libraries are NOT regular folders that contain files, so what’s going on? Well, the text file is saved to the Documents Library default save location, which is, by default, the user’s Documents folder – also known as “My Documents” and is part of the user profile. The user has full control over the default save location as well as the other locations that are part of a library. As shown in the next figure, the Picture Library management dialog (which is accessible directly from the Windows Explorer UI) contains several locations on my local hard drive with one of the folders designated as the default save location.

Library Management Dialog

It is important to note that the Pictures Library didn’t replace the My Pictures folder from Windows Vista; it simply includes that folder in the Pictures library as one of many locations. Also, please note that the CSIDL system and its APIs system are still supported for application compatibility. However, we do not recommend that you use them in new application development.We recommend that you use the known folder system instead

A Library in Windows 7 is stored as an XML definition file that has a file extension of “.library-ms.” The file name is the actual library’s name. For example, the Documents Library is represented by an XML file called Documents.library-ms. Library descriptions are saved on disk in the %appdata% Roaming\Microsoft\Windows\Libraries folder (also known as FOLDERID_Libraries). You can use the Library definition files to monitor changes to the library as we will explain in future posts

Let’s dig into the Documents Library definition file schema. The XML structure is pretty self-explanatory, but let’s explain a few of its elements. At the top of the file, we can find the Library “header” information:

<libraryDescription xmlns="http://schemas.microsoft.com/windows/2009/library">
<name>@shell32.dll,-34575</name>
<ownerSID>S-1-5-21-2127521184-1604012920-1887927527-4897363</ownerSID>
<version>4</version>
<isLibraryPinned>true</isLibraryPinned>
<iconReference>imageres.dll,-1002</iconReference>
<templateInfo>
<folderType>{7D49D726-3C21-4F05-99AA-FDC2C9474656}</folderType>
</templateInfo>

The root XML element is libraryDescription, which contains child elements that define the library:

  • <ownerSID> is an element that defines the Security ID of the user who created this library to isolate Libraries and protect user data from other users
  • <isLibraryPinned> is a Boolean element that defines if the library is pinned to the left navigation pane in Windows Explorer and NOT to the Taskbar
  • <version> defines the content version of this library, which reflects the number of times the library definition file has been changed
  • <templateInfo> is an optional container element that lets the author specify the folder type (Documents, Pictures, Video) for controlling the arrangements of views in Windows Explorer
  • <iconReference> defines an icon resource using standard Windows Shell resource style; for example: <iconReference> C:\Windows\system32\imageres.dll,-65 </iconReference>. This icon presents the library in the Windows Explorer

Users can’t change the default libraries icon via Windows Explorer, nor can they assign the icon to a new customized user-defined library. However, this can be done programmatically using the API, which we will cover in future posts.

A key part of the XML is the list of locations that the Library represents:

<searchConnectorDescriptionList>
<searchConnectorDescription publisher="Microsoft" product="Windows">
<description>@shell32.dll,-34577</description>
<isDefaultSaveLocation>true</isDefaultSaveLocation>
<isSupported>true</isSupported>
<simpleLocation>
<url>knownfolder:{FDD39AD0-238F-46AF-ADB4-6C85480369C7}</url>
<serialized>MBAAAE…. </serialized>
</simpleLocation>
</searchConnectorDescription>
  • <searchConnectorDescriptionList> contains one or more search connectors that map to physical locations included in this library
  • <searchConnectorDescription> contains a <simpleLocation> element that describes one location included in the library
  • <url> defines a URL for this location and it is there for human-readability only, this cannot be used by developers since it is likely to be out of date.
  • <serialized> this is the actual representation (Base64) of a location in a library which is as a serialized ShellLink object

One final note - Applications should never attempt to access or edit Library description files. Instead, applications should always use the Shell programming model or the IShellLibrary API to consume and manipulate Library contents.

In the next post we will dive into the Shell programming model.


Understanding Windows 7 Libraries

This is the second post in a series of posts about Windows 7 Libraries. This post describes some of the rationale that drove Windows 7 Libraries functionality, and explores the new features and opportunities we, as developers, have with Windows 7 Libraries.

What Libraries mean for users in Windows 7?

To better understand the concept of Libraries in Windows 7, we need to look back to the time before Windows 7. Earlier version of Windows like Windows Vista and XP, included sets of special folders for storing user’s content such as “My Documents” and “My Pictures.” In Windows Vista, these special folders where automatically indexed to allow users to perform faster more efficient searches on their content. Even so, many users, me included, store their files, music, and pictures all over the PC in various folders like c:\temp, d:\Birthday2008\pictures, or even in remote storage. We refer to this as storing data outside the user’s profile storage space. This affects the indexing and therefore the entire search experience, and often sends the user on a small quest to try to find their content.

So, in Windows 7, Libraries tries to address the problem of users' content stored all over the PC by allowing users to have full control over their “Documents Library” folder structure. Meaning that in Windows 7, users can define which folders to include in the Documents Library. This is true for any Library. Therefore, we can say that Libraries are user-defined collections of content. By including folders in Libraries, the user is telling Windows where his important data is located. The system will index folders, to enable fast searching and stacking based on file properties.

In Windows 7, users will go to Libraries in order to manage their documents, music, pictures, and other files. As you can see in Windows Explorer and the Common File Dialog, Libraries are an integral part of the Windows Shell. This integration is very important because it enables users to browse their files the same way they would in a folder, which means there is no new behavior to learn. Clicking on the Documents Library shows you your documents. Moreover, due to the fact that libraries are integrated into the Windows Shell, users can perform searches and filter results by properties like date, type, and author in both Windows Explorer and the Common File Dialog. In other words, by using libraries, users get to enjoy storage that is both flexible and indexed. The following image displays the integration of several folders into a single library view and the rich search and pivots  of Windows Explorer in Windows 7.

Win7_libraries

So what is a library?

In many ways, a Library is similar to a folder. As we mentioned before, when users open a Library, they can see one or more files or folders. However, unlike a folder, a Library can display files that are stored in several folders at the same time. This is a subtle, but important, difference. Libraries don't actually store items. They monitor folders that contain a user’s items, and provide a single access point and rich view pivots (by file Type, date or author) of this aggregated content. Libraries promote a user’s data and let the file system fade into the background.

The Windows 7 default Libraries setting has one main Library called “Libraries” that contains four predefined default Libraries: Documents, Music, Pictures, and Videos. Users can save and copy files directly to a library, even if we said that libraries are not file system folders, since every library has a default save location to send these files to. Each library contains two physical file locations, the user's personal folder (this is the default Known Folder that is included in a library, for example, My Documents in the Documents Library), and the public folder For custom categories, the default save location is the first folder added. Users may change the default save location of a library at any point, but if they remove the default save location, the system selects the next folder in the library as the new save location. In addition, users can save to any folder they have permissions to that are included in a library.

For folders to be successfully added to a library, they must be capable of being indexed on the local machine, indexed on a remote Windows machine, or on a server with files indexed by Windows Search. In order to maintain the high standards for the Windows Shell search experience, users can’t add folders that are not indexed into a folder.

What more do developers need to know about Libraries?

After understanding what Libraries are, developers need to understand how they can support and use Libraries in their applications. This is important because by using Libraries, users inform Windows where their important data is. This allows you, as developer, to access a user's Library and consume its contents, removing the need maintain your own set of data storage for your application.

You can also use the new IShellLibrary API to empower your applications to manipulate libraries. This can help ensure that applications remain in sync with user files and Windows since any change made to a library structure will be reflected in the application that is monitoring that library – giving us developers great power and great responsibility.

In the next post, we will cover the underlying architecture of libraries and dive deeper into the API.


Windows 7 Libraries .NET Sample Library – an Overview

Libraries are the primary entry points to user data in Windows 7. They are the natural evolution from the user’s Known Folders, including those for documents, pictures, music, and videos. However, before jumping into the technicalities, let’s try to explain what a Library in Windows 7 is. A Windows 7 Library is a user-defined collection of content that represents the user’s data independently from the folder hierarchy. Users can unify and flatten the folder hierarchy by aggregating any number of physical locations (on their local machine or on remote machines) into a single view – which is the library. By including folders in Libraries, users tell Windows where their important data are located. In Windows 7 therefore, most applications should use a Library instead of the user’s Known Folders. It is important to note that as Libraries are an integral part of the Windows Shell, they play a greater role in the Windows 7 Explorer user experience. Accordingly, the importance and integration points of Libraries span multiple parts of the Windows Shell, including the Common File Dialog, Folder Picker, and the Windows Explorer Browser control (not Internet Explorer!).

This is the first post in a series of Library posts. It provides an overview of both the Windows 7 Library functionality and the Libraries Sample .NET Interop Library, which is a managed code wrapper and part of the Windows 7 .NET Interop Sample Libraries. The second post is all about Understanding Windows 7 Libraries. In future posts, we will dive into the internal implementation of Libraries as well as how to use the Libraries programming model and APIs.

If you are unfamiliar with and haven’t seen any demonstrations of the updated Windows 7 Shell and Libraries in action, I suggest you watch the Windows 7: Find and Organize Part 1 webcast on Channel 9. This will give you some context for the technical material we cover here.

Let’s review the Windows 7 Libraries .NET Interop Sample Library architecture and note the important classes. Please remember that the Libraries sample is part of the Taskbar and Libraries assembly. Since both Taskbar and the Libraries share many common integration points with the Windows Shell, it makes sense to have them grouped together and use the same Shell structures and methods.

Opening the solution reveals the following structure:

  • The Demos folder containing several demo projects that show the various aspects of both the Taskbar and Libraries wrappers as you can see from the image; we will focus on the Libraries
  • The Wrappers folder containing the Windows7.DesktopIntegration assembly, which is the main manager API for both the Taskbar and Libraries
  • A modified version of the Vista Bridge Sample Library - We based our code on the 1.4 version. And as mentioned before, the Windows Vista bridge Project will be superseded by the new Windows API Code Pack for the .NET Library
image

Let’s take a quick look at the main class that enables developers to take advantage of the new Library functionality. The ShellLibrary.cs file contains the ShellLibrary class, which is the main entry point for managed code developers. Using the ShellLibrary, developers can programmatically perform all Library operations, including:

  • Create new library
  • Load existing library
  • Delete library
  • Add / remove folders from the library
  • Set the default save location of the library
  • Set the folder type
  • Show the library management dialog box
  • Set the library icon
  • Pin and unpin the library from the left navigation pan in Windows Explorer

The demos in the Libraries folder highlight all the above-mentioned Library functionality. Let’s review them:

  • The LibraryManagerDemo is a Windows Presentation Foundation (WPF) application that showcases all the functionality offered by libraries. It is a very simple application that offers developers a great opportunity to review all the above-mentioned Libraries functionality.

image

  • The SLUtil (not Silverlight) is a command line interface that allows users and developers to manage their Libraries. Again, it offers all the above-mentioned Libraries functionality.

image

Here are some additional resources for programming Windows 7 Libraries:

View Channel 9 videos:

Additional blog posts

 

Alon Fliess contributed to this post


Windows 7 Taskbar .NET Sample Library – an Overview

One of the first noticeable changes in Windows 7 Desktop is the new Taskbar. The Windows 7 Taskbar post on the E7 blog clearly documents the reasons driving the Windows 7 Taskbar look and feel. The Windows 7 taskbar introduces new functionality that developers need to understand in order for them to take full advantage of it in their own applications and enhance their end users’ experiences. The Windows 7 Taskbar is an application-launching and window-switching mechanism that consolidates the functionalities from previous Windows Desktop mechanisms such as Quick Launch, Recent Documents, Notification area icons, desktop shortcuts, and running application windows.

If you are unfamiliar with and haven’t seen any demonstrations of the Windows 7 Taskbar, please watch the Windows 7 Taskbar Overview webcast on Channel 9. This will give you some context for the technical material we cover here.

This is the first post in a series of Taskbar posts. It provides an overview of both the new Taskbar functionality and the Taskbar and Libraries Sample .NET Interop Library, which is a managed code wrapper and part of the Windows 7 .NET Interop Sample Libraries.

Let’s review the Windows 7 Taskbar and Libraries .NET Interop Sample Library architecture and note the important classes. Opening the solution reveals the following structure:

  • A modified version of the Vista Bridge Sample Library - We based our code on the 1.4 version. And as mentioned before, the Windows Vista bridge Project will be superseded by the new Windows API Code Pack for the .NET Library
  • The Demos folder containing several demo projects that show the various aspects of both the Taskbar and Libraries wrappers as you can see from the image
  • The Wrappers folder containing the Windows7.DesktopIntegration assembly, which is the main manager API for both the Taskbar and Libraries
image

Let’s take a quick look at the main classes that enable developers to take advantage of the new taskbar functionality:

  • The Windows7Taskbar class provides low-level facilities for manipulating the process-wide and window-specific application IDs, controlling custom window preview bitmaps, setting the Taskbar overlay icon and progress bar, and clipping the Taskbar thumbnail
  • The JumpListManager class provides an abstraction of the application’s jump list, including facilities to manipulate custom destinations, user tasks, the Recent and Frequent lists, and items removed by the user
  • The ThumbButtonManager class provides an abstraction of the Taskbar thumbnail toolbar, including the facilities to create thumbnail toolbar buttons and receive notifications when they are clicked
  • The CustomWindowsManager class provides an abstraction of a customized window thumbnail preview and live preview (peek), including the facilities to receive a notification when a preview bitmap is requested by the Desktop Window Manager (DWM), and to automatically grab the preview bitmap of a window

The Taskbar demos showcase all of the above-mentioned Taskbar functionality. Let’s review them:

The MainDemo sample is a simple WinForm application that showcases all the functions that are expose via the API, including building a jump list with custom categories and custom tasks, setting an overlay icon and progress bar, and creating and handling events from Thumbnail Toolbar buttons:

image

In order for the main demo application to run properly, you will need to register this application as a registered handler for text files (*.txt). By registering this application and a handler for text files, you ensure that each time you open a text file directly from Windows Explorer. Windows automatically calls SHAddToRecentDocs on your application's behalf. This inserts the item in the Windows Recent list and eventually into the Jump List Recent Category. The same automatic behavior occurs when using the Windows common file dialog to open files through our applications.

You can register the application from the Administrative tool strip menu.

The DocumentReader sample demonstrates how developers can provide better Taskbar Thumbnail preview experiences for their users by clipping and customizing the Thumbnail Preview.

image

The IMClient sample demonstrates how Taskbar overlay icons and Taskbar progress bars can light up an application’s Taskbar button instead of relying on an additional dialog or on an icon in the system notification area (the tray). It is important to note that in Windows 7, the notification area has undergone a few changes and now shows the least number of icons in order to keep the taskbar clean and reduce the number of balloon notification messages.

image

The last demo, WebBrowser, demonstrates how to customize both the Thumbnail previews and the window preview (AeroPeek), and display internal tabs. As you can see from the following images, we can override the default behavior by flipping the images and adding some text on top of the preview image.

image

 

Here are some additional resources for programming the Windows 7 Taskbar:

Channel 9 videos:

Sasha Goldstein contributed to this blog - http://blogs.microsoft.co.il/blogs/sasha/archive/2009/02/12/windows-7-taskbar-apis.aspx


Windows 7 Sensor and Location .NET Interop Sample Library

The Windows 7 Sensor and Location platform enables your computer and applications to adapt to their current environment and change the way they look, feel, or behave. For example, imagine an application that uses a light sensor and so can change the brightness and contrast of its displayed content based on the differing amounts of indoor and outdoor light. Or an application that uses location sensors and so can know their current location, enabling many different scenarios, such as automatic content localization and location base services.

The Sensor and Location platform provides a standard way to integrate sensor and location devices with Windows 7, and provides a standard programming model for applications to take advantage of these devices. Hardware manufacturers can learn how to write sensor and location drivers by installing the Windows 7 WDK. Developers can learn how to write location-aware and sensor-enabled applications by installing the Windows 7 Beta SDK.

Some may ask, why use the Windows 7 Sensor and Location Platform? To answer that question, we need to understand that most of the applications that we use on a daily basis were designed for “normal” environmental conditions, for example, under indoor standard lighting conditions. However, nowadays laptops offer higher mobility than ever before, allowing us to use them in different locations with different environmental conditions, switching from bright outdoor light into darker indoor light. Wouldn’t it be nice to have an application that adjusts its look, feel, and behavior to the change in the environment? Ambient light sensors, for example, can allow your computer to automatically adjust your screen's brightness based on the current lighting conditions. Furthermore, developers can also enable applications to optimize their content for readability, making your application easier to use in a range of different operating environments.

For example, the following image shows an updated version of the MSDN Reader. This version of the MSDN Reader changes the way the application looks depending upon the amount of light the Ambient Light Sensor detects. On the left is how the application displays under normal indoor light. On the right is how the application displays under outdoor light. On the right, you can see that the application reduces the use of colors to increase contrast and increases the font size, making the displayed content (the actual text displayed) of the application more readable under the brighter lighting conditions. I used the Virtual Light Simulator application that ships with the Windows 7 Beta SDK; you can find it in the Program Files\Microsoft SDKs\Windows\v7.0\Bin\VirtualLightSensor.exe when you install the Windows 7 beta SDK. So you can actually download the sample and install the SDK and try this on your own Windows 7 computer - it is kind of cool. Note that when you launch the Virtual Light Sensor application, you’ll have to go to your computer Device Manager and search for drivers (use the same directory as above) in order to install the unsigned Virtual Light driver. After that, the tool will work.

image

The Windows 7 Beta SDK provides tools, documentation, and examples for writing drivers for sensor devices as well as using the Sensor and Location platform in building Windows 7 applications. As is true for most Windows 7 APIs, the Sensor and Location API is native. There are some examples in the SDK that display managed code applications using a very thin interop layer. However, this Windows 7 Sensor and Location .NET Interop Sample Library offers a broader and more “.NET-like” programming model with strongly typed objects and an easy extensibility model for sensor and data reports.

Let’s review the Windows 7 Sensor and Location .NET Interop Sample Library architecture and note the important classes.

To start working with sensors, you must first obtain one. You can do this using the SensorManager class whose main purpose in life is to expose sensor classes (for example light and accelerometer sensor classes) to the developer. Using the SensorManager, developers can:

  • Get an array of sensors by CategoryID. CategoryID is a GUID that defines a well-known specific class of sensors such as Light Sensors, Accelerometer Sensors, Motion Sensors, or Location. You can find the complete list of well known sensors in the SensorCategories class and in the SDK.
  • Get an array of sensors by TypeID. TypeID is a specific type of a sensor that is related to a specific class of sensors. For example, Type of LocationGPS is part of the Location Sensors class, and Accelerometer3d and Accelerometer2d are related to the Accelerometer Sensors class. You can find the complete list of sensor Types in the SensorCategories class.
image
  • Get a specific Sensor using the sensor's GUID
  • GetAllSensors, which retrieves all the sensors that are in the register. You can use any sensors from that list as long as you have permission to do so. The end user will have to enable each sensor for the application to use.
  • Show the permission dialog box to provide users with a way to enable sensors.
  • Notify the application of a sensor's availability with the SensorAttached event.

Once you have obtained a sensor from the SensorManager, the application can retrieve data using a SensorDataReport class, which is an abstract base class for all DataReports. For a sensor to be useful, it must provide meaningful data. The amount, frequency, and type of data generation vary from sensor to sensor. For example, a sensor that detects whether or not a door is open would generate a small amount of Boolean data, while a motion sensor might continuously generate multiple data items. To standardize the way your program receives data, the native Sensor API uses the sensor data report object.

You can access the information in a sensor data report through the native API that has the ISensorDataReport interface. This interface lets you retrieve the data report’s time stamp so you can determine whether the information in the report is useful. You can retrieve the data itself in two ways: as an individual data field value or as a set of values. To retrieve data as an individual value, call the GetSensorValue method. To retrieve multiple values, call the GetSensorValues method. You specify the type of data, or data fields, you want to retrieve from the report by using a PROPERTYKEY structure. It may be easy for native code developers to use this programming model. However, beside the fact that it is hard to access from managed code, it lacks key features like strong type, since each sensor has different data fields. Therefore, one of our goals is to create a strong typed .NET class for each sensor and for each sensor data report, enabling easy binding to the .NET property system.

The managed code SensorDataReport is the base class for sensor type-tailored data reports (for example, Accelerometer3DReport). When developers implement support for a custom sensor, they usually create a set of two classes: a Sensor-derived class, and a SensorDataReport-derived class. The SensorDataReport provides base methods, such as querying a property by PropertyKey, which are intended to be overridden by type-safe properties in derived classes (for example, AxisY_G - float in Accelerometer3DReport).

The follow diagram illustrates three derived data report classes that we implemented in the Windows 7 Sensor and Location .NET Interop Sample Library. An Accelerometer3DDataReport, an AmbientLightSensorDataReport, and a BooleanSwitchArrayDataReport.

 image

We also implemented a LatLongLocationReport and a CivicAddressLocationReport that you can find under the Location Providers in the Windows 7 Sensor and Location .NET Interop Sample Library.

Let’s examine few lines of code that illustrate the process of reading the amount of light by using the AmbientLightSensor sensor and data report. To do so, a developer will need to:

1. Get an AmbientLightSensor class from the SensorManager

2. Get a data report from the AmbientLightSensor class. Note that GetDataReport returns a generic SensorDataReport

The following code snippet shows how you can obtain a light sensor from the SensorManager and use that light sensor to get an AmbientLightSensorDataReport.

//obtain a light sensor 
AmbientLightSensor[] lightSensors =
SensorManager.GetSensorsByType<AmbientLightSensor>();
if (lightSensors.Length > 0)
{
_lightSensor = lightSensors[0];
_lightSensor.ReportInterval = _lightSensor.MinReportInterval;
}

//use the light sensor to get en AmbientLightSensorDataReport
AmbientLightSensorDataReport lightReport =
(AmbientLightSensorDataReport)_lightSensor.GetDataReport();
//Get the lux value from that date report
_illuminanceLux = lightReport.IlluminanceLux;

Developers can do a lot more with a given sensor then just retrieve a data report. The Sensor base abstract class contains a comprehensive set of properties that provide general info like FriendlyName, SensorDescription, SensorID, SensorSerialNumber, and SensorState. There are also specific properties such as ReportInterval to set the intervals between each time a sensor device generates a report, and MinReportInterval to set the minimum time between reports. In addition, the Sensor class exposes a set of events including DataUpdated that is triggered when a new data report is ready, and OnStateChanged that is triggered when the sensor state has changed. The Sensor class exposes additional properties that you are welcome to explore. The ISensorEventsInternal diagram shows the Sensor class and three derived classes we created for the Sensors and Location Managed Library Sample.

image 

Enabling Sensors

For each installed sensor the end user will have to enable it for use. Users can do so from the Location and Other Sensors located in the Control Panel. Application can also display the same dialog by calling the proper API. The following image shows the sensors I have installed on my dev machine

 image

 

The Sensor and Location Managed Library Sample includes two demos: the MSDN Reader and Marble Sample. The latter is an XNA application that requires you to download the XNA Game Studio 3.0. This demo shows how to use the Accelerometer3D sensors. The MSDN Reader uses the AmbientLightSensor to change the size and color of the fonts in the reader.

In a future post, we will further explore the architecture we chose for the Windows 7 Sensor and Location .NET Interop Sample Library and expand your understanding of how to create your own set of sensors.

Dima Zurbalev contributed to this post.