[PT] (for a English version, see bellow on this page, please)
Olá a todos,
Recentemente num projecto interno nós estávamos a necessitar de utilizar algum tipo de activeX numa página Web, para que fosse possível a importação dos contactos do Outlook, tal como no linkedIn.
Portanto, para quê um activeX quando temos as aplicações XBAP? Hum… parece-me bem. Então aqui fica um pouco da experiência que tivemos no desenvolvimento desta brincadeira. Em primeiro lugar, não esquecer que se a nossa aplicação vai interagir com um dos membros do Microsoft Office, as Visual Tools for Office têm as bibliotecas certas para isto!
Eis os nossos passos:
1) Importação da biblioteca do Outlook para a nossa aplicação:
using Microsoft.Office.Interop.Outlook;
2) Criação dos tipos necessários para a transmissão com o Outlook e leitura dos dados:
private MAPIFolder oContactsFolder = null;
//load outlookcontacts
var oApp = new Microsoft.Office.Interop.Outlook.Application();
NameSpace oNS = oApp.GetNamespace("MAPI");
oContactsFolder = oNS.PickFolder();
string filter = "[MessageClass] = \"IPM.Contact\"";
Items oContactItems = oContactsFolder.Items.Restrict(filter);
foreach (ContactItem oContact in oContactItems)
{
var item = new EmailContact();
if (oContact != null)
{
item.ContactEmail = oContact.Email1Address;
item.ContactName = oContact.FullName;
//before add the email let's see that's is valid
if (ValidateEmailAdd(item.ContactEmail) && !String.IsNullOrEmpty(item.ContactEmail))
{
contactList.Add(item);
}
}
3) Definição da interface e da lógica da aplicação
Para tal escolhemos a XBAP para que nos seja possível aplicar todas as funcionalidades que o WFP nos oferece, mas para tal existem algumas notas importantes a ter em consideração:
- A XBAP deverá correr em modo de “full trust”, e para tal é necessário um certificado digital que assine o código da aplicação, e obviamente o nosso browser deverá confiar no mesmo.
Para tal, criámos um certificado fullsix CA, algo que fomos seguindo aqui:
http://msdn.microsoft.com/en-us/library/aa194055%28office.11%29.aspx
Outro post com informações muito importantes sobre esta parte:
http://blogs.microsoft.co.il/blogs/maxim/archive/2008/03/05/wpf-xbap-as-full-trust-application.aspx
Para a extracção do certificado seguimos:
http://blogs.microsoft.co.il/blogs/maxim/archive/2008/03/31/how-to-run-wpf-xbap-application-in-full-trust-mode-post-2-certificate-extraction.aspx
Para automatizar este processo, desenvolvemos uma pequena aplicação de consola que permite o download e a instalação silenciosa do mesmo. Assim o certificado fullsix CA fica instalado no computador, que assina o certificado que usamos para assinar o código da nossa XBAP application.
Aqui fica o código que usámos:
try
{
var myStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("InstallXBAPOutlookCert.Console.f6signing.cer");
byte[] b = new byte[myStream.Length];
myStream.Read(b, 0, b.Length);
X509Certificate2 cert = new X509Certificate2(b);
X509Store store = new X509Store(StoreName.AuthRoot, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadWrite);
store.Add(cert);
store.Close();
store = new X509Store(StoreName.TrustedPublisher, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadWrite);
store.Add(cert);
store.Close();
System.Console.WriteLine("Certificate Successfully Installed...!");
System.Console.Read();
}
catch (Exception ex)
{
System.Console.WriteLine("Error " + ex.ToString());
}
Não esquecer de embeber o ficheiro de manifesto da aplicação dentro do ficheiro exe da aplicação, isto é necessário para utilizar os direitos de Administrador da máquina, para que seja possível fazer a instalação do certificado. É necessário alterar este manifesto como se segue:
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
E para embeber o manifesto no exe:
O utilizador vê o ficheiro .exe no browser e se no seu caso a empresa possuir um certificado assinado por uma das bem conhecidas CA’s não deverá existir qualquer problema, no nosso caso, os utilizadores deverão confiar no nosso certificado, para que seja possível visualizar a demo correctamente :)
Depois o certificado fullsix CA fica instalado no computador tal como se pode ver abaixo:
Agora a aplicação XBAP está devidamente assinada e é confiada pelo browser e tudo corre em modo full trust.
Nota:
- WPF threading module. É um pouco doloroso entender para quem está mais familiriarizado com o modo de threading do silverlight como é o nosso caso. Em WPF existem algumas diferenças, o que significia que é necessário pensar sobre esta questão para que não se bloqueie a thread da Interface. Imaginando por exemplo uma animação de loading enquando a comunicação com o Outlook é feita. Um bom artigo para ajudar nesta questão:
http://msdn.microsoft.com/en-us/library/ms741870.aspx
Para evitar o bloqueio da thread principal da interface, lançamos o método de interacção com o Outlook noutra thread da seguinte forma:
var myDispatcher = new Thread(new ParameterizedThreadStart(s => { StartRetriveContacts(); }));
Depois no regresso á thread original:
private void StartRetriveContacts()
{ …
UIDispatcher.BeginInvoke(DispatcherPriority.Background, (SendOrPostCallback)delegate { ProcessContacts(contactList); },
contactList);
Usando este tipo de “roteamento” entre as threads permite-nos fazer um update constante na interface de modo a dar feedback constante ao utilizador sobre as operações que decorrem em background.
E pronto :) é isto, podem testar. http://labs.fullsix.pt/projects/xbapoutlookdemo/default.aspx e já agora dar uma vista de olhos nos outros projectos que estão no fullsix Labs.
Queria deixar também uma nota de agradecimento aos meus colegas Antoine e Fiel pela ajuda no desenvolvimento.
Merci.
[EN]
Hi all,
In order for a internal project we need some kind of an activeX in a web page from Outlook contact email addresses importation, such has like linkedIn has.
So why use a activeX when we have XBAP apps? Sweet hum? Here is how we've done the little app. First of all keep in mind this is something to interop with an Microsoft Office application, right? The Visual Tools for Office have the right libraries for it!
Steps:
1) Import the Microsoft Interop Namespace:
using Microsoft.Office.Interop.Outlook;
easy as butter
2) Create the right types to exchange with outlook and load content
private MAPIFolder oContactsFolder = null;
//load outlookcontacts
var oApp = new Microsoft.Office.Interop.Outlook.Application();
NameSpace oNS = oApp.GetNamespace("MAPI");
oContactsFolder = oNS.PickFolder();
string filter = "[MessageClass] = \"IPM.Contact\"";
Items oContactItems = oContactsFolder.Items.Restrict(filter);
foreach (ContactItem oContact in oContactItems)
{
var item = new EmailContact();
if (oContact != null)
{
item.ContactEmail = oContact.Email1Address;
item.ContactName = oContact.FullName;
//before add the email let's see that's is valid
if (ValidateEmailAdd(item.ContactEmail) && !String.IsNullOrEmpty(item.ContactEmail))
{
contactList.Add(item);
}
}
3) Define your UI and the rest of the behaviors
We choose a XBAP application in order to have the WPF capabilities in a regular web page but you must be aware of some important settings:
- XBAP app needs to run in a full trust mode, so that requires a DigitalCertificate to sign your code and the browser needs to trust on that.
So we created a fullsix CA certificate. Something that follows here:
http://msdn.microsoft.com/en-us/library/aa194055%28office.11%29.aspx
You can see a quite nice post’s about this at:
http://blogs.microsoft.co.il/blogs/maxim/archive/2008/03/05/wpf-xbap-as-full-trust-application.aspx
and for the certificate extraction
http://blogs.microsoft.co.il/blogs/maxim/archive/2008/03/31/how-to-run-wpf-xbap-application-in-full-trust-mode-post-2-certificate-extraction.aspx
to automate this process we develop a simple console application that you download first and installs on your computer our fullsix CA certificate, that signs the code sign certificate that we use previously to sign the xbap code.
Here is the code for that:
try
{
var myStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("InstallXBAPOutlookCert.Console.f6signing.cer");
byte[] b = new byte[myStream.Length];
myStream.Read(b, 0, b.Length);
X509Certificate2 cert = new X509Certificate2(b);
X509Store store = new X509Store(StoreName.AuthRoot, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadWrite);
store.Add(cert);
store.Close();
store = new X509Store(StoreName.TrustedPublisher, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadWrite);
store.Add(cert);
store.Close();
System.Console.WriteLine("Certificate Successfully Installed...!");
System.Console.Read();
}
catch (Exception ex)
{
System.Console.WriteLine("Error " + ex.ToString());
}
Don’t forget to embed the application manifest in the exe file, you need that for auto Admin rights permissions to install :) like this in your manifest file:
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
and to embed it on the exe:
The user see’s the .exe on the browser and if your company has a certificate that’s signed by one of very well known CA you should haven’t any trouble. In this case our users must have trust on us :)
then you have the fullsix CA in your machine as you can see here:
So now XBAP application is signed and User grant a full trust environment for it.
Note:
- WPF threading module. It’s some kind of “pain”, for those who are more familiar with Silverlight like me, in WPF there are some differences, which means that you have to think about threading block handling, in order to avoid frozen the main UI thread, that can being display, for example, a loading animation of the contact import progress. for that there are also a nice article:
http://msdn.microsoft.com/en-us/library/ms741870.aspx
To avoid the main UI thread block we launched the Outlook interop method in another thread, here’s the way:
var myDispatcher = new Thread(new ParameterizedThreadStart(s => { StartRetriveContacts(); }));
then to get back on the main UI:
private void StartRetriveContacts()
{ …
UIDispatcher.BeginInvoke(DispatcherPriority.Background, (SendOrPostCallback)delegate { ProcessContacts(contactList); },
contactList);
Using this kind of “routed threading model” we were able to provide an UI update with some animation and application update state.
And that’s it..! you can try for your self
http://labs.fullsix.pt/projects/xbapoutlookdemo/default.aspx , and take a look into our others fullsix labs projects.
Also a thanks to Antoine and Fiel for their help on this development.
Posted
11-06-2009 0:50
by
Gonçalo Chaves