はじめに
今回と次回は、

これまでの連載で紹介してきたように、
前回に少しふれたLive SDK 5.

また、
PowerPointアドインの開発
今回は、
Windows PhoneはSkyDriveとシームレスに連携していて、
プレゼンテーション中にWindows Phoneを使ってデモ画面や会場を撮影してSkyDriveにアップロードすると、
アドインでは、
開発環境
開発にはVisual Studioを使用します。Officeアドインを作成するにはVisual StudioのProfessional以上が必要です。今ならVisual Studio 11 Betaを使ってみるのも手かもしれません。
ここでは、
アプリの登録
はじめに、

「アプリケーションの作成」

アプリケーション名と言語を入力し、

今回のようなデスクトップクライアント用のアプリ、
プロジェクトの作成
それでは、
メニューの

プロジェクトには、
Json.NETのインストール
Live Connectを利用する際にJSONデータを扱いますが、
Visual Studio 11の場合、

または、
リボンの追加
はじめに、

図9のようにリボンが表示され、

リボンのコントロールを追加しましょう。ツールボックスの
Group1の中にある、

配置したボタンとメニューは、
ImageとLabelプロパティも編集して図11のようにします。画像は適当なものを用意してください。TabのLabelプロパティも編集します。
MenuのImageとLabelは、

また、
ButtonとMenuの名前も変更しておきましょう。この後のコードでは、
コードの編集
リボンのボタンをクリックしたときの処理は、
まず、
Public Class ThisAddIn
Private Sub ThisAddIn_Startup() Handles Me.Startup
End Sub
Private Sub ThisAddIn_Shutdown() Handles Me.Shutdown
End Sub
' 以下の3個のメソッドを追加
Sub SignIn()
End Sub
Sub SignOut()
End Sub
Sub AddMarker()
End Sub
End Class
リボン側で、
Imports Microsoft.Office.Tools.Ribbon
Public Class MainRibbon
Private Sub SignInButton_Click(sender As Object, e As RibbonControlEventArgs) Handles SignInButton.Click
Globals.ThisAddIn.SignIn()
End Sub
Private Sub SignOutButton_Click(sender As Object, e As RibbonControlEventArgs) Handles SignOutButton.Click
Globals.ThisAddIn.SignOut()
End Sub
Private Sub MarkerButton_Click(sender As Object, e As RibbonControlEventArgs) Handles MarkerButton.Click
Globals.ThisAddIn.AddMarker()
End Sub
End Class
上記コードでは、
認可画面フォームの作成
Live Connectは、

次は、
新しい項目の追加で、

ツールボックスから、

コントロール名を適当なものに変更しましょう。本稿では、
認可画面の表示
Live Connectのおさらいです。認可画面
- https://
oauth. live. com/ authorize?client_ id=CLIENT_ ID &scope=SCOPES&response_type=code&redirect_ uri=https:// oauth. live. com/ desktop
これは、
作成するフォームでは、
プロトコルに関する部分は、
ConsentForm.
Public Class ConsentForm
Private RedirectUri As Uri
Private ClientId As String
Private Scopes As IEnumerable(Of String)
Public Sub New(clientId As String, scopes As IEnumerable(Of String))
InitializeComponent()
' コンストラクタで Client ID と Scope を受け取り Private メンバへ格納
Me.RedirectUri = New Uri("https://oauth.live.com/desktop")
Me.ClientId = clientId
Me.Scopes = scopes
End Sub
Private Sub ConsentForm_Load(sender As Object, e As EventArgs) Handles Me.Load
' フォーム Load 時に Web ブラウザーコントロールに 認可画面を表示
Dim uri = New Uri(String.Format("https://oauth.live.com/authorize?locale=ja&client_id={0}&scope={1}&response_type=code&redirect_uri={2}",
Me.ClientId, String.Join("+"c, Scopes), Me.RedirectUri))
Me.MainWebBrowser.Navigate(uri)
End Sub
End Class
Webブラウザーコントロール内の認可画面をユーザーが操作し、
- https://
oauth. live. com/ desktop?code=[AuthorizationCode]
このcodeパラメーターに認可コードが含まれています。この値を参照できるようコードに追記します。
Private _Parameters As New Dictionary(Of String, String)
ReadOnly Property Parameters As IDictionary(Of String, String)
Get
Return _Parameters
End Get
End Property
Private Sub MainWebBrowser_Navigated(sender As Object, e As Windows.Forms.WebBrowserNavigatedEventArgs) Handles MainWebBrowser.Navigated
If e.Url.Host <> RedirectUri.Host OrElse e.Url.AbsolutePath <> RedirectUri.AbsolutePath Then
' https://oauth.live.com/desktop 以外のアドレスの場合処理を抜ける
Exit Sub
End If
' URL のクエリーを取得
Me._Parameters.Clear()
Dim param = e.Url.Query.Substring(1).Split({"&"c, "="c})
For i = 0 To param.Length - 1 Step 2
Dim val = param(i + 1)
Me._Parameters.Add(param(i), param(i + 1))
Next
' フォームを閉じる
Me.DialogResult = Windows.Forms.DialogResult.OK
Me.Close()
End Sub
上記のコードでは、
フォームに記述するコードは以上です。
Live Connect クラスの作成
さて、
新しくクラスを作るには、
LiveConnectSession
OAuthのAuthorization Code Grant Flowでは、
はじめに、
Namespace Live
Public Class LiveConnectSession
Private _AccessToken As String
ReadOnly Property AccessToken As String
Get
Return _AccessToken
End Get
End Property
Private _RefreshToken As String
ReadOnly Property RefreshToken As String
Get
Return _RefreshToken
End Get
End Property
Private _Expires As DateTimeOffset
ReadOnly Property Expires As DateTimeOffset
Get
Return _Expires
End Get
End Property
Private _Scopes As IEnumerable(Of String)
ReadOnly Property Scopes As IEnumerable(Of String)
Get
Return _Scopes
End Get
End Property
Friend Sub New(accessToken As String, refreshToken As String, expires As DateTimeOffset, scopes As IEnumerable(Of String))
Me._AccessToken = accessToken
Me._RefreshToken = refreshToken
Me._Expires = expires
Me._Scopes = scopes
End Sub
End Class
End Namespace
アクセストークンのAccessTokenプロパティ、
LiveAuthClient
次に、
アクセストークンの取得は、
- https://
oauth. live. com/ token?client_ id=CLIENT_ ID &code=AUTHORIZATION_CODE &grant_type=authorization_ code&redirect_ uri=https:// oauth. live. com/ desktop
クラスは、
Imports System.Threading.Tasks
Imports System.Net
Imports Newtonsoft.Json.Linq
Namespace Live
Public Class LiveAuthClient
Private ClientId As String
Private RedirectUri As Uri
Event InitializeCompleted As EventHandler(Of LoginCompletedEventArgs)
Sub New(clientId As String)
' コンストラクタでアプリのクライアント ID を渡す
Me.ClientId = clientId
Me.RedirectUri = New Uri("https://oauth.live.com/desktop")
End Sub
' 認可画面フォームの表示、アクセストークン取得後イベントを起こす
Sub InitializeAsync(scopes As IEnumerable(Of String))
Using form = New ConsentForm(Me.ClientId, scopes)
If form.ShowDialog <> Windows.Forms.DialogResult.OK OrElse
Not form.Parameters.ContainsKey("code") Then
Exit Sub
End If
Task.Factory.StartNew(Of LiveConnectSession)(
Function()
Return GetSession(form.Parameters("code"))
End Function) _
.ContinueWith(
Sub(t As Task(Of LiveConnectSession))
RaiseEvent InitializeCompleted(Me, New LoginCompletedEventArgs(t.Result))
End Sub)
End Using
End Sub
' 認可コードからアクセストークンを取得
Private Function GetSession(code As String) As LiveConnectSession
Dim uri = New Uri(String.Format("https://oauth.live.com/token?client_id={0}&code={1}&grant_type=authorization_code&redirect_uri={2}",
Me.ClientId, code, Me.RedirectUri))
Dim client = New WebClient
Dim json = client.DownloadString(uri)
Dim o = JObject.Parse(json)
If o("error") IsNot Nothing Then
Return Nothing
End If
Dim session As New LiveConnectSession(
o("access_token").ToString(),
o("refresh_token").ToString(),
New DateTimeOffset(Now.ToUniversalTime).AddSeconds(o("expires_in").ToObject(Of Integer)),
o("scope").ToString.Split(" "c))
Return session
End Function
End Class
End Namespace
GetSessionメソッドでアクセストークンを取得しています。サーバーからの応答は次のようなJSONデータになっています。コードでは、
{
"access_token": "xxxxx",
"expires_in": 3600,
"refresh_token": "xxxxx",
"scope": "wl.offline_access wl.skydrive",
"token_type": "bearer"
}
ちなみに、
{
"error": "invalid_grant",
"error_description": "The provided value for the input parameter 'code' is not valid."
}
LoginCompletedEventArgs
続いて、
Namespace Live
Public Class LoginCompletedEventArgs
Inherits EventArgs
Private _Session As LiveConnectSession
ReadOnly Property Session As LiveConnectSession
Get
Return _Session
End Get
End Property
Sub New(session As LiveConnectSession)
_Session = session
End Sub
End Class
End Namespace
LiveConnectClient
最後は、
REST APIは、
- https://
apis. live. net/ v5. 0/ me/ skydrive/ files?access_ token=ACCESS_ TOKEN
今回はHTTP GETメソッドしか使いませんので、
Namespace Live
Public Class LiveConnectClient
Private _Session As LiveConnectSession
ReadOnly Property Session As LiveConnectSession
Get
Return _Session
End Get
End Property
Public Sub New(session As LiveConnectSession)
_Session = session
End Sub
Function [Get](path As String) As String
Dim uri = New Uri("https://apis.live.net/v5.0/" &
path &
If(path.Contains("&"), "&", "?") &
"access_token=" & Me.Session.AccessToken)
Dim client = New Net.WebClient With {.Encoding = System.Text.Encoding.UTF8}
Return client.DownloadString(uri)
End Function
End Class
End Namespace
以上で、
サインインユーザーの表示
ここで、
サインイン
ThisAddInクラスにあるSingInメソッドを編集します。
' (ファイルの先頭に Imports SamplePowerPointAddIn.Live を記述すること)
Private Const ClientId As String = "XXXXX" ' 登録したアプリのクライアント ID
Sub SignIn()
Dim client = New LiveAuthClient(ThisAddIn.ClientId)
AddHandler client.InitializeCompleted,
Sub(s, e)
If e.Session Is Nothing Then
Exit Sub
End If
Dim t = New Threading.Thread(AddressOf GetUserInfo)
t.SetApartmentState(Threading.ApartmentState.STA)
t.Start(e.Session)
End Sub
client.InitializeAsync(New String() {"wl.skydrive", "wl.offline_access"})
End Sub
LiveAuthClientオブジェクトを生成し、
InitializeAsyncメソッドで、
GetUserInfoメソッドでは、
' (ファイルの先頭に Imports Newtonsoft.Json.Linq を記述すること)
Private LiveConnectClient As LiveConnectClient
Private Sub GetUserInfo(session As LiveConnectSession)
Me.LiveConnectClient = New LiveConnectClient(session)
Globals.Ribbons.MainRibbon.SignInButton.Enabled = False
Try
' サインインしたユーザーの表示アイコンをダウンロード
Dim url = "https://apis.live.net/v5.0/me/picture?access_token=" & session.AccessToken
Dim client = New Net.WebClient
Dim file = System.IO.Path.GetTempFileName
client.DownloadFile(url, file)
' サインインしたユーザー情報を取得
Dim result = LiveConnectClient.Get("me")
' UI 操作
Dim o = JObject.Parse(result)
Globals.Ribbons.MainRibbon.SignOutMenu.Label = o("name").ToString
Globals.Ribbons.MainRibbon.SignOutMenu.Image = New System.Drawing.Bitmap(file)
Globals.Ribbons.MainRibbon.SignOutMenu.Visible = True
Globals.Ribbons.MainRibbon.SignInButton.Visible = False
Catch ex As Exception
' (例外は無視)
End Try
End Sub
コード中にある次のURLにアクセスすると、
- https://
apis. live. net/ v5. 0/ me/ picture?access_ token=ACCESS_ TOKEN
また、
- https://
apis. live. net/ v5. 0/ me?access_ token=ACCESS_ TOKEN
この結果は、
{
"id": "xxxxx",
"name": "梓 中野",
"first_name": "梓",
"last_name": "中野",
"gender": null,
"locale": "en_US"
}
コードでは、
さて、
このサインイン処理は、
おわりに
今回はここまでです。いかがでしたか。今回はほとんど準備段階となってしまいましたが、