Raspberry piでC#

Raspberry piで dotnet core開発

Raspberry piでc#開発する

Microsoftのdotnet coreはマルチプラットフォームなのでraspberryのようなlinuxでも開発実行ができます。 今回はc#の開発をraspberryでおこなった例です

手順

raspberry pi準備
Raspberry Pi imagerを使う
dotnet準備
raspberryにdotnet sdkをインストールする
コンソールアプリ
Hello worldの出力
WebでHello world
webテンプレートで文字出力
Webにhtml出力
webに文字としてhtmlを出力
Razorテンプレートのサンプル
ページファイルとページモデルの組み合わせで表示する

raspberry pi準備

raspberry piをすでにraspberry5まで来ているんですね。少し離れている間に高速になっています。

以前と違ってSDのフォーマットやdownloadなどを総合的に行うraspberry pi imagerというものがあるのでdownloadしましょう。

raspberry pi HOME

raspberry pi homeに行きます。

raspberry pi software

softwareに行って、少し下にimagerのダウンロードがありますので、ダウンロードします。imager_1.8.5.exe(2024/7/7現在)をダブルクリックしてインストールします。

raspberry pi imager

起動するとこんな感じのラズベリー色のツールが立ち上がります

raspberry pi imagerでするべきこと

SDカード初期化
8G程度のmicroSDカードを準備して初期化
OSダウンロード
64bit,32bit,full,lite色々あるのであらかじめダウンロードしておきます
SDカード書き込み
SDカードへの書き込み、チェック
raspberry pi電源投入
キーボード、マウス、HDMIを接続してから電源投入
リモート接続
VNC ViewerとteraTermの接続

SDカード初期化

SDカードは8G程度あればいいのですが、初期化しないといけないので、次の処理をしてください。

erase sd card data

raspberry pi imagerの真ん中のOSをクリックして「erase」を選択して、デバイスを選択して実行します。もしここでエラーが出たらそのSDは壊れているかもしれません。SDは消耗品だと思ってください。

OSダウンロード

select os

imagerをダウンロードしたところの下のほうに「see all download options」があります。

select os

32bit,64bitが分かれて置いてありますので選んでください。今回は、64bitを選びました。

download files

1.1Gあるので時間がかかります。ダウンロードする時にユーザー名など聞かれますがこの時のユーザー名がリモートなどでログインする時のユーザー名になります。以前はデフォルトがpiでした。

SDカード書き込み

select os image

imagerのosで「custom」を選びます。ここでどれかOSを選んでもいいのですが、毎回やるのは面倒なので、先にDOWNLOADしたものを使いました。

select os image

書き込んだら、続いてチェックが走りますのでそれが終わるまで待ってください。

書き込み終わったら、初期化しろとか色々OSが言うかもしれませんが無視してSDを取り外してください

raspberry pi電源投入

USBキーボード、USBマウス、HDMIケーブルをつなぎ、SDカードを入れて、ディスプレイの準備ができたらUSB Bタイプの電源を入れて起動しましょう。

最初の起動はディスプレイがある状態でしましょう。rasberry configurationで設定画面を開いて日本語やパスワードの設定をしましょう。

into setup select language

設定が出来たら右上のWiFiのアイコンにポイントしてIPアドレスを調べておいてください。ポイントはマウスをかざすだけで、クリックしてはいけません。おそらくそのIPアドレスでしばらく接続することになるでしょう。

ip address

リモート接続

ディスプレイを別に用意できる人は良いですが、そうでない方はリモート接続すればパソコンの中に画面を表示して操作ができるので楽ができます。

select remote

設定のインターフェースで「SSH」と「VNC」をONにしてください。この後「REBOOT」すると、リモートが出来るようになります。

続いて、リモートアクセス用のアプリをWindowsにインストールします。画面が出るのがReal VNC Viewerで、コマンドでのやり取りが teraTermです。

vnc

real vnc viewerのダウンロードでWindowsのものをダウンロードしてインストールしてください。起動したらIPアドレスを聞かれます

vnc start

ここでは半角数値で192.168.12.191と入力しています。

password

ユーザー名はdownloadするときに決めたものです。パスワードもそうですが、後から変えたのであればそちらを入れてください

vnc window

するとWindowとしてVNCが立ち上がり、その中にraspberryの画面が表示されます。Windowsのマウスをこの中で移動させれば実際の画面でもマウスが移動します。

shutdownしないでただ接続を切りたい場合はマウスを上に持って行って、真ん中のせり出しメニューの×を押してください。

vnc切断

shutdownしたい場合はログアウトからshutdownしてください。

raspberry shutdown raspberry shutdown

接続が切れて黒い画面になるのでアプリを終了してください。ただし、shutdown自体には時間が掛かりますので、raspberry本体の緑のLEDのチカチカが止まってから 電源を抜いてください。

画面は不要で、コマンドだけで良い場合は、teratermなどのsshアプリを使用します。

tera termは日本人が作ったアプリで、暗号化通信ができるのでよく使われます。窓の杜などからダウンロードしましょう。

ダウンロード、インストールしたら起動します

teraterm

起動したらIPアドレスを入力します。初回だけ暗号化の確認画面がでますので確認してください。

teraterm login

ユーザーIDとパスフレーズを入れます。初回で入れたパスワードです。これでコマンド入力が出来ます。

dotnet 準備

ようやくここまで来ました。ここからdotnetの話になります。このあたりからはMicrosoft Learn にも載っています。くわしく載っています

次のコマンドを入力してください

dotnetのインストール
    curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin --channel STS
dotnet install

少し時間が掛かりますが、自動的にインストールが行われます。つづけて設定があります

dotnetの設定
    echo 'export DOTNET_ROOT=$HOME/.dotnet' >> ~/.bashrc
    echo 'export PATH=$PATH:$HOME/.dotnet' >> ~/.bashrc
    source ~/.bashrc

    dotnet --version

コンソールアプリ

ようやく環境が出来ましたので、teratermでつないでコンソールアプリでhello worldしてみましょう。

workspace(cstest)の作成
    mkdir cstest
    cd cstest

まずはこれからworkspaceになるcstestフォルダーを作ってその下に作っていきます

HelloConの作成(cstest上で入力)
    f710@ras01:~/cstest $ dotnet new console -o HelloCon
    テンプレート "コンソール アプリ" が正常に作成されました。

    作成後の操作を処理しています...
    /home/f710/cstest/HelloCon/HelloCon.csproj を復元しています:
        Determining projects to restore...
        /home/f710/cstest/HelloCon/HelloCon.csproj を復元しました (720 ミリ秒)。
    正常に復元されました。

これですでにひな形は出来ていますが、少し変更してみましょう

HelloConの作成(cstest上で入力)
    f710@ras01:~/cstest $ cd HelloCon
    f710@ras01:~/cstest/HelloCon $ ls
    HelloCon.csproj  Program.cs  obj
    f710@ras01:~/cstest/HelloCon $ sudo nano Program.cs

nanoがlinuxのエディタで、少し使いづらいですが、viよりましです。

sudoは特権を持って実行でProgram.csがメインプログラムです

Program.cs

C#の最上位レベルのコーディングになっているのでmainの内部だけのソースです。

Hello worldをHello console worldに変更して、CTRL+X y Enter で変更保存します。

Program.cs Program.cs
HelloConの実行
    f710@ras01:~/cstest/HelloCon $ dotnet run
    Hello, console World!

実は最初の1回目だけテレメトリとか開発証明書の発行とかが表示されます。raspberryでc#の実行ができました。

dotnet runはビルドしてrunです。実行だけするのであれば、

HelloConの実行
    f710@ras01:~/cstest/HelloCon $ bin/Debug/net7.0/HelloCon
    Hello, console World!

で、実行できます。

webでHello world

workspaceになるcstestフォルダーに移動してその下に作っていきます

HelloWebの作成(cstest上で入力)
    f710@ras01:~/cstest $ dotnet new web -o HelloWeb
    テンプレート "ASP.NET Core (空)" が正常に作成されました。
    
    作成後の操作を処理しています...
    /home/f710/cstest/HelloWeb/HelloWeb.csproj を復元しています:
      Determining projects to restore...
      /home/f710/cstest/HelloWeb/HelloWeb.csproj を復元しました (704 ミリ秒)。

これですでにひな形は出来ていますが、少し変更してみましょう

HelloWebの作成(cstest上で入力)
    f710@ras01:~/cstest $ cd HelloWeb
    f710@ras01:~/cstest/HelloWeb $ ls
    HelloWeb.csproj  Properties                    appsettings.json
    Program.cs       appsettings.Development.json  obj
    f710@ras01:~/cstest/HelloWeb $ sudo nano Program.cs
Program.cs

WebApplicationのCreateBuilderメソッドでWebApplicationBuilderクラスを作成します。

MapGetでどのurlの時に機能を呼び出すのかを記述します。今回はHelo worldの文字を出力します

HelloConの実行
    f710@ras01:~/cstest/HelloWeb $ sudo nano Properties/launchSettings.json
Program.cs

実はdefaultでrunしてしまうと、localhostで実行されてしまい、外からアクセスできないので、Settingを変えます

httpのapplicationUrlをlocalhostから0.0.0.0に変えてください。

プログラムを起動すると指定されたportで待ち受けてくれるので、接続します。ちなみにport番号は適当です。ぶつかっていなければ何番でもかまいません。

HelloWebの実行
    f710@ras01:~/cstest/HelloWeb $ dotnet run
    ビルドしています...
    info: Microsoft.Hosting.Lifetime[14]
          Now listening on: http://0.0.0.0:5003
    info: Microsoft.Hosting.Lifetime[0]
          Application started. Press Ctrl+C to shut down.
    info: Microsoft.Hosting.Lifetime[0]
          Hosting environment: Development
    info: Microsoft.Hosting.Lifetime[0]
          Content root path: /home/f710/cstest/HelloWeb

ブラウザを立ち上げて、接続します

Web Helo

文字が出ただけですが、Webに接続できました。

ところで、このc#はIISを使用していません。kestrelという簡易サーバーです。

HelloWebの終了
    ^Cinfo: Microsoft.Hosting.Lifetime[0]
    Application is shutting down...

kestrelを止めるにはCTRL+Cを押します

webで文字としてhtml出力

workspaceになるcstestフォルダーに移動してその下に作っていきます

HelloHtmlの作成(cstest上で入力)
    f710@ras01:~/cstest $ dotnet new web -o HelloHtml
    テンプレート "ASP.NET Core (空)" が正常に作成されました。
    
    作成後の操作を処理しています...
    /home/f710/cstest/HelloHtml/HelloHtml.csproj を復元しています:
      Determining projects to restore...
      /home/f710/cstest/HelloHtml/HelloHtml.csproj を復元しました (782 ミリ秒)。
    正常に復元されました。

さっきはただ文字列を出しましたが、今度は文字列としてHTMLを出してみましょう。先ほどと同じソースなのでこんな風に変更します

HelloHtmlの作成(cstest上で入力)
    var builder = WebApplication.CreateBuilder(args);
    var app = builder.Build();
    
    app.MapGet("/", (HttpContext context) =>
      {
            context.Response.ContentType = "text/html";
            return """
            <html><head>
            <title>Hello</title>
            </head>
            <body>
            <h1>Hello</h1>
            <p>This is sample page.</p>
            </body>
            </hetml>
            """;
      }
    );
    
    app.Run();

applicationUrlも変更して実行します。

Web Hello

Razorテンプレートのサンプル

workspaceになるcstestフォルダーに移動してその下に作っていきます

HelloRazorの作成(cstest上で入力)
    f710@ras01:~/cstest $ dotnet new webapp -o HelloRazor
    テンプレート "ASP.NET Core Web アプリ" が正常に作成されました。
    このテンプレートには、Microsoft 以外のパーティのテクノロジーが含まれています。詳しくは、https://aka.ms/aspnetcore/7.0-third-party-notices をご覧ください。
    
    作成後の操作を処理しています...
    /home/f710/cstest/HelloRazor/HelloRazor.csproj を復元しています:
      Determining projects to restore...
      /home/f710/cstest/HelloRazor/HelloRazor.csproj を復元しました (709 ミリ秒)。
    正常に復元されました。

Razorは1ページ単位に2つのファイルを組み合わせて作成するアプリケーションです。 *.cshtmlというテンプレートの部分とそれに対応する *.cshtml.csというコードの部分がPagesフォルダーにあることで作動します。

HelloRazorで作られたファイル(Pagesフォルダー)
    f710@ras01:~/cstest/HelloRazor $ ls Pages
    Error.cshtml     Index.cshtml.cs    Shared
    Error.cshtml.cs  Privacy.cshtml     _ViewImports.cshtml
    Index.cshtml     Privacy.cshtml.cs  _ViewStart.cshtml

Error,Index,Privacyの3つのページができています。

applicationUrlだけ変更して実行すると、こんな感じの出力になります。bootstrapが効いています

Web Hello Razor

ソースを眺めてみましょう。

Program.cs
    var builder = WebApplication.CreateBuilder(args);

    // Add services to the container.
    builder.Services.AddRazorPages();
    
    var app = builder.Build();
    
    // Configure the HTTP request pipeline.
    if (!app.Environment.IsDevelopment())
    {
        app.UseExceptionHandler("/Error");
        // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
        app.UseHsts();
    }
    
    app.UseHttpsRedirection();
    app.UseStaticFiles();
    
    app.UseRouting();
    
    app.UseAuthorization();
    
    app.MapRazorPages();
    
    app.Run();

同じWebAplicationで始まっていますが、色々なミドルウェアが追加されています。リダイレクトをつかさどるもの、wwwrootなどの静的ファイルの対応、Pagesフォルダーの中のファイルにアクセスする仕組み、認証機能などです。

Pages/Index.cshtml.cs
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.AspNetCore.Mvc.RazorPages;
    
    namespace HelloRazor.Pages;
    
    public class IndexModel : PageModel
    {
        private readonly ILogger _logger;
    
        public IndexModel(ILogger logger)
        {
            _logger = logger;
        }
    
        public void OnGet()
        {
    
        }
    }

IndexModelというクラスができています。それぞれのファイルが*Modelという名前が付いたクラスになります。

OnGet関数の中にGetが発生したときに行う処理を書きます

Pages/Index.cshtml
    @page
    @model IndexModel
    @{
        ViewData["Title"] = "Home page";
    }
    
    <div class="text-center">
        <h1 class="display-4">Welcome</h1>
        <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
    </div>

先ほどのcsファイルのモデルを使用しています。@pageで始まっています。これがRazorディレクトティブでRazorであることを宣言しています。

classの中に display-4とかあるのは frameworkのbootstarp形式です。これらを組み合わせてRazorの画面を作っています。