XML Literals: Creating an XML File

One of my favorite features in VB 9 (Visual Studio 2008) is XML Literals. This example demonstrates how insanely easy it is to build an XML file using VB.

This code builds xml from a list of customers.

Dim customerXml As XElement = _
<customers>
   <%= From c In customerList _
       Select <customer>
                 <LastName><%= c.LastName %></LastName>
                 <FirstName><%= c.FirstName %></FirstName>
              </customer> %>
</customers>
customerXml.Save("customers.xml")

This code starts with the customers root node. It then builds a customer node for each customer found in the list.

The resulting XML:

<customers>
  <customer>
    <LastName>Baggins</LastName>
    <FirstName>Billbo</FirstName>
  </customer>
  <customer>
    <LastName>Baggins</LastName>
    <FirstName>Frodo</FirstName>
  </customer>
  <customer>
    <LastName>Kurata</LastName>
    <FirstName>Deborah</FirstName>
  </customer>
</customers>

Enjoy!

Posted by Deborah Kurata | with no comments
Filed under: , , ,

Lambda Expressions: Finding Differences in Two Lists

One of my favorite features in .NET 3.5 is lambda expressions. This example demonstrates how to use lambda expressions:

  • To compare items in two lists and find which items in one list are not in the other. For example: {1, 2, 3}, {2, 3, 4}. {1} is only in the first list.
  • To display the contents of the resulting set.

First, define two lists:

List<int> list1 = new List<int>() { 1, 6, 8 };
List<int> list2 = new List<int>() { 2, 6 };

The following lambda expression finds all of the items that are only in the first list:

Func<IEnumerable<int>> exceptionFunction = () => list1.Except(list2);

This is a Func delegate which returns an IEnumerable<int>. There are no arguments passed into the function, hence the empty parenthesis (). The => is the lambda operator. The remaining code uses the Except method of the list to find the items not in the second list.

The following lambda expression displays the resulting items:

Action displayList =
    () => exceptionFunction().ToList().ForEach(i => Debug.WriteLine(i));

This one is an Action delegate that takes no parameters. It first takes the IEnumerable result from the exceptionFunction, converts it to a list, then writes each item to the Debug window.

Call the displayList method to try this out:

displayList(); // Result 1,8

Calling displayList calls exceptionFunction which operates on the two lists. This will display 1 and 8 to the Debug window.

You can then change the list and see the new results:

list2 = new List<int>() { 1, 4 };
displayList();  // Result = 6, 8

Since the code in the lambda expressions is not executed until it is called, this call to displayList recognizes the current values of the lists. So you get new results.

You can change the other list and see the new results:

list1 = new List<int>() { 3, 4, 9 };
displayList();  // Result = 3, 9

Enjoy!

Posted by Deborah Kurata | with no comments
Filed under: , , ,

Google has screwed up yet again

So I go to do my favourite technical question method which involves searching just the microsoft.public.access newsgroups and it totally fails.  Worked just fine a few days ago.

Start at groups.google.com and enter your search term.  For example "access books vba" but without the double quotes.  

Now if you just click on Search Groups you get many, many useless, duplicate hits.   The problem is that there are many web sites out there mirroring the NNTP Usenet and Microsoft newsgroups.   All so they can sell Google advertising.  

I should note that there are a few genuine online forums such as Utter Access and, think, the Access World forums.   However the vast majority are bottom feeding, scum suckers whose only interest is advertising revenue.

So as to limit the search just to the Microsoft newsgroups I would then click on Advanced Search go down to the Group name field and enter microsoft.public.access.*  

And that doesn't find any hits.  I *KNOW* a few days ago this worked just fine. 

So Google has screwed up the NNTP newsgroup search interface yet again.    Ahh, for the good old days of dejanews.com and deja.com.    They did only one thing and did it well.

Posted by Tony | with no comments
Filed under:

Renewed as an MVP

I found out yesterday that I was renewed as a Microsoft MVP for another year!  I look forward to tweeting, blogging, and writing about Microsoft .NET technologies.  You can connect to me with the following:

Twitter: @brianmains
Linked In: http://www.linkedin.com/in/brianmains 

Posted by bmains | with no comments

What Data Access Model Do You Use For Your App? Take This Poll!

I created a TWTPOLL for this very question.  Please submit your opinion:  http://twtpoll.com/2oqm0o.  Thanks for your participation in advance.

Posted by bmains | with no comments
Filed under:

Operation FACEBOOK is on right NOW!

http://www.facebook.com/pages/Windows-Small-Business-Server/88799484644

Okay troops.  We have a mission.  Click on that link.  If you aren't a facebook person, become one.  Now.  As we have a mission to get SBS a vanity url "fan" page faster than EBS 2008 did.  We need 100 "fans" as soon as possible.

http://www.facebook.com/pages/Windows-Small-Business-Server/88799484644

So click on that link and become a fan and lets get to 100 faster than EBS did.  The race is on.  On your marks, get ready,  GO!

So step one Operation FACEBOOK is on right NOW! 

Stay tuned for the SBS twitter feed next.....

..yeah yeah Susan blogging about twitter... what is the world coming to?

Posted by bradley | 3 comment(s)
Filed under:

Welcome to Deborah’s Developer MindScape

So many things to think about, so little time.

Deciding to be a developer with .NET is deciding to be a life-learner. There is no one manageable set of things to learn and then you are done. Rather, you spend every day learning new, better, more efficient ways to accomplish your task.

I love to code. I love to learn.

So I finally decided to start blogging about these things I am learning and share the things I know with others.

Enjoy!

Posted by Deborah Kurata | 2 comment(s)
Filed under: , , , ,

When Good Tools Go Bad

Think the "cloud" is the end-all and be-all of computing? It's got a long way to go, baby, and I've had a front-row seat for just how bad things can get. A certain vendor (who will remain nameless so don't bother asking) that we work with through my primary business has had an on-line order processing system that went live a couple of years ago and seriously streamlined not only the ordering process but really enhanced our entire relationship with them. Absolutely godsend, actually. Well, two years into this system, the vendor decided to update their partner portal, and it's been hell ever since. First, the portal was updated and locked me out before I got an e-mail saying that an updated portal was even in the works, much less going live. Second, after getting access to the new portal, the ordering system (which is apparently still running the old code) started glitching and some orders were lost and others couldn't be generated. The time involved in going from quote to order to delivery is now longer than it was before the on-line portal solution was implemented, because I'm having to see if the portal is working for a particular order to know if I can still use the portal (frustratingly, it does work occasionally, meaning I can't just give up on it totally) and then contact the vendor to go through the process manually.

Guess what... people can still write bad code, even if its in the cloud.

Now I'm not pooh-poohing the notion that cloud services are here to stay. I regularly use and even host several cloud services. But I also understand that just because its in the cloud doesn't make it infallible. If someone uses a desktop application and hears that the update to that application has problems, they have the option of not updating until the application is fixed. For cloud-based services, that luxury is gone.

Know what you're getting yourself into and be prepared for the good AND the bad. Life isn't all rosy on premise, but there's not always a silver lining in the cloud, either.

Posted by eriq | with no comments

¿/Savecred, /Savedcred, /Savedcreds...? Es lo mismo

Como quizá sepa, el comando Runas.exe de Windows XP y Windows Server 2003 sirve para ejecutar procesos en el contexto de otra cuenta de usuario. Los usuarios domésticos normalmente lo usan para ejecutar un proceso como administrador desde una cuenta limitada. Echando un vistazo al listado de parámetros de Runas.exe nos encontramos con uno que suele llamar la atención de bastante gente. Sirve para almacenar temporalmente en el administrador de credenciales (Credential Manager) el usuario y contraseña que va a ejecutar el programa. El atractivo de este parámetro es que no tendremos que introducir el nombre de usuario y contraseña para ese programa durante la sesión en curso. Sin embargo, no hay unanimidad con respecto al nombre del parámetro (incluso la propia documentación del sistema operativo creo que presenta alguna inconsistencia al respecto): Unos lo llaman /savecred, otros /savedcred, otros /savedcreds... Incluso en algunos sitios se indica que tienen semántica diferente.

Nada más lejos de la realidad. Runas.exe solo entiende el parámetro /sa (que contiene el mínimo número de letras que diferencian /savecred de los parámetros /smartcard y /showtrustlevels); lo que venga después le es indiferente. Del mismo modo, en cuanto se encuentra con /p supone el parámetro /profile; si se encuentra con /e supone /env, y así sucesivamente.

Nota: Por limitaciones del administrador de credenciales de XP Home Edition, el parámetro /savecred no es tenido en cuenta en esta versión de Windows. Este artículo no es aplicable tampoco a Windows Vista, pues el comando Runas.exe en Windows Vista es bastante diferente del de XP y será tema de un próximo artículo.

Posted by dmartin | with no comments
Filed under: ,

Code de Webcast de Flujo de Trabajo con InfoPath

Damas y caballeros aquí les dejo el proyecto de código de Visual Studio 2008 que generé durante el WebCast de Construccion de Flujos de Trabajo con Formularios InfoPath 2007. Espero les sirva y muchas gracias por haberme seguido todos hasta el final.

Saludos.

SCOM 2007 R2: Documentação do produto

Um recurso que eu utilizo muito é a documentação online dos produtos que fazem parte da família System Center, mas como nem sempre é possível estar online eu também mantenho a documentação off-line para consulta. Uma ótima opção para baixar os documentos do SCOM 2007 R2 é a seguinte:

 

Link principal: http://www.microsoft.com/downloads/info.aspx?na=40&p=1&SrcDisplayLang=en&SrcCategoryId=&SrcFamilyId=93ddf25b-1ef0-4851-81b0-5fb9a2f76181&u=http%3a%2f%2ftechnet.microsoft.com%2fen-us%2fopsmgr%2fbb498235.aspx

 

Abraços,

 

Cleber Marques

Microsoft Most Valuable Professional (MVP)
Projeto MOF Brasil: Simplificando o Gerenciamento de Serviços de TI
www.mof.com.br | www.clebermarques.com | www.clebermarques.com.br

Posted by Cleber Marques | 2 comment(s)
Filed under: ,

Multithreading: when interlocked operations aren’t enough

In the previous post, we’ve started looking at interlocked operations. As we’ve seen, interlocked operations are great at what they do but they won’t be usable in all scenarios (ie, don’t think that they’ll solve all your locks problems). To show how things might go awry when using interlocks, I’ll reuse a great example written by Raymond Chen a few years ago (I’m updating it to C#):

class Program 
{
  private static Object _lock = new Object();
  public static Int64 InterlockedMultiply(
ref Int64 multiplicand, Int64 multiplier) { Int64 result = 0; lock (_lock) { var aux = multiplicand; Thread.Sleep(100);//oops!!! result = multiplicand = aux * multiplier; } return result; } static void Main(string[] args) { Int64 a = 5; new Thread(
() => InterlockedMultiply(
ref a, 5)).Start(); new Thread(() => {
Thread.Sleep(50);
Interlocked.Increment(ref a); }).Start(); Thread.Sleep(2000); Console.WriteLine(a); } }

The idea is to add a safe multiplier method. As we’ve seen in the previous post, interlocked increments are atomic. That means that they’re executed as a “single” operation by the processor. Since we didn’t had a method that performs the same operation for multiplication, we’ve decided to mimic that behavior by adding a new method which uses a lock to ensure proper multiplication.

If I asked you what Console.WriteLine(a) would print, what would you say? For now, forget those nasty Sleep invocations (they’re there to force the wrong behavior)… I’m guessing that you’d probably say that Console.WriteLine will only write 26 or 30. It will write 26 if InterlockedMultiply “beats” Increment or 30 if Increment is run before InterlockedMultiply. Ah, well, with those nasty sleep instructions, I’ve managed to get 25 here on my machine. Wtf? How? Why?

Well, what happened is logical…Interlocked.Increment will always update the value in a single atomic operation (this means it will load, update and then store the value in a “single” step). However, InterlockedMultiply only ensures that the code wrapped by the lock will only be executed by a thread at a time. Look at that method carefully…can you see a load followed by a store? Those two operations aren’t performed atomically like the one you get through the Interlocked.Increment method!

There is a solution to this problem, but it involves looping until you get a valid result. Take a look at the method updated to work correctly:

public static Int64 InterlockedMultiply(
ref Int64 multiplicand, Int64 multiplier) { Int64 result = 0; Int64 aux = 0; do { aux = multiplicand; result = aux * multiplier; } while ( Interlocked.CompareExchange(
ref multiplicand, result, aux) != aux); return result; }

As you can see, we’re using the Interlocked.CompareExchange method to ensure that multiplicand will only be updated if it hasn’t changed during the  execution of that loop. That happens because the Interlocked.CompareExchange method will always return the value that was stored in multiplicand at the time of the call (recall that CompareExchange always returns the original value of the 1st parameter passed to the method at the time of the call).

As you can see, interlocked operations don’t ensure proper serialization of your code. They only guarantee that the interlocked operation is done atomically. And I guess that’s all for now. Keep tuned for more on multithreading.

Posted by luisabreu | 1 comment(s)
Filed under: ,

System Center no TechNet Brasil

Amigos, existem algumas pessoas que não conseguem fazer download dos vídeos de SCCM 2007 que eu publiquei no Megaupload, por algum motivo que eu desconheço. Porém agora os vídeos também estão disponíveis no site do TechNet Brasil, começando pelos vídeos de SCCM e futuramente os de SCOM e assim por diante. O link é:

 

http://technet.microsoft.com/pt-br/dd560812.aspx

 

A idéia é sempre tornar o acesso de vocês o mais simples possível, aguardem que em breve teremos mais novidades e mudanças J

 

Abraços,

 

Cleber Marques

Microsoft Most Valuable Professional (MVP)
Projeto MOF Brasil: Simplificando o Gerenciamento de Serviços de TI
www.mof.com.br | www.clebermarques.com | www.clebermarques.com.br

Posted by Cleber Marques | with no comments
Filed under: ,

Pergunta: Qual a diferença entre o SCCM e o SCOM?

Ao responder um e-mail que recebi estes dias eu achei interessante compartilhar com vocês visitantes do blog a resposta, a pergunta foi algo simples, mas que sempre deixa algumas pessoas na dúvida, e isso é normal para todos nós, não se preocupem J. Me perguntaram o seguinte: Qual é a diferença entre SCOM e SCCM? E a resposta foi simplesmente uma lista com as principais funcionalidades de cada ferramenta:

 

System Center Configuration Manager (SCCM) 2007

·         Realiza inventário de Hardware e Software

·         Distribui aplicativos para os computadores da rede (Office, Antivírus, etc)

·         Implementa sistemas operacionais de forma semi-assistida ou automatizada

·         Distribui atualizações de software

·         Controle as alterações de hardware e software nos computadores da rede

·         E muito mais...

 

System Center Operations Manager (SCOM) 2007

·         Monitora a saúde dos computadores na rede (desempenho e utilização)

·         Oferece controle dos serviços de TI com base na relação entre seus componentes

·         Monitora dispositivos como roteador, switch entre outros

·         Centraliza logs de segurança para auditoria

·         Monitora web sites com base em testes definidos pelo administrador

·         Oferece relatórios para tomada de decisão

·         E muito mais.

 

Por mais simples que possam parecer nossas dúvidas é sempre importante não deixarmos de perguntar, pois estamos aqui pra aprender.

 

Abraços,

 

Cleber Marques

Microsoft Most Valuable Professional (MVP)
Projeto MOF Brasil: Simplificando o Gerenciamento de Serviços de TI
www.mof.com.br | www.clebermarques.com | www.clebermarques.com.br

Posted by Cleber Marques | with no comments
Filed under: , ,

Get the SharePoint version programmatically

This post is about a question that many developers ask themselves, ¿how can I get the SharePoint version programmatically?

There are at least  three possible ways to do this (that I'm aware of):

In my case, I'm always using  WMI and Windows provides us with the right tool (WBEMTEST.EXE) to try our  WQL queries

Regards,

Angel

Posted by AngelHernandez | with no comments

Multithreading: introducing the interlocked operations

As we’ve seen in the previous post, most processors give us important insurances regarding memory loads and stores. However, even though those insurances are important and can be used in several scenarios, the truth is that they aren’t enough for all real world tasks.

Fortunately, most processors also offer a group of interlocked operations which enable atomic compare and swap scenarios. These operations rely on hardware and interprocess synchronization. Notice that these operations aren’t as simply as they might seem at first sight. For instance, it’s important to recall that in today’s architectures, these kind of operations need to play well with caches. My point is that event though these operations tend to be cheaper that the traditional locks, they’re still not cheap (for instance, there are cases where an interlocked operation ends up locking the bus and that is not a good thing).

Currently, there are several kinds of interlocked operations. In .NET, all interlocked operations are exposed as members of the Interlocked class:

  • Add: adds two integers (int or long) and replaces the first with the value of the sum;
  • CompareAndExchange: compares two values and if they’re equal, replaces one of them with the other (notice that this method receives three parameters). This is probably the most important method of this class (it supports compares and exchanges on reference types two!);
  • Decrement: Similar to add, but in this case, it performs a subtraction;
  • Exchange: updates a variable with another value;
  • Increment: adds one to an existing variable;
  • Read: reads a value from a variable;

As I’ve said before, the advantage of using these methods is that all the operations are performed atomically. The Read method might not seen necessary at first until you look at its signature:

public static long Read(ref long location);

As you can see, it should only be used in 32 bits system when you need to access 64 bits integers. Atomically setting a value on 64 bits can be done through the Exchange method:

public static extern long Exchange(ref long location1, long value);

This means that you can easily build a generic write or read routine and reuse them across your programs:

public static class Generic64Helper {
  private const int WordSize32 = 4;
  public static void WriteLong(ref long location, long value) {
    if (IntPtr.Size == WordSize32) {
        Interlocked.Exchange(ref location, value);
    } else {
        location = value;
    }
  }
  public static long ReadLong(ref long location) {
    if (IntPtr.Size == WordSize32) {
        return Interlocked.Read(ref location);
    }
    return location;
  }
}

There a couple of interesting things going on here. First, we use the IntPtr.Size property to get the size of the “current” word. In 64 bits, we really don’t want to pay the price of the Interlocked operation and will simply delegate to a hardware atomic write or read. However, in 32 bits system (where the word size is 4), we really need to use those methods to have atomicity. Reusing this class is rather simple, as you can see from the next snippet (t is initialized with 10 and y is initialized with the value of t):

Generic64Helper.WriteLong(ref t, 10);
long y = Generic64Helper.ReadLong(ref t);

There a couple of gotchas with the previous approach (notice that only the read and write are atomics), but we’ll leave that for a future post. Now, the important thing is to concentrate on introducing most of these methods. If you use reflector, you should see that Interlocked.Read depends directly on the CompareExchange method:

public static long Read(ref long location) {
  return CompareExchange(ref location, 0L, 0L);
}

This is really a cool trick!

As I’ve said before, the CompareExchange method is one of the most important methods exposed by the class. The CompareExchange method receives three parameters: if the first and third parameters are equal, then it updates the first with the value of the second parameter. The method will always return the initial value of the first parameter (even when there’s no update).

So, the code used on the Read method will only end up doing a write (ie, a store) if the current stored value is 0. And even when this happens, there really isn’t any update in the value (notice that if its value is 0 we’re writing 0 again!).

The remaining methods exposed by the class are fairly obvious, so I won’t really go into examples here (the docs do a good job on showing how to use these methods). The important thing to take from this post is that these operations are atomic and are performed at the hardware level. On the next post, we’ll keep talking about this class and on how you can reuse them to add some free lock programming to your apps. Keep tuned!

Posted by luisabreu | 3 comment(s)
Filed under: ,

Determinando el número de versión de SharePoint programáticamente

Este post trata de una pregunta que muchos desarrolladores se hacen, ¿cómo determino la versión de SharePoint que tengo instalada por medio de código?

A continuación enumero las tres posibles maneras (que yo conozco para hacerlo):

En mi caso particular, siempre hago uso de WMI y Windows nos ofrece WBEMTEST.EXE para probar nuestras consultas WQL

Saludos,

Angel

Posted by AngelHernandez | with no comments

Antigen and Forefront for Exchange with SP2

Microsoft has just released new versions of its security products for Exchange Server.

The service packs introduce technology that will notify customers of engine changes – including the addition or elimination of engines – and allow administrators to update their engine configurations without having to deploy any new product updates. This update allows customers to accommodate engine changes effortlessly, helping maintain the high level of security provided in the Forefront server security products.
As an example of Microsoft’s commitment to continual improvement of our malware detection leadership, we are investing in new antispam technology through a partnership with
Cloudmark that will provide an overall better antispam experience including higher detection rates, lower false positives, and improved submission and service experience. The Cloudmark engine is now included in latest service pack releases of Antigen for Exchange with Antigen Spam Manager 9.0 and Antigen for SMTP Gateways with Antigen Spam Manager 9.0 products as Beta while it undergoes customer trials.

Related Links:

Posted by Rui Silva | with no comments
Filed under: ,

Microsoft Security Bulletin Major Revisions

Issued: July 1, 2009

Summary

The following bulletins have undergone a major revision increment.
Please see the appropriate bulletin for more details.

* MS03-011
* MS02-069
* MS02-052
* MS02-013
* MS00-081
* MS00-075
* MS00-059
* MS00-011
* MS99-045
* MS99-031

Bulletin Information:

* MS03-011

- http://www.microsoft.com/technet/security/bulletin/ms03-011.mspx
- Reason for Revision: V2.0 (July 1, 2009): Removed download
information because Microsoft Java Virtual Machine is no
longer available for distribution from Microsoft. For more
information, see Patch availability.
- Originally posted:
- Updated: July 1, 2009
- Bulletin Severity Rating: Critical
- Version: 2.0

* MS02-069

- http://www.microsoft.com/technet/security/bulletin/ms02-069.mspx
- Reason for Revision: V2.0 (July 1, 2009): Removed download
information because Microsoft Java Virtual Machine is no
longer available for distribution from Microsoft. For more
information, see Patch availability.
- Originally posted:
- Updated: July 1, 2009
- Bulletin Severity Rating: Critical
- Version: 2.0

* MS02-052

- http://www.microsoft.com/technet/security/bulletin/ms02-052.mspx
- Reason for Revision: V2.0 (July 1, 2009): Removed download
information because Microsoft Java Virtual Machine is no
longer available for distribution from Microsoft. For more
information, see Patch availability.
- Originally posted:
- Updated: July 1, 2009
- Bulletin Severity Rating: Critical
- Version: 2.0

* MS02-013

- http://www.microsoft.com/technet/security/bulletin/ms02-013.mspx
- Reason for Revision: V3.0 (July 1, 2009): Removed download
information because Microsoft Java Virtual Machine is no
longer available for distribution from Microsoft. For more
information, see Patch availability.
- Originally posted:
- Updated: July 1, 2009
- Bulletin Severity Rating: Critical
- Version: 3.0

* (MS00-081)

- http://www.microsoft.com/technet/security/bulletin/ms00-081.mspx
- Reason for Revision: V2.0 (July 1, 2009): Removed download
information because Microsoft Java Virtual Machine is no
longer available for distribution from Microsoft. For more
information, see Patch availability.
- Originally posted:
- Updated: July 1, 2009
- Bulletin Severity Rating:
- Version: 2.0

* (MS00-075)

- http://www.microsoft.com/technet/security/bulletin/ms00-075.mspx
- Reason for Revision: V2.0 (July 1, 2009): Removed download
information because Microsoft Java Virtual Machine is no
longer available for distribution from Microsoft. For more
information, see Patch availability.
- Originally posted:
- Updated: July 1, 2009
- Bulletin Severity Rating:
- Version: 2.0

* (MS00-059)

- http://www.microsoft.com/technet/security/bulletin/ms00-059.mspx
- Reason for Revision: V2.0 (July 1, 2009): Removed download
information because Microsoft Java Virtual Machine is no
longer available for distribution from Microsoft. For more
information, see Patch availability.
- Originally posted:
- Updated: July 1, 2009
- Bulletin Severity Rating:
- Version: 2.0

* (MS00-011)

- http://www.microsoft.com/technet/security/bulletin/ms00-011.mspx
- Reason for Revision: V3.0 (July 1, 2009): Removed download
information because Microsoft Java Virtual Machine is no
longer available for distribution from Microsoft. For more
information, see Patch Availability.
- Originally posted:
- Updated: July 1, 2009
- Bulletin Severity Rating:
- Version: 3.0

* (MS99-045)

- http://www.microsoft.com/technet/security/bulletin/ms99-045.mspx
- Reason for Revision: V3.0 (July 1, 2009): Removed download
information because Microsoft Java Virtual Machine is no
longer available for distribution from Microsoft. For more
information, see Patch Availability.
- Originally posted:
- Updated: July 1, 2009
- Bulletin Severity Rating:
- Version: 3.0

* (MS99-031)

- http://www.microsoft.com/technet/security/bulletin/ms99-031.mspx
- Reason for Revision: V3.0 (July 1, 2009): Removed download
information because Microsoft Java Virtual Machine is no
longer available for distribution from Microsoft. For more
information, see New Version Availability.
- Originally posted:
- Updated: July 1, 2009
- Bulletin Severity Rating:
- Version: 3.0

Posted by Don | with no comments

Windows 7 Sensor and Location platform: Implementation of own sensor (Part 3/3)

Windows 7 +1Recently I have told about use Sensor and Location platform in the applications. We have seen, that use of this component set can be very convenient for the application and do not demand many efforts. Also we have an opportunity to work with set of devices in the unified style. Problem of use of this platform there is a presence of drivers for Windows 7 and presence of wrappers for Sensor API. Development of the driver for the device - a task of the manufacturer. And implementation of support in Sensor API can be made own forces.

As I already spoke an entry point is SensorManager class . By means of this class it is possible to get access to the necessary sensor controls and to work with them. This class has methods of getting of the list of all sensors, sensor getting by ID or on type, request to sensor use, and also event of change of quantity of sensors in system.

SensorManager

Each sensor has two main types of identifiers - SensorId and TypeId. TypeId identifies a separate class of devices. For example, by it it is possible to get all sensors of light in system, or any other types of devices. SensorId it is given it is unique to each device. For example, if in system three same sensors of movements everyone will have the unique identifier. Is also CategoryId which unites sensors in a category.

Each identifier represents GUID. They are set by manufacturers by developing of the device and drivers. Thus, it is possible to get a concrete sensor only knowing it ID. Each sensor is presented by Sensor class. It has the general information about a sensor and methods which data from the generalised collections in not typified kind allow to obtain. It is clear, that such data presentation is not so convenient for our applications. Therefore for each sensor it is accepted to implement a class-wrapper within Sensor API. It is implemented by inheritance from general class Sensor. In demonstration examples already there are two such realisations - for 3D accelerometer and for light sensor. However, at the device which we considered earlier there are also touch buttons which also can be used. Therefore let's implement such class for this sensor.

We will define a new class which will be the inheritor of Sensor class. That it was recognised in Sensor API it it is necessary to mark with SensorDescription attribute in which to specify TypeId for this type of sensors. In base class Sensor there are two important things for us - DataReport property and DataReportChanged event. This property contains data from a sensor, and event fires at their change. The task of our class - to take advantage of these data and to deliver to their user of our class in a convenient kind. For this purpose we will create one more small class which will be engaged in analysis of the information from DataReport.

Experimental by we will find out, that by pressing of the button 1 the code 1 is generated, by pressing 2 - the code 2 is generated, by pressing 3 - the code 4 is generated, and by pressing 4 - the code 8 is generated. It is visible, that binary bits here are used. Also the code 0 in a case unpress of all buttons is generated. Thus, we can write the following code.

[SensorDescription("545C8BA5-B143-4545-868F-CA7FD986B4F6")]
public class SwitchArraySensor : Sensor
{
    public class SwitchArraySensorData
    {
        private static Guid KeyStateProperyId = new Guid(@"38564a7c-f2f2-49bb-9b2b-ba60f66a58df");
 
        public SwitchArraySensorData(SensorReport report)
        {
            uint state = (uint) report.Values[KeyStateProperyId][0];
            Button1Pressed = (state & 0x01) != 0;
            Button2Pressed = (state & 0x02) != 0;
            Button3Pressed = (state & 0x04) != 0;
            Button4Pressed = (state & 0x08) != 0;
        }
 
        public bool Button1Pressed { get; private set; }
        public bool Button2Pressed { get; private set; }
        public bool Button3Pressed { get; private set; }
        public bool Button4Pressed { get; private set; }
    }
 
    public SwitchArraySensorData Current
    {
        get { return new SwitchArraySensorData(DataReport); }
    }
 
    public event EventHandler StateChanged;
 
    public SwitchArraySensor()
    {
        DataReportChanged += SwitchArraySensor_DataReportChanged;
    }
 
    void SwitchArraySensor_DataReportChanged(Sensor sender, EventArgs e)
    {
        if (StateChanged != null)
        {
            StateChanged.Invoke(sender, e);
        }
    }
}

Actually, this class is a wrapper in Sensor API for the sensor necessary to us. For its use I should subscribe for StateChanged event and receive the information through Current property.

For getting of the list of accessible sensor of the some type it is possible to use GetSensorsByTypeId method of SensorManager class. Thus TypeId these sensor it will be defined on the basis of set SensorDescription attribute. Now, using these sensors we can subscribe on necessary event and obtain data in a kind convenient for the application. For example, we can display on the form a state of pressing of buttons.

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    var sensors = SensorManager.GetSensorsByTypeId<SwitchArraySensor>();
    foreach (SwitchArraySensor sensor in sensors)
    {
        switch (sensor.FriendlyName)
        {
            case "Left Switch Array Sensor":