Archivi categoria: windows

Integrating Twitter with Universal Windows Platform

Twitter is my favorite social network. It is useful both for work and for fun: I read twitter often and post some tweets, too.

In this post we’re going to see how to read information from Twitter about the logged user and how to interact with the Twitter API with a Universal Windows App (UWP). Because we’re lazy we’re going to use the Linq2Twitter library available on GitHub to make our life easier.

Configuring

The first step to start our work is registering the app in the Twitter Developer Portal.

clip_image002

Without this step we cannot access the Twitter API. In order to register our app we need a Twitter account.

With our twitter account set-up we can go to https://apps.twitter.com/ where we register our app by clicking on “Create New App”.

clip_image004

After that, registering the application is as easy as compiling this form

clip_image006

Name: the name of our application.
Description: a simple description of what our app can do.
Website: the reference website for our app.
Callback URL: the return address after a successful authentication. We do not need this in our example because we’re doing a UWP app.

At the end we agree with the “Developer Agreement” and click on “Create your Twitter application”.

If the process completes successfully we can manage our application settings in a page that looks like this (my app is called Buongiorno):

clip_image008

To make valid calls to Twitter API we need to use the Consumer Key (API Key) and the API Secret key. You can read the Consumer Key under the Application Settings section. To read the API Secret we need to click on “manage keys and access tokens”.

clip_image010

In this page we can read both API Key and Secret. We need to keep in mind that these values are sensitive information and not to publicize them because other (malicious) developers can impersonate our application and do harmful things.

Now we’re finished with the Twitter website and we can go to write code!

Coding

We open a new UWP project with Visual Studio.

clip_image012

We can give any name and then Visual Studio prepares for us a blank app.

The next thing to do is to import the Linq2Twitter library available as a NuGet package. Right-click on the project in the Solution Explorer and click Manage NuGet Packages.

clip_image013

Next we search for “Linq2Twitter” in the browse section and download the package with the download arrow icon on the right.

clip_image015

Visual Studio will prompt us to Accept licenses and dependencies. We click Accept and move on. The NuGet system will take care of all the download process and at the end we’ll be ready to use the library without any other click.

In the MainPage.xaml we make some basic UI to trigger the Linq2Twitter library and display the logged user timeline.

Our goals are:

· Retrieve user timeline

· Post a tweet.

clip_image017

The XAML code to achieve this layout is the following:

<Page x:Class="Buongiorno.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Buongiorno"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="1*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Button Content="Get Timeline" Name="btnGetTimeline"
Click="Button_Click" />
<ListView Name="TweetList"
Grid.Row="1"
ItemsSource="{Binding}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Margin="2">
<TextBlock Text="{Binding User.ScreenNameResponse}" />
<TextBlock Text="{Binding Text}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<StackPanel Orientation="Horizontal"
Grid.Row="2">
<TextBox PlaceholderText="Hello World of Twitter!"
Name="txtUserTweet" />
<Button Name="btnSendTweet"
Click="btnSendTweet_Click">Tweet!</Button>
</StackPanel>
</Grid>
</Page>

 

In the code-behind file (MainPage.xaml.cs) we’ll code our logic to leverage Linq2Twitter.

Starting from the click event of the btngetTimeLine we write:

private async void BtnGetTimeline_Click(object sender, RoutedEventArgs e)
{
 try
  {
    UniversalAuthorizer auth = await Authenticate();

    using (var twitterCtx = new TwitterContext(auth))
    {
    var srch = await
    (from tweet in twitterCtx.Status
    where tweet.Type == StatusType.Home
    select tweet).ToListAsync();

    var observableTweets = new ObservableCollection&lt;Status&gt;(srch);

    TweetList.DataContext = observableTweets;
   }
 }
 catch (Exception ex)
 {
    var msg = new MessageDialog(ex.Message, "Ops!");
    await msg.ShowAsync();
 }
}

 

In this method we are basically: 1) authenticating to Twitter, 2) retrieve the timeline for the logged in user and display the result in the UI.

We need to focus on the Authenticate Method. It takes care of requesting to Twitter the authorization to act with the API, opening the user interface to login and save the tokens to never ask again for credentials for every API call. The tokens are saved in the local app storage: I recommend this MSDN reading for further details about app data storage. All this is done a few line of codes thanks to Linq2Twitter methods.

private static async Task<UniversalAuthorizer> Authenticate()
{
var localSettings = Windows.Storage.ApplicationData.Current.LocalSettings;
var auth = new UniversalAuthorizer()
{
CredentialStore = new InMemoryCredentialStore()
{
ConsumerKey = "<your consumer key here>",
ConsumerSecret = "<your consumer secret here>",
OAuthToken = localSettings.Values["OAuthToken"]?.ToString(),
OAuthTokenSecret = localSettings.Values["OAuthTokenSecret"]?.ToString(),
ScreenName = localSettings.Values["ScreenName"]?.ToString(),
UserID = Convert.ToUInt64(localSettings.Values["UserId"] ?? 0)
},
Callback = "http://127.0.0.1"
};
await auth.AuthorizeAsync();
//Save credentials.
localSettings.Values["OAuthToken"] = auth.CredentialStore.OAuthToken;
localSettings.Values["OAuthTokenSecret"] = auth.CredentialStore.OAuthTokenSecret;
localSettings.Values["ScreenName"] = auth.CredentialStore.ScreenName;
localSettings.Values["UserId"] = auth.CredentialStore.UserID;
return auth;
}

 

The important steps to note are to set our app Consumer Key and Consumer Secret that Twitter assigned in the App Center where we registered our app at the beginning of this post. At the first authentication the UniversalAuthorizer will open for us the Twitter authorization UI.

clip_image019

At the end of the authentication process in our C# code the auth reference will hold the OAuthToken and OAuthTokenSecret in the CredentialStore variable that we save locally for future use and avoid this pop-up every API call.

The result will be something like that:

clip_image021

The btnSendTweet event handler implements our logic to write a tweet:

private async void btnSendTweet_Click(object sender, RoutedEventArgs e)
{
if (string.IsNullOrWhiteSpace(txtUserTweet.Text)) return;
try
{
var tweetText = txtUserTweet.Text;
UniversalAuthorizer auth = await Authenticate();
using (var twitterCtx = new TwitterContext(auth))
{
await twitterCtx.TweetAsync(tweetText);
await new MessageDialog("You Tweeted: " + tweetText, "Success!").ShowAsync();
}
}
catch (Exception ex)
{
await new MessageDialog(ex.Message, "Ops!").ShowAsync();
}
}

 

As always we need to authenticate and then call the TweetAsync method of TwitterContext to post our tweet.

TL;DR

In this post we learned how to do a simple custom Twitter client that reads our timeline and can write tweets. The main points were to register our app in the Twitter Developer portal, leverage the Linq2Twitter API to do the OAuth authentication and save the tokens in the local storage and make calls to Linq2Twitter API to search for timeline and to tweet.

If you want to learn more, you can refer to the GitHub project of Linq2Twitter (https://github.com/JoeMayo/LinqToTwitter) and the Twitter API official documentation (https://dev.twitter.com/docs). The source code of this example is available on my GitHub (https://github.com/phenixita/uwp-simpletwitter).

If you liked this post please share!

WPF modificare i menù in base al componente attivo

Durante l’aggiunta di funzioni a un’applicazione che sviluppiamo in azienda mi ero accorto che era giunto il momento di un pesante refactoring sulla gestione delle voci di menù. È così nata l’esigenza di poter modificare le funzioni esposte all’utente contestualizzandole sugli elementi attivi scrivendo le minori cablature possibile nel codice. L’obiettivo era quello di realizzare in maniera semplice il concetto che vediamo in Microsoft Word quando selezioniamo per esempio una tabella: subito in alto compare la zona del menù “Strumenti Tabella”.

image

Per spiegare i concetti su come ho implementato la mia versione ho realizzato un esempio di un’app WPF (scaricabile qui) che, tramite l’uso di UserControl e un po’ di System.Reflection, è in grado di modificare una zona della UI per offrire all’utente le funzionalità dello specifico UserControl. È un’implementazione all’acqua di rose del concetto di plug-in per cui farò altri esempi più avanti.

compo

La MainWindows è una semplice shell che contiene un menù con 3 voci.

image

Component 1 richiama il primo componente e lo aggancia sotto al menù.

Component 2 richiama il componente numero 2 e lo aggancia.

La voce “selected component options” si costruisce dinamicamente in base al componente attivo mostrando le sue specifiche opzioni.

image

image

Il meccanismo si basa su due cose:

  1. I componenti che ho realizzato (le classi Component1 e Component2) ereditano da UserControl;
  2. Un Attribute custom chiamato ComponentFunctionAttribute da utilizzare sui metodi che i componenti vogliono rendere disponibili alla shell che li ospita: in questo caso MainWindow.

Ecco che il code behind di Component1 e Component2 diviene:

image

image

In questo modo gli UserControl con questo Attribute etichettano i metodi che vogliono esperre alla shell.

Il codice di ComponentFunctionAttribute è:

image

(per le Guidelines sugli Attribute rimando a MSDN)

A questo punto alla shell non resta che cercare che cosa espone un determinato componente e disegnare il menù di conseguenza, agganciando le funzioni ai controlli utente che più fanno comodo. In questo esempio a dei MenuItem del menù “Selected component options”.

image

image

Servizio WCF ospitato nei Windows Services

Mi sono sempre chiesto la differenza tra ospitare un servizio WCF in IIS e nei Windows Services (services.msc, per capirsi). Così mi sono documentato e ho trovato quanto segue nell’MSDN.

image

Non contento ho fatto una prova completa dalla creazione del progetto all’installazione e interrogazione del servizio per capirci di più. Metto a disposizione il download della soluzione di Visual Studio 2015 che implementa questo esperimento.

Questi sono stati i passaggi.

  1. Nuovo progetto di tipo WCF Service Library
    1
  2. Ho rinominato con F2 i nomi dei file del progetto standard e del servizio che volevo implementare. Ho chiamato l’interfaccia ICalculatorService e la classe che lo implementa CalculatorService. Il servizio espone una funzionalità di somma di numeri con virgola.2
  3. Implementazione molto semplice nella classe CalculatorService.
    3
  4. Ho eseguito il progetto (F5) e mi sono imbattuto subito in un problema: AddressAccessDeniedException. Cercando su MSDN e StackOverflow ho capito che è un problema di privilegi. Per registrare un endpoint di ascolto bisogna avere permessi di amministratore.
    4
  5. Riavviato Visual Studio come amministratore e rieseguito il processo tutto parte senza problemi nell’host dei servizi.5
  6. E con il WCF test client le somme funzionano.6
  7. Viene il momento di creare un nuovo progetto per creare un Servizio Windows che ospiti il servizio WCF. Aggiungo quindi il progetto alla soluzione.7
  8. Un po’ di rinomina sui nomi del file e del servizio che chiamo WindowsCalculatorService rendono più chiaro il lavoro.8
  9. Aggiungo al progetto un installer per facilitare il lavoro di installazione del servizio. Clic destro, Add Installer.9
  10. Il bravo Visual Studio inserisce l’installer correttamente e vado a valorizzare con dei nomi sensati alcune proprietà tipo il nome del servizio con cui poi lo stesso comparirà nell’elenco dei servizi di Windows. C’è anche la possibilità di dare una descrizione (che io ho omesso).10
  11. Sostituisco il metodo Main() di Program.cs del progetto WindowsCalculatorService con queste righe di codice per permettere l’installazione semplicemente avviando l’exe e digitando una lettera: I installa, U disinstalla. 11
  12. Per fare funzionare questo trucchetto bisogna convertire il progetto in progetto Console andando nelle Proprietà del progetto stesso. 12
  13. Per far sì che il servizio WCF sia correttamente configurato quando ospitato dal servizio Windows bisogna riportare la configurazione dal file App.config del progetto WCF a quello del servizio di Windows. Attenzione! Riportare solo la sezione <system.serviceModel>! 13
  14. Per permettere l’installazione del servizio di Windows è necessario avere privilegi di amministratore quindi aggiungendo un file manifest alla soluzione WindowsCalculatorService (add item –> manifest file) vado a specificare level=requireAdministrator nell’apposita sezione <security> del file.14
  15. Modifico il WindowsCalculatorService.cs affinché quando viene avviato esegua il necessario per ospitare il nostro servizio WCF CalculatorService.
    21
  16. Compilo e avvio WindowsCalculatorService.exe e il sistema operativo propone l’UAC come giusto che sia.
    15
  17. Ottenuta la conferma il programma Console ci chiede se vogliamo installare o disinstallare. Ovviamente scrivo I ed installo.16
  18. L’installer del servizio vuole sapere con che utenza deve girare il nostro servizio. Inserisco le mie credenziali.
    17
  19. Ecco che il servizio compare correttamente nell’elenco dei servizi di Windows e lo avvio.18
  20. Avviando il WCF Test Client inserisco l’endpoint specificato nel file app.config.19
  21. Il servizio è operativo e funzionante!20

Voi avete esperienza con WCF? Io l’ho sempre usato per piccole cose e sempre in IIS ma dopo questa prova con i servizi di Windows credo che li userò sempre così. Sono più adatti ai miei scopi e, soprattutto, non richiede l’installazione di IIS.

Ultrasearch (e Windows Search)

Ogni tanto si scoprono dei tool / programmi che, una volta adoperati, ci si chiede come si sia potuto fare senza.

Questo è il caso di Ultrasearch, almeno per me.

Ultrasearch esegue ricerce di file nel disco a una velocità stratosferica. La cosa interessante è che si basa sulla MFT del file system NTFS per raggiungere tale velocità.

A questo punto sorge una domanda. Non so se avete problemi con le ricerche di file in Windows (soprattutto in cartelle non indicizzate) ma io sono disarmato dalla lentezza di cui il sistema operativo stesso soffre in questo caso. Perché Windows non fa uso delle stesse tecniche di ricerca di Ultrasearch visto che l’NFTS l’ha inventato proprio Microsoft? E se ne fa uso, come mai è così lento?

Ad ogni modo ringrazio il collega Giacomo per avermi fatto scoprire Ultrasearch che ho già usato con ottimi risultati in più di qualche occasione.

P.S.: A me la ricerca di Windows funziona particolarmente nella cartella OneDrive con tanto di ricerca nei contenuti. Per il resto lascia molto a desiderare.