WinUI3で前面&フルスクリーンアプリを作ってみる。第2回 実行ファイル作ってみる編

趣旨

常に前面&全画面表示をさせるキオスク的アプリを作りたくて、とりあえず勉強しながら試作品を作ってみた。
プログラムある程度できたのでexeにしてみたかったのだが、ビルドしてできたexeをダブルクリックしても動かん。どうもアンパッケージアプリという形でビルドしないといけないらしく、下記手順でいけた。

ソリューションエクスプローラーでプロジェクトを右クリック、メニューから「プロジェクトファイルを編集」を選択する。

エディタにXMLファイルが表示されたら、<PropertyGroup>に「<WindowsPackageType>None<WindowsPackageType>」と追記する。

「ビルド」リボンから「ソリューションのビルド」を実行して、exeファイルを作る。
できたexeをダブルクリックしてアプリが立ち上がったらおわり。

自分の場合は終われず、このようなエラーが出た。
必要なバージョンのランタイムがインストールされていない環境でも動いてほしかったので、対処する。 先ほど同様、ソリューションエクスプローラーから「プロジェクトファイルを編集」を選択しXMLファイルを表示する。

エディタにXMLファイルが表示されたら、<PropertyGroup>に「<WindowsAppSDKSelfContained>true<WindowsAppSDKSelfContained>」と追記する。
「ビルド」リボンから「ソリューションのビルド」を実行して、exeファイルを作る。 できたexeをダブルクリックで実行できた。(けど同時に作られるdll等と同じディレクトリに格納してないと動かぬ。。。)

実行する環境によっては、もしかしたらWebView2のランタイムが無いよってエラーが出るかも。 アプリ起動時にランタイムをインターネットからダウンロードしてそうで、インターネットに繋がらない環境かつランタイムが未インストールだったら当該エラーが出る気がしている(調査中)。

WinUI3で前面&フルスクリーンアプリを作ってみる。第1回 とりあえずアプリ作ってみる編

趣旨

常に前面&全画面表示をさせるキオスク的アプリを作りたくて、とりあえず勉強しながら試作品を作ってみた。
ウインドウアプリなんてMFCしか使ったことないしC#なんて知らないし。。。という状態から始めたので、全体的にセンス無いかも。
今回は以下機能を持ったアプリをWinUI3で作ってみた。

      • ボタン押すと表示モード切り替わる
      • フルスク時はどのウインドウがアクティブだろうとこのアプリが前面に出てくる
      • フルスク時はタイトルバーを出さない
      • フルスク時はタスクバーまで隠す
      • WebView2を使ってプライマリモニターにのみ本ブログを表示させる

デバック実行中、前面時に例外とか発生して止まっちゃたときは何も見えなっちゃって、そんなときはShift+F5でデバッグモードを終了すればいいのだけど、それにしばらく気が付かずVisualStudioをアクティブにしてAlt+F4で無理やり落としてた。くそぅ。
アプリは本記事執筆後もちょいちょい更新していくつもりで、最新のコードは気が向いたらGitHubにプッシュしておこうかと考え中。
URL:https://github.com/Elizack/KioskLikeApp

(こういう内容ははてなブログよりQiitaとかZennとかに投稿したほうがいいのかな。。。)

XAMLはこれ

<?xml version="1.0" encoding="utf-8"?>
<Window
    x:Class="FullScreenAppTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:FullScreenAppTest"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:controls="using:Microsoft.UI.Xaml.Controls"
    mc:Ignorable="d"
    Title="FullScreenAppTest">


    <Grid x:Name="grid1" HorizontalAlignment="Left" VerticalAlignment="Top">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>

        <StackPanel Orientation="Vertical" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="0" Grid.Column="0">
            <Button x:Name="myButton" Click="myButton_Click">Click Me</Button>
            <TextBlock x:Name="textBlock1">tb1</TextBlock>
        </StackPanel>

        <controls:WebView2 x:Name="MyWebView" Grid.Row="1" Grid.Column="0"
                           Source="https://kedarake-haidarake.hatenablog.jp/" HorizontalAlignment="Stretch"
                           VerticalAlignment="Stretch"/>
    </Grid>

</Window>

CSはこれ(NuGetでWindowsDisplayAPIを入れてる)

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Runtime.InteropServices.WindowsRuntime;
using Microsoft.UI.Windowing;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Navigation;
using Windows.Foundation;
using Windows.Foundation.Collections;

// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.

namespace FullScreenAppTest
{
    /// <summary>
    /// An empty window that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainWindow : Window
    {
        // trueのときフルスクリーンモードにする。
        bool fs_flg = false;

        // フルスクリーン切り替え直前のウインドウ位置、サイズを覚えておく用の変数
        int prev_x = 0, prev_y = 0;
        int prev_width = 0, prev_height = 0;

        public MainWindow()
        {
            this.InitializeComponent();

            _presenter = this.AppWindow.Presenter as OverlappedPresenter;
        }
        private OverlappedPresenter? _presenter;

        private void myButton_Click(object sender, RoutedEventArgs e)
        {
            // ボタン押して画面モードを切り替え
            fs_flg = !fs_flg;
            changeScreenMode();
        }

        private void changeScreenMode()
        {
            if (_presenter is not null)
            {
                _presenter.IsAlwaysOnTop = fs_flg & false; // trueにすると常に前面になる
                _presenter.SetBorderAndTitleBar(hasBorder: !fs_flg, hasTitleBar: !fs_flg);
                _presenter.IsResizable = !fs_flg; // falseにすると画面サイズ変更不可になる
                _presenter.IsMinimizable = fs_flg; // trueにするとディスプレイの端までウインドウをでかくできる
            }

            if (fs_flg)
            {
                myButton.Content = "フルスクリーンモード";

                // フルスクリーンにする直前のウインドウ位置、サイズを覚えておく(再度ボタン押したときに戻すため)
                prev_x = this.AppWindow.Position.X;
                prev_y = this.AppWindow.Position.Y;
                prev_width = this.AppWindow.ClientSize.Width;
                prev_height = this.AppWindow.ClientSize.Height;

                 // WebView2用Gridのサイズをプライマリモニターに収めるためのパラメータ
                double grid_width = 0, grid_height = 0;

                // ディスプレイの左上の座標と、サイズを取得
                int topLeft_x = 0, topLeft_y = 0;
                int width = 0, height = 0;
                foreach(WindowsDisplayAPI.Display disp in WindowsDisplayAPI.Display.GetDisplays())
                {
                    // 左上取得(プライマリモニターが左上に無い場合、xやyにはマイナスがはいるっぽい)
                    topLeft_x = topLeft_x < disp.CurrentSetting.Position.X ? topLeft_x : disp.CurrentSetting.Position.X;
                    topLeft_y = topLeft_y < disp.CurrentSetting.Position.Y ? topLeft_y : disp.CurrentSetting.Position.Y;

                    // 縦幅と横幅合計する
                    width += disp.CurrentSetting.Resolution.Width;
                    height += disp.CurrentSetting.Resolution.Height;

                    // プライマリモニターであれば、WebView2用の設定値に値入れる
                    if(disp.CurrentSetting.Position.X == 0 && disp.CurrentSetting.Position.Y == 0)
                    {
                        grid_width = disp.CurrentSetting.Resolution.Width;
                        grid_height = disp.CurrentSetting.Resolution.Height;
                    }
                }

                // TextBlockにディスプレイの左上と右下の座標を出力(確認用)
                textBlock1.Text = "*1";

                // ウインドウの左上を(min_x,min_y)に、サイズを(width,height)にする。
                this.AppWindow.MoveAndResize(new Windows.Graphics.RectInt32(topLeft_x, topLeft_y, width, height));

                // WebViewの表示範囲をプライマリモニターに収める
                grid1.Translation = new Vector3(Math.Abs(topLeft_x), Math.Abs(topLeft_y), 0); // ウインドウの左上が原点。それに対する相対位置を指定する。
                grid1.Width = grid_width;
                grid1.Height = grid_height;
            }
            else
            {
                myButton.Content = "ウインドウモード";
                this.AppWindow.MoveAndResize(new Windows.Graphics.RectInt32(prev_x, prev_y, prev_width, prev_height));
                grid1.Translation = new Vector3(0, 0, 0);
                grid1.Width = prev_width;
                grid1.Height = prev_height;
            }
        }
    }
}

 

 

 

 

 

*1:" + topLeft_x + "," + topLeft_y + "),(" + width + "," + height + "

VirtualBoxでADサーバの勉強をしてみる。第3回 Moodleサーバ構築編

前書き

Ubuntu 24.04をMoodleサーバにして、ADとの連携まで行う。

いろいろインストール

Apache、MySQL、PHPをインストール

Ubuntuにログインし、以下コマンドを実行する。
sudo apt install apache2 mysql-client mysql-server php libapache2-mod-php

PHPのモジュールをインストール

以下コマンドを実行しPHPのモジュールをインストールする。
sudo apt install graphviz aspell ghostscript clamav php8.3-pspell php8.3-curl php8.3-gd php8.3-intl php8.3-mysql php8.3-xml php8.3-xmlrpc php8.3-ldap php8.3-zip php8.3-soap php8.3-mbstring
終わったらApache2を再起動する。
sudo service apache2 restart

Moodleをダウンロード

まずは下記コマンドでGitをインストールする。
sudo apt install git
Gitがインストールできたら下記コマンドを順に実行していき、Apache2用のフォルダにMoodleを格納するところまで行う。
cd /opt
sudo git clone git://git.moodle.org/moodle.git
cd moodle
sudo git branch -a
sudo git branch –track MOODLE_405_STABLE origin/MOODLE_405_STABLE
sudo git checkout MOODLE_405_STABLE
sudo cp -R /opt/moodle /var/www/html
sudo mkdir /var/moodledata
sudo chmod -R 777 /var/moodledata
sudo chmod -R 0755 /var/www/html/moodle

MySQLをセットアップ

MySQLの設定ファイル(/etc/mysql/mysql.conf.d/mysqld.cnf)の[mysqld]セクション最下部に、以下を追記する。
default_storage_engine = innodb
innodb_file_per_table = 1
以下コマンドでMySQLを再起動する。
sudo service mysql restart
MySQLを起動し、Moodle用のDBとかユーザとか作る。
sudo mysql -u root -p
**Ubuntuにログインしたユーザのパスワードを入力**
MySQLが起動したら以下SQLを実行
CREATE DATABASE moodle DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER ‘moodledude’@’localhost’ IDENTIFIED BY ‘passwordformoodledude’;
GRANT ALL ON moodle.* TO ‘moodledude’@’localhost’ WITH GRANT OPTION;
quit;で終了。

Moodleをセットアップ

Moodle自身で設定ファイルを作れるよう、以下コマンドを打っておく。
sudo chmod -R 777 /var/www/html/moodle
適当なマシンのブラウザから以下のURLにアクセス。
http://192.168.176.4/moodle
Moodleにアクセスできたらセットアップ画面が表示されるので、画面に従って設定を進める。MySQLの設定では、先ほど設定した内容に合わせたものを入力する。 本手順の内容をそのまま実施していたら下図の感じになる。

「max_input_varsは5000以上です!」みたいなメッセージがでたら、php.iniを編集してmax_input_varsを5000以上にする。
自分の場合は「/etc/php/8.3/apache2/php.ini」にあった。(apache2が使うPHPの設定ファイルはここっぽい?)
管理者ユーザの名前とかタイムゾーンとかサイト名とかお好みで入力して完了。

ActiveDirectoryと連携

ADサーバの操作

Windows FirewallでTCP接続を許可する。 コンパネ等からWindows Firewallの設定画面へ遷移し、「受信の規則」に新しい規則を追加する。(プロトコルはTCP、ポート番号は389)

Moodleの管理者用ユーザを作成するため「Active Directoryユーザーとコンピューター」で「Users」を右クリック、「新規作成」→「ユーザー」を選択する。

以下の通りユーザーを作成する。パスワードはP@ssword01にした。

LDAPにアクセスするアカウントを作成するため、先ほどと同じ要領で以下ユーザを作成する。パスワードはP@ssword01にした。

Moodle用のSG(管理者用と講座作成者用)を作成するため「Active Directoryユーザーとコンピューター」で「Users」を右クリック、「新規作成」→「グループ」を選択する。以下2つのグループを作る。

Moodleの設定

適当なマシンのブラウザで以下にアクセス、管理者アカウントでログインする。
http://192.168.176.4/moodle
「サイト管理」タブで「プラグイン」→「認証」→「認証の管理」を選択。

「LDAPサーバ」行の「設定」を選択。「LDAPサーバ設定」-「ホストURL」にドメコンのIPアドレスを入力。

「バインド設定」にさっき作ったLDAPアクセス用のユーザのDNとパスワードを入力。

ユーザルックアップ設定にいろいろ入力する。


システムロールマッピングにMoodle用に作ったSGを設定する。

データマッピングはメアドまで設定し、そこから下はデフォルトのまま。

ドメインユーザでのログインは、ユーザログオン名でできる。 任意のユーザでログインできることを確認し今回は終。(SGは使ってないけど。。。)

VirtualBoxでADサーバの勉強をしてみる。第2回 ADサーバ構築編

前書き

前回セットアップしたWindows ServerをADサーバにして、OUとドメインユーザの作成まで行う。 下図のような構成を目指す。

ADのインストール

サーバーマネージャーのダッシュボードから、「役割と機能の追加」をクリック。表示されたウィザードで「役割ベースまたは機能ベースのインストール」を選択。
「サーバーの役割の選択」まで進んだら、「Active Directoryドメインサービス」と「DNSサーバー」を選択して「次へ」。

進めていってインストール完了したら、「このサーバーをドメインコントローラーに昇格する」をクリック。

「新しいフォレストを追加する」を選んで、ルートドメイン名に「animals.local」を入力。

機能レベルに「Windows Server 2016」を選択して、パスワードを入力。

NetBIOSドメイン名に「ANIMALS」と入力。

以降はデフォルトのままインストール完了まで進める。

Windows 10の設定を更新

Windows 10のVMを起動。「ネットワーク設定」でイーサネットを選択して、IP設定でIPv4の「優先DNS」にドメコンのIPアドレスを入力する。

VMをドメインに参加させるため、「設定」→「システム」→「詳細情報」→「システムの詳細設定」と進み、表示されたダイアログで「変更」をクリック。

「所属するグループ」を「ドメイン」にし、さっき作ったドメイン名を入力する。

権限あるアカウントの名前とパスワードを求められるので、Windows Serverにログインできるアカウントの名前とパスワードを入力する。ドメイン名が表示されたら完了。

OUを作る

Windows Serverにログイン、サーバーマネージャーの「ツール」→「ActiveDirectoryユーザとコンピュータ」を選択。ドメイン名を右クリックしたら、「新規作成」→「組織単位(OU)」と選択する。

「名前」に「イヌネコOU」と入力。

同じ要領で「ニンゲンOU」、「イヌOU」、「ネコOU」を作る。OUのツリーが下図の感じになればOK。

ドメインユーザーを作る

「ActiveDirectoryユーザーとコンピューター」の画面でさっき作った「イヌOU」を右クリック、「新規作成」→「ユーザー」を選択。

ダイアログに従いユーザを作る。

Windows 10を起動し先ほど作ったユーザにログインできることを確認し完了。 同じ要領でほかのユーザも作って終。

VirtualBoxでADサーバの勉強をしてみる。第1回 VM作成編

前書き

今回は前回インストールしたVirtualBoxで仮想マシンの作成とNW設定まで行う。

Windows 10のセットアップ

VMを作成

VirtualBoxを起動して、「ツール」から「新規」を選択する。
VMの名前、ホストOS上の保存フォルダを選択する。ISOイメージはまだ選択しない。

ハードウェアはメモリ4GB、CPUは2コア、ストレージは500GBにした。(ホストOSの性能に合わせてください。。。)

VMができたらWindows 10のISOをマウントする。さっき作ったVMを選択し、「設定」→「ストレージ」と選択。「属性」欄右側のディスクアイコンをクリックして、「仮想光学ディスクの選択/作成」を選択する。
ISO選択のダイアログが出るので、Windows10のISOを選択して「選択」を押下する。もし一覧に出ていない場合は、左上の「追加」ボタンを押して、一覧に追加する。

Windows 10のインストール

VMを起動するとWindows 10のインストールが始まる。(はず)
インストールウィザードに従って進めていく。アカウントのセットアップをし、デスクトップまで遷移できたら完了。

Windows Server 2022のセットアップ

Windows 10とほぼ同じ手順。インストーラではオプションを選ばされるが、GUIが欲しいので「Windows Server 2022 Standard Evaluation(デスクトップエクスペリエンス)」を選択した。

Ubuntu 24.04のセットアップ

VMを作成

ISO選択の直前まではWindows 10、Windows Server 2022と同じ手順。
ISOの選択が少し違う。作ったVMを選択し、「設定」→「ストレージ」と選択。「コントローラー:IDE」の下にある「空」を選択後、右側ペインの「属性」-「光学ドライブ」の右側にあるディスクのアイコンをクリック。「仮想光学ディスクの選択/作成」をクリックする。

Ubuntu 24.04のISOを選択して完了。

Ubuntu 24.04のインストール

VMを起動するとまずブートローダーが起動するので、「Try or Install Ubuntu」を選択してEnterを押す。インストールが始まるので、指示に従って進める。

NWの設定をする

VMの設定を変更

今回は、ホストOSとゲストOSの通信をできるようにし、ゲストOSからはインターネットに接続できないようにする(Ubuntu以外)。
IPアドレス変わるのめんどいので、DHCPは無効、ゲストOSには固定IPアドレスを使ってもらう。
まずVirtualBoxの「ツール」を右クリック、「ネットワークマネージャー」を選択する。「作成」をクリックし、下記の通りホストオンリーアダプターを作成する。DHCPは無効にする。

作った3つのVMをそれぞれホストオンリーアダプターに接続する。もしVMが起動してたらシャットダウンしておく。 設定更新したいVMを選んだ状態で「設定」→「ネットワーク」を選択。アダプター2にさっき作ったホストオンリーアダプターを設定する。

WindowsとWindows Serverはインターネットにつながないのでアダプター1(NAT)を無効にしておく。

Windows 10のIPアドレスを固定する

VMを起動。ログインしたら「設定」→「ネットワークとインターネット」→「イーサネット」と選択。

「識別されていないネットワーク」をクリック、「IP設定」の下にある「編集」ボタンを押す。「手動」を選び、下記の通り入力する。(IPアドレスはホストオンリーアダプターの設定に合わせる。)
ホストマシンからpingが通ることを確認し、完了。もしpingが通らなかったらおそらくWindows Firewallの問題。「受信の規則」→「ファイルとプリンターの共有(エコー共有-ICMPv4受信)」を有効にすれば通るはず。

Windows Server 2022のIPアドレスを固定する

VMを起動。ログインしたら「サーバマネージャー」→「ローカルサーバー」と選択。「イーサネット2」のとこにある「IPv4アドレス(DHCPにより割り当て)、IPv6(有効)」をクリック。

ネットワーク接続の設定画面が出てくるので「イーサネット2」を選択。表示されたダイアログの「プロパティ」をクリックする。

次のダイアログが出てきたら「インターネットプロトコルバージョン4(TPC/IPv4)」を選んで「プロパティ」をクリック。以下の通り入力する。

ホストOS、ゲストOSそれぞれからpingが通ることを確認し完了。

Ubuntu 24.04のIPアドレスを固定する

VMを起動。ログインしたらネットワーク設定の画面を開く。ホストオンリーアダプターに繋がってる方のEthernet接続を選択して、下記の通り入力して完了。

ホストOS、ゲストOSのそれぞれからpingが通ることを確認して今回は終。

VirtualBoxでADサーバの勉強をしてみる。第0回 準備編

前書き

ActiveDirectoryについてネットで調べてみたものの、百聞は一見に如かずと思い、持て余していたデスクトップにADサーバを立ててみた。
誰かの役に立てたらいいなーと思いやったことをブログに残してみる。(全○○回)

本記事では最終的に、VirtualBox上に、Windows 10、Windows Server 2022、Ubuntu 24.04のVMを用意し、ADと連携したE-Learningサイト(Moodle)を作ってみる。

構成

VMの構成

ホストOSにVirtualBoxをインストール、VirtualBox上に仮想マシン3台(Windows 10、Windows Server 2022、Ubuntu 24.04)を作る。

 

NWの構成

ホストOS、ゲストOS間はそれぞれ相互に通信可能にする。ゲストOSのうちWindowsとWindows Serverはインターネットに接続しない。Ubuntuはライブラリ等のインストールが頻発するので、随時インターネットに接続できるようにしておく。図にすると以下のイメージ(たぶん)。

必要なものをダウンロード

VirtualBox

以下のページにアクセスしてインストーラーをDLする。DLできたらウィザードに従ってインストールする。途中で「ネットが一時的に繋がらなくなるぞ!」みたいな警告が出ても臆さない。
https://www.virtualbox.org/wiki/Downloads

ISO

Windows 10のISO

ブラウザを起動し下記ページにアクセス。
https://www.microsoft.com/ja-jp/software-download/windows10
Windows上のブラウザからDLしようとすると、ISO作るためのツールをインストールさせられてしまう。それが嫌な人は開発者ツールからiPad Pro用の画面を開けばOK。64bit版、日本語のWindows 10のISOがDLできる。

Windows Server 2022のISO

ブラウザを起動し下記ページにアクセス。
https://www.microsoft.com/ja-jp/evalcenter/download-windows-server-2022
64bit版、日本語のWindows Server 2022のISOをDLする。

UbuntuのISO

ブラウザを起動し下記ページにアクセス。
https://ubuntu.com/download/desktop
64bit版のUbuntu 24.04のISOをDLする。