2019年10月31日 星期四

Github 快速上手 2 : 建立新的 Repository 與 同步

Github 快速上手 2 : 建立新的 Repository 與 同步

在 Github 建立一個新的 Repository

請打開 Github 網頁,於登入認證之後,點選右上方的 + 加號 圖片
當 [Create a new repository] 頁面出現之後,請在 [Repository name] 這個欄位中,輸入想要建立的 Repository 的名稱,這裡會輸入 MyFirstRepository
使用滑鼠捲動網頁到最下方,將會看到 [Create respository] 這個按鈕,請點選這個按鈕,完成這個 Repository 的建立。

複製 Github 的 Repository 到本機電腦上

現在完成了這個 MyFirstRepository 這個 Repository 的建立,現在,請在 [Quick setup — if you’ve done this kind of thing before] 標題的下方,將會看到一個 HTTS URL,請將這個 URL 複製到系統剪貼簿內。
請打開檔案總管,切換到想要儲存這個 Repository 的目錄內,這裡是切換到這台電腦的 [C:\Xamarin] 目錄內;接著,在檔案總管空白地方,使用滑鼠右擊,現在將會看到彈出功能表中有個 [Git Clone...] 這個選項,請點選這個選項。
現在, [TortoiseGit] 將會使用系統剪貼簿內儲存的 URL,複製一份遠端 Github 上的 Repository 到這台電腦上的這個目錄內。
當出現了 [Git clone] 對話窗的時候,可以直接使用預設值 ( 因為,對於 URL 欄位的內容,將會從剪貼簿取得 ),接著請點選 [OK] 按鈕

設定 Repository 簽入 Commit 要排出的檔案類型

現在請切換到這個 Repository 的目錄下,也就是 [C:\Xamarin\MyFirstRepository] 這個目錄,並且建立一個 [.gitignore] 文字檔案。
該 [.gitignore] 的檔案內容,可以從 https://raw.githubusercontent.com/vulcanlee/CSharp2019/master/.gitignore 取得
上面螢幕截圖為建立 [.gitignore] 文字檔案 與 加入該檔案內容的操作結果。
現在可以進行第一次的 簽入 Commit,請在這個 Repository 目錄內的空白地方,點選滑鼠右鍵,從彈出功能表中選擇 [Git Commit -> "master"] 這個選項
當 [C:\Xamarin\MyFirstRepository - Commit - TortoiseGit] 對話窗出現之後,請在 [Message] 欄位中輸入 Init (或者任何代表此次簽入的文字內容)。
在下方的 [Changes made (double-click on file for diff)] 標題下方,點選 [All] 文字,代表要選擇所有當前所有的檔案。
最後,找到下方的 [Commit] 按鈕,請先點選該按鈕右方的 向下黑色三角形 ,此時會出現一個彈出選單,請在該選單內選擇 [Commit & Push] ,表示,按下這個按鈕之後,將會進行簽入與推入到遠端的 Github 主機內。
當進行第一次操作的時候,將會如上面螢幕截圖,要求第一次要先進行 Github 身分驗證,在這裡,請輸入剛剛申請 Github 的帳號(或者Email)和密碼之後,點選 [Github Login] 對話窗下方的 [Login] 按鈕。
當看到如上面螢幕截圖,這就表示這次的簽入與推入到遠端 Github Repository 的工作已經完成了。
從網頁中將會看到剛剛增加的 [.gitignore] 檔案已經成功地簽入到 Github Repository 內了。

將 Xamarin.Forms 的方案內所有專案,簽入到 Github Repository 內

現在可以找出一個正在開發或者新建立的 Xamarin.Forms 專案,不過,最好這個專案是可以正常建置與執行的,因為,這裡需要這些專案內的 Bin Obj 目錄下的這些二進位元檔案。
在這裡已經複製一份 CustNaviService 之 Xamarin.Forms 的方案,根據檔案總管的統計,這個 CustNaviService 目錄下總共有 182MB 磁碟空間,可是,真正的原始碼並沒有這麼多,絕大多數是由二進位檔案所佔據。
在此之前,已經 簽入 Commit 這個 [.gitignore] 檔案,因此,當要繼續簽入這個專案檔案內容的時候,將會排除這些 二進位 型態的檔案,現在,來檢驗看看。
請在檔案總管確認是在 [C:\Xamarin\MyFirstRepository] 目錄下,使用滑鼠右鍵點選空白地方,當彈出功能表出現的時候,請選擇 [Git Commit -> "master"] 這個選項,準備簽入與推入到 Github Repository 內
在出現了 [C:\Xamarin\MyFirstRepository - Commit - TortoiseGit] 對話窗的時候,請在 [Message] 欄位內輸入 [加入 CustNaviService 方案所有檔案] 簽入備註訊息,並且在下方點選 [All] 文字,選擇所有的檔案內容。
若此時使用滑鼠捲動最下方的檔案清單內容,應該不會看到任何 二進位元 類型的檔案。
最後,請點選 [Commit & Push] 按鈕,進行簽入與推入到Github Repository。
當完成簽入與推入之後,將會看到如上圖的畫面。

確認推入的專案,將不包含二進位元的檔案

先打開 Github 網站中的 MyFirstRepository Repository,檢查剛剛推入的檔案是否已經推進去了。
打開 https://github.com/XamarinForms/MyFirstRepository 網頁,在下方就會看到 [CustNaviService] 目錄已經在 Github 的 Repository 內了。
請使用滑鼠來點選上面截圖的紅色箭頭指向的按鈕,也就是 [Clone or download] 按鈕
當彈出了 [Clone with HTTPS] 視窗的時候,請將該子視窗內的 URL 複製起來。這裡的 URL 將會是 : https://github.com/XamarinForms/MyFirstRepository.git
現在請使用檔案總管切換到 C:\Xamarin 這個目錄下
在該目錄的空白地方,使用滑鼠右鍵點選 [Git Clone...] 這個選項
當出現了 [Git clone - TortoiseGit] 這個對話窗,請將 [Directory] 這個欄位,輸入成為 C:\Xamarin\MyFirstRepository2
也就是要複製一份 Github 上的 Repository,不過,是要複製到 C:\Xamarin\MyFirstRepository2 這個目錄下 (原先剛剛的 Repository 是複製到 C:\Xamarin\MyFirstRepository 目錄下)
最後,請點選 [OK] 按鈕,開始進行複製
完成複製後,請在 [C:\Xamarin - Git Command Program - TortoiseGit] 對話窗內,點選 [Close] 按鈕
從上面操作螢幕截圖中,可以看到 [MyFirstRepository2] 這個目錄已經產生出來了。
請使用檔案總管,查看 [C:\Xamarin\MyFirstRepository2\CustNaviService] 目錄的內容,發現到 [CustNaviService] 這個目錄下,僅佔有 1.32 MB 大小,這與之前查詢 [C:\Xamarin\MyFirstRepository\CustNaviService] 目錄所站的空間為 182MB 有很大的落差,這是因為絕大部分的檔案都是二進位元的檔案,而且在簽入的時候都已經排出掉了,不會簽入到 Github Repository 內。

清除本機 Repository 內的二進位元檔案

現在,請使用檔案總管回到 [C:\Xamarin\MyFirstRepository] 目錄下,準備把這些二進位元的檔案清除掉,順便檢查清除後的專案所佔據的磁碟空間。
請在 [C:\Xamarin\MyFirstRepository] 目錄下,使用滑鼠右擊空白地方,當彈出選單出現之後,依據點選 [TortoiseGit] > [Clean up...] 選項
現在出現了 [C:\Xamarin\MyFirstRepository - Clean - TortoiseGit] 這個對話窗,相關的選項請使用預設值,直接點選 [OK] 按鈕
現在請使用檔案總管來查看 [C:\Xamarin\MyFirstRepository\CustNaviService] 目錄的內容,從上面螢幕截圖中,可以看到,這些二進位元檔案也都被移除了,整個 [C:\Xamarin\MyFirstRepository\CustNaviService] 目錄僅佔有 1.32 MB
請注意
在使用這個功能的時候,請記得這個 Repository 已經完成了 簽入 Commit 動作




2019年10月30日 星期三

Github 快速上手 1 : 環境的安裝與設定

Github 快速上手 1 : 環境的安裝與設定

當我在進行 Xamarin.Forms 課程教學的時候,當學員所練習的專案有問題時候,我都會建議學員把專案原始碼提供給我,好方便進行除錯,可是,通常學員給我的該練習專案的壓縮檔案都非常大,幾乎超過 80MB 以上、甚至更大,而,就算請學員把專案原始碼推入到 Github Repository 上,該 Repository 的檔案體積也是十分的大;這是因為在進行 git commit 簽入時候,把許多二進位元檔案也簽入進去了,而這些二進位元檔案是 Visual Studio 在建置時期產生的,其實不需要簽入或者儲存起來,因為,下次建置的時候,就會重新產生出來了。
因此,在這裡撰寫了兩篇系列文章,方便學員參考了解 Github 這個工具的使用過程
這裡將會說明如何在第一次使用 Github 功能的時候,如何申請帳號、安裝相關軟體、進行設定
這裡將會說明如何建立 Github Repository、複製該 Repository 到本機電腦內、簽入忽略二進位元的設定到 Github Repository 內、簽入 Xamarin.Forms 的專案、使用 TortoiseGit 工具清除本機 Repository 內的二進位元檔案。
在這系列文章中,假設開發者已經有安裝了 Visual Studio 2017 或者 Visual Studio 2019 開發工具。

申請 Github 帳號

若還沒有 Github 帳號,可以參考底下的步驟來進行申請,若已經有 Github 帳號,則可以跳過有關 Github 帳號申請說明的內容,直接進入到下一段內容。
在打開 Github 網站之後,將會看到該網頁的左方有 [Username] 、 [Email] 、 [Passowrd] 三個文字輸入盒,請在這裡輸入你自己的相關資訊,完成後,請點選 [Sing Up for Github] 這個按鈕,申請一個免費的 Github 帳號。
此時,Github 網站需要進行驗證,請點選中間的 [驗證] 按鈕
請依照網頁文字說明指示內容進行操作,完成後,將會看到如上圖的文字,表示驗證完成,此時,可以點選螢幕上的 [完成] 按鈕。
現在,可以點選下方的 [Next: Select a plan] 按鈕,不過,在這裡有勾選 Email preferences 的選項 [Send me occasional product updates, announcements, and offers.]
在此,可以選擇免費 [Free] 的方案即可,請點選 [Choose Free] 這個按鈕
當看到歡迎來到 Github 網站的訊息,請使用滑鼠轉動到最下方。
在這裡將可以點選 [Complete setup] 按鈕,不過,將會使用直接點選 [Skit this setp]
好的,請檢查剛剛申請帳號使用的 Email 信箱,打開 Github 寄送來的驗證郵件
請點選郵件上的 [Verify email address] 藍色按鈕,或者底下的 URL 連結
現在已經完成了 Github 帳號的申請作業了

確認與 Git for Windows 有安裝

請先確認電腦中是否已經有安裝 Git for Windows
在桌面左下角,點選放大鏡或者在 [搜尋方塊] 中輸入 git 文字,若這個時候沒有找到任何應用程式,那就表示這台電腦上還沒有安裝 [Git for Windows] 這個應用程式。
若沒有的話,可以透過 Visual Studio Installer 工具來協助安裝。
Visual Studio Installer
在電腦中找到 [Visual Studio Installer] 這個應用程式
當 Visual Studio Installer 安裝程式啟動起來之後,請點選 [個別元件] 標籤頁次,可以在 [程式碼工具] 區段中,找到 [Git for Windows] 這個選項,若該選項尚未勾選,請勾選這個選項,把它安裝起來。
現在再度在桌面左下角,點選放大鏡或者在 [搜尋方塊] 中輸入 git 文字,此時將會看到上面的螢幕截圖,表示這電腦上已經有安裝 [Git for Windows] 這個應用程式。

安裝 TortoiseGit

為了要能夠透過 [檔案總管] 來進行 [Github] 的同步與操作更多功能,在這裡可以先安裝 [TortoiseGit] 這個工具;請先使用瀏覽器打開這個網址 https://tortoisegit.org/
在 [TortoiseGit] 網頁上,將會看到 [Download] 按鈕,請點選這個按鈕
當 [Download] 網頁出現之後,可以選擇 [for 64-bit Windows] 文字下方的檔案下載連結,這裡看到的是 Download TortoiseGit 2.8.0 - 64-bit 準備下載與進行安裝這個工具。
[TortoiseGit] 安裝程式啟動之後,請點選 [Next] 按鈕
在 [Information] 對話窗中,點選 [Next] 這個按鈕
在 [Choose SSH Client] 對話窗中,使用預設值,點選 [Next] 這個按鈕
在 [Custom Setup] 對話窗中,使用預設值,點選 [Next] 這個按鈕
在 [Ready to Install] 對話窗中,點選 [Install] 這個按鈕,準備開始進行安裝作業。
現在已經安裝完成了,請點選 [Finish] 按鈕,準備進行第一次精靈的設定
在 [Welcome to TortoiseGit] 對話窗中,使用預設值,點選 [下一步] 這個按鈕
在 [Welcome to TortoiseGit] 對話窗中,使用預設值,點選 [下一步] 這個按鈕
在 [Configure git.exe] 對話窗中,點選中間右方的 [Check now] 按鈕,此時,在該按鈕的左方會出現這台電腦已經安裝 Git 工具版本,這裡顯示的是 [git version 2.17.1.windows.2] ,最後請點選 [下一步] 這個按鈕
在 [Configure user information] 對話窗中,請在 [Name] 與 [Email] 欄位中,輸入你的相關資訊,點選 [Next] 這個按鈕
在 [Authentication and credential store] 對話窗中,使用預設值,點選 [完成] 這個按鈕
在 [Information] 對話窗中,使用預設值,點選 [Next] 這個按鈕



2019年9月25日 星期三

使用 Microsoft.Graph NuGet 套件 來存取 Office 365 行事曆的功能

使用 Microsoft.Graph NuGet 套件 來存取 Office 365 行事曆的功能

現在要來使用 Microsoft.Graph 套件所提供的 API,進行新增一筆行事曆事件,想要使用這個功能,那就需要先完成前一篇的文章 使用 MSAL.NET 的 Resource Owner Password Credential ROPC 架構來取得存取權杖但是無須透過瀏覽器來進行身分驗證 的程式碼練習,透過該文章中的說明方法,就可以取得要存取 Microsoft Graph API 所需要用到的 Access Token。
在這篇文章所提到的專案原始碼,可以從 GitHub 下載

建立測試專案

在這篇文章中,將會使用一個 Console 主控台應用程式類型的專案,來進行設計這樣的需求,也就是說,在無需與使用者互動,或者當時電腦環境沒有瀏覽器軟體的環境下,可以透過使用者帳號與密碼的方式,取得存取權杖 Access Token。因此,請先建立一個名為 MicrosoftGraphAPI 的 Console 專案,在這裡使用的是 .NET Framework 開發框架。並且把這篇文章 使用 MSAL.NET 的 Resource Owner Password Credential ROPC 架構來取得存取權杖但是無須透過瀏覽器來進行身分驗證 中的所有程式碼複製一分到這個專案內,並且使其可以正常運作。

安裝 Microsoft.Graph NuGet 套件

接著要來安裝 Microsoft.Graph 套件
  • 滑鼠右擊此專案
  • 選擇 [管理 NuGet 套件] 選項
  • 點選瀏覽標籤頁次
  • 在搜尋文字輸入盒內輸入這個文字 Microsoft.Graph
  • 點選 安裝 按鈕

開啟該使用者的 Office 365 Outlook 的行事曆

首先,先來確認這個使用者的行事曆中,是沒有任何事件或者約會存在

開始設計新增一筆行事曆事件的程式碼

請在獲取 Access Token 之後的程式碼,建立一個型別為 GraphServiceClient 的執行個體,在這裡會在建構函式內傳入一個 DelegateAuthenticationProvider 物件,並且在此要指定剛剛取得的 Access Token 存取權杖值。
使用 底下的程式碼,建立一個 Event 物件,使其加入到這個使用者的行事曆內。
await graphServiceClient.Me.Events.Request(requestOptions)
                .AddAsync(new Event
                {
                    Subject = "自動同步行事曆測試" + Guid.NewGuid().ToString(),
                    Start = startTime,
                    End = endTime
                });
請執行這個應用程式,確認有看到 新的行事曆事件已經建立成功 文字顯示出來。
最後,請檢查該使用者 Outlook 行事曆中,是否有這筆新事件產生出來。
這是這篇文章使用到的程式碼
C Sharp / C#
class Program
{
    static string clientId = "應用程式 (用戶端) 識別碼";
    static string authority = "目錄 (租用戶) 識別碼";
    static string account = "Office 365 使用者的電子郵件信箱";
    static string password = "Office 365 使用者的密碼";

    static void Main(string[] args)
    {
        GetMicrosoftGraphAccessTokeyAsync().Wait();
    }

    static async Task GetMicrosoftGraphAccessTokeyAsync()
    {
        string[] scopes = new string[] { "user.read" };
        IPublicClientApplication app;
        app = PublicClientApplicationBuilder.Create(clientId)
              .WithAuthority($"https://login.microsoftonline.com/{authority}")
              .Build();

        AuthenticationResult result = null;

        try
        {
            #region 將所提供的密碼,使用 SecureString 以加密的方式儲存
            // SecureString 代表應該將文字保密,例如於不再使用時將它從電腦記憶體刪除。 
            var securePassword = new SecureString();
            foreach (char c in password)
                securePassword.AppendChar(c);
            #endregion

            // 使用使用者的帳號與密碼憑證,來獲取存取權杖
            result = await app.AcquireTokenByUsernamePassword(scopes, account, securePassword)
                               .ExecuteAsync();
        }
        catch (MsalException ex)
        {
            Console.WriteLine(ex.Message);
        }

        Console.WriteLine(result.Account.Username);
        Console.WriteLine($"Access Token : {result.AccessToken}");
        foreach (var item in result.Scopes)
        {
            Console.WriteLine($"Scope :{item}");
        }


        var graphServiceClient = new GraphServiceClient(new DelegateAuthenticationProvider((requestMessage) =>
        {
            requestMessage
                .Headers
                .Authorization = new AuthenticationHeaderValue("bearer", result.AccessToken);

            return Task.FromResult(0);
        }));

        List<Option> requestOptions = new List<Option>();

        // 指定事件開始與結束時間
        DateTimeTimeZone startTime = new DateTimeTimeZone
        {
            DateTime = DateTime.Now.AddDays(3).ToString("o"),
            TimeZone = TimeZoneInfo.Local.Id
        };
        DateTimeTimeZone endTime = new DateTimeTimeZone
        {
            DateTime = DateTime.Now.AddDays(5).AddHours(1).ToString("o"),
            TimeZone = TimeZoneInfo.Local.Id
        };


        // 新增這個事件
        Event createdEvent = await graphServiceClient.Me.Events.Request(requestOptions)
            .AddAsync(new Event
            {
                Subject = "自動同步行事曆測試" + Guid.NewGuid().ToString(),
                Start = startTime,
                End = endTime
            });

        if (createdEvent != null)
        {
            Console.WriteLine($"新的行事曆事件已經建立成功");
        }

    }
}