カテゴリー
プログラム 社内SE

Outlookのフォルダ構成ごとメールを取り出す方法

Outlookのメールだけならドラッグ&ドロップすれば、Windowsのフォルダへコピー可能だが、フォルダ毎ドラッグしてもWindowsのファイルシステムへコピーすることはできない。

これを実現するにはマクロでコピーするしかない。こんなこと通常やる必要は全くないのだが、ボケた上役の命令でやる機会があったので一応記録を残しておく。

Outlookでマクロを有効にための事前準備は以下。

  • [ファイル]-[オプション]-[トラストセンター]で[トラストセンターの設定]を開く
  • [マクロの設定]で[全てのマクロに対して警告を表示する]以下を選択する。
  • Outlookを再起動する。
  • [Alt]+[F11]でVBAの画面を開く
  • VBA画面で[ツール]-[参照設定]で開く画面から[Microsoft Scripting Runtime]を探し、チェックし[OK]をクリックする。
  • VBA画面で[挿入]-[標準モジュール]をクリックする。

ここまでで、左側のパネルでModule1という箇所が選択され、右側のパネルにVBAのプログラムが書けるようになるので、以下のプログラムをコピペする。

Dim objFSO As Scripting.FileSystemObject

Sub ExportOutlookFolders()
    Dim objFolder As Outlook.Folder
    Dim strFolderPath As String
    strFolderPath = SelectAnExportFolder()
    If strFolderPath = "" Then
        MsgBox "出力するフォルダを選択してください。", vbInformation + vbOKOnly, "フォルダ選択"
    Else
        Set objFSO = New Scripting.FileSystemObject
        Set objFolder = Outlook.Application.ActiveExplorer.CurrentFolder
        ExportAnOutlookFolder objFolder, strFolderPath
    End If
    Set objFolder = Nothing
    Set objFSO = Nothing
End Sub

Sub ExportAnOutlookFolder(ByVal OutlookFolder As Outlook.Folder, strFolderPath As String)
    Dim objSubFld As Outlook.Folder
    Dim objItem As Object
    Dim strPath As String
    Dim strFilePath As String
    Dim strSubject As String
    Dim strFilename As String
    Dim strRecievedTime As String
    Dim nCount As Long
    On Error Resume Next
    strPath = strFolderPath & "\" & ReplaceInvalidCharacters(OutlookFolder.Name)
    If Dir(strPath, 16) = Empty Then MkDir strPath

    nCount = 0

    For Each objItem In OutlookFolder.Items
        strSubject = ReplaceInvalidCharacters(objItem.Subject)
        If strSubject = "" Then
            strSubject = "notitle"
        End If
        strRecievedTime = Format(objItem.ReceivedTime, "yyyymmddhhnnss")
        strFilename = strRecievedTime & "_" & strSubject & ".msg"
        strFilePath = strPath & "\" & strFilename
        If objFSO.FileExists(strFilePath) Then
            nCount = nCount + 1
            strFilename = strRecievedTime & "_" & strSubject & " (" & nCount & ").msg"
            strFilePath = strPath & "\" & strFilename
        End If
        objItem.SaveAs strFilePath, olMSG
        
        DoEvents
    Next

    For Each objSubFld In OutlookFolder.Folders
        ExportAnOutlookFolder objSubFld, strPath
    Next
    Set OutlookFolder = Nothing
    Set objItem = Nothing
End Sub

Function SelectAnExportFolder() As String
    Dim objSelFolder As Object
    Dim objShell As Object
    Set objShell = CreateObject("Shell.Application")
    Set objSelFolder = objShell.BrowseForFolder(0, "Select a folder", 0, 0)
    If Not TypeName(objSelFolder) = "Nothing" Then
        SelectAnExportFolder = objSelFolder.self.Path
    End If
    Set objSelFolder = Nothing
    Set objShell = Nothing
End Function

Function ReplaceInvalidCharacters(Str As String) As String
    Dim objRegEx As Object
    Set objRegEx = CreateObject("vbscript.regexp")
    objRegEx.Global = True
    objRegEx.IgnoreCase = False
    objRegEx.Pattern = "\||\/|\<|\>|""|:|\*|\\|\?"
    ReplaceInvalidCharacters = objRegEx.Replace(Str, "_")
    Set objRegEx = Nothing
End Function

ここまでが終わったら、

  • Outlookの画面に戻り、コピーしたいフォルダを選択する
  • VBAの画面に戻り、一番上の「ExportOutlookFolders」という関数にカーソルを合わせる。(下図のように上部に[General]と[ExportOutlookFolders]が選択されたらOK。)
  • その後、下図の左上、赤丸内の緑の再生ボタンをクリックすると、Windows側の出力先のフォルダ選択画面が表示されるので、選択するとフォルダ構成毎、Windows側にコピーされる。
マクロ実行方法

プログラムとしては、「今Outlookで選択されているフォルダを、指定のフォルダに出力する」という処理を行っている。出力されるファイル名は「メールの受け取り時刻+件名」になる。

カテゴリー
その他 社内SE

collabora onlineの高速化

NextCloudのインストール時にcollabora onlineのインストールも行ったのだが、デフォルトの設定では遅く、設定を修正しパフォーマンスを上げた。

以下その記録。

前提

collabora online自体は、proxyの背後で、フロントから127.0.0.1:9980に接続。SSLは以下の設定でオフ。(proxyがSSL処理)

loolconfig set ssl.enable false
loolconfig set ssl.termination true
loolconfig set storage.wopi.host your.nextcloud.domain

公式のガイドもproxy前提のようなので、proxyで設定している。

設定

要点としては、設定XMLの以下3箇所を修正する。

  • allowed_languagesでサポート言語をen_USのみに変更
  • net.protoでipv6を使用せず、ipv4のみとする。(proxyなのでipv6はアクセスなし)
  • 初期起動数(num_prespawn_children)を増やす。(最重要 正直ここだけで良いはず。)

以下のXMLファイルを直接編集する。

vi /etc/coolwsd/coolwsd.xml

XMLファイルの修正点は以下。(修正箇所のみ抜粋)

<!-- 1箇所目 元は以下 -->
<!-- allowed_languages default="de_DE en_GB en_US es_ES fr_FR it nl pt_BR pt_PT ru" desc="List of supported languages of Writing Aids (spell checker, grammar checker, thesaurus, hyphenation) on this instance. Allowing too many has negative effect on startup performance.">de_DE en_GB en_US es_ES fr_FR it nl pt_BR pt_PT ru</allowed_languages -->
<allowed_languages default="en_US" desc="List of supported languages of Writing Aids (spell checker, grammar checker, thesaurus, hyphenation) on this instance. Allowing too many has negative effect on startup performance.">en_US</allowed_languages>

<!-- 2箇所目 元は以下 -->
<!--proto default="all" desc="Protocol to use IPv4, IPv6 or all for both" type="string">all</proto-->
<proto default="all" desc="Protocol to use IPv4, IPv6 or all for both" type="string">IPv4</proto>

<!-- 3箇所目 元は以下 10人ぐらいしか同時接続しないとみて、1から10に変更-->
<!-- num_prespawn_children default="1" desc="Number of child processes to keep started in advance and waiting for new clients." type="uint">1</num_prespawn_children-->
<num_prespawn_children default="1" desc="Number of child processes to keep started in advance and waiting for new clients." type="uint">10</num_prespawn_children>

カテゴリー
その他 社内SE

外部の公開サーバでvscode serverを使ってみた

Visual Studio codeのserver版がpreviewながら公式からリリースされたので、SSL/TLS+Basic認証/クライアント認証を施し、systemdのサービスとして起動するように手持ちのVPSサーバ上に設定してみた。

これでブラウザがあれば、どこからでもサーバのファイルを編集できるようになった。

設定方法 (Ubuntu 20.04使用)

フロントエンドにNginxをReverse Proxyとして設定し、ここでSSLなどのセキュリティをかける。VS code server自体はバックエンドにする。Websocketが通らないため、Apacheをフロントエンドにはできないので注意。

Visual Studio code server 設定

以下のようにインストールした後、サービスとして登録するため、systemdファイルを作成する。

# インストール
sudo wget -O- https://aka.ms/install-vscode-server/setup.sh | sh

# systemd unitファイル作成 途中のUser/Groupは書き換えること。
sudo vi /lib/systemd/system/vscodeserver.service
---
[Unit]
Description=vs code server
After=network-online.target

[Service]
ExecStart=/usr/local/bin/code-server serve-local --accept-server-license-terms --disable-telemetry
Restart=always
User=yourUserName
Group=yourGroupName
UMask=002

[Install]
WantedBy=multi-user.target
---

systemdに登録し実行する。(上のunitdファイルに記述したユーザ/グループで実行される。)

# 登録
sudo systemctl enable vscodeserver
# 開始
sudo systemctl start vscodeserver

初回起動時のみ起動に時間がかかるため、1,2分待ち、起動した後に表示される接続先のURLを取得しておく。

# statusの中のWeb UI available atにあるURLを取得する。
sudo systemctl status vscodeserver
---
Jul 13 07:20:14 devserver001 code-server[367393]: Server bound to 127.0.0.1:8000 (IPv4)
Jul 13 07:20:14 devserver001 code-server[367393]: Extension host agent listening on 8000
Jul 13 07:20:14 devserver001 code-server[367393]: Web UI available at http://localhost:8000/?tkn=6de5345a-b644-48cd-a7f9-3433bcc031e3
Jul 13 07:20:14 devserver001 code-server[367393]: [07:20:14] Extension host agent started.
Jul 13 07:20:14 devserver001 code-server[367393]: [07:20:14] Deleted from disk ms-ceintl.vscode-language-pack-ja /home/yourname/.vscode-server/extensions/ms-ceintl.vscode-language-pack-ja-1.67.3
Jul 13 07:20:14 devserver001 code-server[367393]: [07:20:14] Deleted from disk xdebug.php-debug /home/yourname/.vscode-server/extensions/xdebug.php-debug-1.26.1
---

ここでは、http://localhost:8000/?tkn=6de5345a-b644-48cd-a7f9-3433bcc031e3であるのでこれを控えておく。

上の「sudo systemctl status vscodeserver」で「Web UI available at」の行が見つからない場合は、「journalctl –no-pager | grep -e ‘code-server’」で起動時間あたりの情報を探すこと。

Nginx設定

Nginxにはリバースプロキシ、SSL、Basic認証(もしくはクライアント認証)を設定する。SSLの各種ファイルはLet’s Encryptなどで取得済みとする。

Nginxをインストールしていない場合はインストール

sudo apt install nginx

基本の設定ファイルを設定する。このあたりは各自の環境に合わせて設定してほしい。私のサーバは私一人しか使わないため最小限の設定にしている。デフォルトでも問題ないはず。

sudo vi /etc/nginx/nginx.conf
---
user yourUser yourGroup;
worker_processes 1;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
        worker_connections 50;
        multi_accept on;
}

http {

        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 3;
        types_hash_max_size 2048;
        server_tokens off;

        include /etc/nginx/mime.types;
        default_type application/octet-stream;

        ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
        ssl_prefer_server_ciphers on;
        access_log off;
        error_log /var/log/nginx/error.log;

        include /etc/nginx/sites-enabled/*;
}
---

Basic認証の下準備。

# basic認証
sudo apt install apache2-utils
sudo htpasswd -c /etc/nginx/.htpasswd testuser
# ここでBasic認証のパスワードを設定する。testuser/設定passwordがbasic認証のログインアカウントになる。

以下が肝心の設定ファイル。Basic認証でやる場合は以下。server_name、ssl_certificateとssl_certificate_keyは変更のこと。

# virtual host
sudo vi /etc/nginx/sites-available/vscodeFront
---
server {
    listen 443 ssl http2;
    server_name yourServerName.com;

    # SSL 環境に応じて変更のこと
    ssl_certificate     /etc/letsencrypt/live/yourServerName.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourServerName.com/privkey.pem;

    location / {
        auth_basic "Restricted";
        auth_basic_user_file /etc/nginx/.htpasswd;

        proxy_pass http://127.0.0.1:8000/;
        proxy_set_header Host $http_host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_redirect off;

    }
}
---

クライアント認証の場合だと以下。クライアント認証の作り方は割愛。

sudo vi /etc/nginx/sites-available/vscodeFront
---
server {
    listen 443 ssl http2;
    server_name yourServerName.com;

    # server側
    ssl_certificate     /etc/letsencrypt/live/yourServerName.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourServerName.com/privkey.pem;

    # client認証
	ssl_verify_client on;
	ssl_client_certificate /opt/myCA/cacert.pem;
	ssl_crl /opt/myCA/crl.pem;

    location / {

        proxy_pass http://127.0.0.1:8000/;
        proxy_set_header Host $http_host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_redirect off;

    }
}
---

設定が終わったら、virtual hostの設定を有効にして、Nginx再起動。

sudo ln -s /etc/nginx/sites-available/vscodeFront /etc/nginx/sites-enabled/
sudo systemctl restart nginx

ここで、VS code serverの設定時に控えておいた「http://localhost:8000/?tkn=6de5345a-b644-48cd-a7f9-3433bcc031e3」の?から下の部分(赤色部分)を切り取り、https://yourServerName.com/?tkn=6de5345a-b644-48cd-a7f9-3433bcc031e3にアクセスするとVS code serverが表示される。

Port 8000は外部からアクセスできないようにしておくこと。

感想

現時点では、vscode serverの非公式WEB版であるCoderのcode-serverのほうが若干動作が軽く、日本語化もできるので使いやすい。ただ、こちらのvscode serverは公式なので、いずれ非公式のCoder版は廃れる気がする。公式版の不満点としては、使えない拡張機能があることと、日本語化できないことであるが、まだpreview版なのでいずれ対応してくれるのでは、という期待がある。

とりあえず、Coder版から乗り換えた。

カテゴリー
その他 社内SE

chromebook FireFoxの公式インストール Flatpak

Chromebookに使い勝手の良いデスクトップ版のFirefoxをインストールするには、LinuxのFlatpakでインストールするのが一番簡単である。

ただ、以前のFirefoxの公式ページにあるChromebook/ChromeOSへのFlatpak Firefoxのインストール方法に誤りがあり、インストールしても、ひと手間かけないと、Firefoxの起動ができなかった。その対策の記事を書こう書こうと思っているうちに、現在の公式ページが修正され、正しいインストール方法が記載されるようになってしまった。

悔しいので、私も以下にデスクトップ版のFirfoxインストール方法を示す。

1)[設定]-[デベロッパー]のページの[Linux開発環境]をONにする。(細かい方法はいろんなサイトに書いてあるので割愛。ディスクサイズは自動拡張されるのでデフォルトの10GBで良い。)

2)ブラウザのchromeを立ち上げ[Ctrl + Alt + t]でcroshタブを立ち上げる。

3)chroshタブで以下のコマンドを打つ。

vsh termina
lxc config set penguin security.nesting true
exit

4)Chromebook / ChromeOSを再起動する。(電源OFFしON)

5)ターミナルを起動する。(検索ランチャーでterminalと打つと出てくる)

6)ターミナルで以下のコマンドを打つ

sudo apt install flatpak
flatpak --user remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
flatpak install firefox
# この後、どの種類のfirefoxをインストールするか選択肢が出るはず。
# stableという言葉が含まれている行の番号を入力するとOK。

これで検索ランチャーでFirefoxと検索するとFirefoxが出てきて起動できるようになる。

おまけ:Linuxを日本語環境にしてあげれば、Firefoxで日本語も使えるはずである。私は日本語化した後に上記インストールしたので多分としか言えないが、日本語が使えないようであれば、一旦、「flatpak uninstall org.mozilla.firefox」でfirefoxをアンインストールし、Linuxを日本語化した後、再度「flatpak install firefox」をすれば大丈夫だと思う。

ChromebookのLinuxの日本語環境化も探せば色々出てくるかと思うが、ターミナルでだいたい以下の感じのコマンドを打つ。

sudo apt install task-japanese fonts-ipafont locales-all
sudo localectl set-locale LANG=ja_JP.UTF-8
# ここで再起動
#(ターミナルのアイコンを右クリックで[Linuxをシャットダウン]をクリック、再度ターミナル起動)
sudo apt install fcitx-mozc
sudo vim /etc/systemd/user/cros-garcon.service.d/cros-garcon-override.conf
#---
# 以下を上のファイルの最後に追加
Environment="GTK_IM_MODULE=fcitx"
Environment="QT_IM_MODULE=fcitx"
Environment="XMODIFIERS=@im=fcitx"
Environment="GDK_BACKEND=x11"
#---

vim ~/.sommelierrc
#---
# 上のファイルに以下1行追加
/usr/bin/fcitx-autostart
#---
# 再起動(シェルフのアイコンを右クリックで[Linuxをシャットダウン]、以下略)

# fcitxの設定
fcitx-configtool

# GUIになるので、以下設定
#1.) [アドオン]タブで [Advanced] チェックボックスをオン
#2.) 一覧から [Fctix XIM Frontend] を選択してダイアログを開く
#3.) 「XIM で On The Spot スタイルを使う(起動中は変更できません)」チェックボックスをオン

カテゴリー
その他 社内SE

Code-server keyboad Layout 日本語化

VPSに入れてあるUbuntuにCode-serverをインストールして、ブラウザからアクセスしたところ、キーボードショートカットがうまく動かない。ターミナルを開く「Ctrl+Shift+@」を押しても反応がない。手元の日本語キーボードをCode-serverがUSのキーボードと認識しているのが原因のようだ。Keyboad Layoutをjaに変更したいのだが、表示される選択欄にjaはない。VPS上のUbuntuを日本語環境にしてみたりしたが効果がない。

仕方がないのでVS-CODEを立ち上げ、そこのKeyboad Layoutをまるっとコピーしたら、問題が解決した。

以下、方法を備忘録。

code-server 右下のLayout: USとなっているところをクリックします。
右下のLayoutがUS

上の画像の箇所をクリックすると、Keyboad Layoutの変更ができるので、そこで「Configure Keyboad Layout」を選択。

表示されたKeyboad Layoutの切り替え一覧から「Configure Keyboad Layout」を選択します。

表示されるkeyboadlayout.jsonに以下をコピーペーストし保存。(長いコードの下に設定の続きあり。)

{
	"layout": {
		"name": "00000411",
		"id": "",
		"text": "Japanese"
	},
	"rawMapping": {
		"Sleep": {
			"vkey": "VK_SLEEP",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"WakeUp": {
			"vkey": "VK_UNKNOWN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyA": {
			"vkey": "VK_A",
			"value": "a",
			"withShift": "A",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyB": {
			"vkey": "VK_B",
			"value": "b",
			"withShift": "B",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyC": {
			"vkey": "VK_C",
			"value": "c",
			"withShift": "C",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyD": {
			"vkey": "VK_D",
			"value": "d",
			"withShift": "D",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyE": {
			"vkey": "VK_E",
			"value": "e",
			"withShift": "E",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyF": {
			"vkey": "VK_F",
			"value": "f",
			"withShift": "F",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyG": {
			"vkey": "VK_G",
			"value": "g",
			"withShift": "G",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyH": {
			"vkey": "VK_H",
			"value": "h",
			"withShift": "H",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyI": {
			"vkey": "VK_I",
			"value": "i",
			"withShift": "I",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyJ": {
			"vkey": "VK_J",
			"value": "j",
			"withShift": "J",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyK": {
			"vkey": "VK_K",
			"value": "k",
			"withShift": "K",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyL": {
			"vkey": "VK_L",
			"value": "l",
			"withShift": "L",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyM": {
			"vkey": "VK_M",
			"value": "m",
			"withShift": "M",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyN": {
			"vkey": "VK_N",
			"value": "n",
			"withShift": "N",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyO": {
			"vkey": "VK_O",
			"value": "o",
			"withShift": "O",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyP": {
			"vkey": "VK_P",
			"value": "p",
			"withShift": "P",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyQ": {
			"vkey": "VK_Q",
			"value": "q",
			"withShift": "Q",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyR": {
			"vkey": "VK_R",
			"value": "r",
			"withShift": "R",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyS": {
			"vkey": "VK_S",
			"value": "s",
			"withShift": "S",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyT": {
			"vkey": "VK_T",
			"value": "t",
			"withShift": "T",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyU": {
			"vkey": "VK_U",
			"value": "u",
			"withShift": "U",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyV": {
			"vkey": "VK_V",
			"value": "v",
			"withShift": "V",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyW": {
			"vkey": "VK_W",
			"value": "w",
			"withShift": "W",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyX": {
			"vkey": "VK_X",
			"value": "x",
			"withShift": "X",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyY": {
			"vkey": "VK_Y",
			"value": "y",
			"withShift": "Y",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KeyZ": {
			"vkey": "VK_Z",
			"value": "z",
			"withShift": "Z",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Digit1": {
			"vkey": "VK_1",
			"value": "1",
			"withShift": "!",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Digit2": {
			"vkey": "VK_2",
			"value": "2",
			"withShift": "\"",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Digit3": {
			"vkey": "VK_3",
			"value": "3",
			"withShift": "#",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Digit4": {
			"vkey": "VK_4",
			"value": "4",
			"withShift": "$",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Digit5": {
			"vkey": "VK_5",
			"value": "5",
			"withShift": "%",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Digit6": {
			"vkey": "VK_6",
			"value": "6",
			"withShift": "&",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Digit7": {
			"vkey": "VK_7",
			"value": "7",
			"withShift": "'",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Digit8": {
			"vkey": "VK_8",
			"value": "8",
			"withShift": "(",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Digit9": {
			"vkey": "VK_9",
			"value": "9",
			"withShift": ")",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Digit0": {
			"vkey": "VK_0",
			"value": "0",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Enter": {
			"vkey": "VK_RETURN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Escape": {
			"vkey": "VK_ESCAPE",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Backspace": {
			"vkey": "VK_BACK",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Tab": {
			"vkey": "VK_TAB",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Space": {
			"vkey": "VK_SPACE",
			"value": " ",
			"withShift": " ",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Minus": {
			"vkey": "VK_OEM_MINUS",
			"value": "-",
			"withShift": "=",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Equal": {
			"vkey": "VK_OEM_7",
			"value": "^",
			"withShift": "~",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"BracketLeft": {
			"vkey": "VK_OEM_3",
			"value": "@",
			"withShift": "`",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"BracketRight": {
			"vkey": "VK_OEM_4",
			"value": "[",
			"withShift": "{",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Backslash": {
			"vkey": "VK_OEM_6",
			"value": "]",
			"withShift": "}",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Semicolon": {
			"vkey": "VK_OEM_PLUS",
			"value": ";",
			"withShift": "+",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Quote": {
			"vkey": "VK_OEM_1",
			"value": ":",
			"withShift": "*",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Backquote": {
			"vkey": "VK_UNKNOWN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Comma": {
			"vkey": "VK_OEM_COMMA",
			"value": ",",
			"withShift": "<",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Period": {
			"vkey": "VK_OEM_PERIOD",
			"value": ".",
			"withShift": ">",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Slash": {
			"vkey": "VK_OEM_2",
			"value": "/",
			"withShift": "?",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"CapsLock": {
			"vkey": "VK_UNKNOWN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F1": {
			"vkey": "VK_F1",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F2": {
			"vkey": "VK_F2",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F3": {
			"vkey": "VK_F3",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F4": {
			"vkey": "VK_F4",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F5": {
			"vkey": "VK_F5",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F6": {
			"vkey": "VK_F6",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F7": {
			"vkey": "VK_F7",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F8": {
			"vkey": "VK_F8",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F9": {
			"vkey": "VK_F9",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F10": {
			"vkey": "VK_F10",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F11": {
			"vkey": "VK_F11",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F12": {
			"vkey": "VK_F12",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"PrintScreen": {
			"vkey": "VK_SNAPSHOT",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"ScrollLock": {
			"vkey": "VK_SCROLL",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Pause": {
			"vkey": "VK_NUMLOCK",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Insert": {
			"vkey": "VK_INSERT",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Home": {
			"vkey": "VK_HOME",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"PageUp": {
			"vkey": "VK_PRIOR",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Delete": {
			"vkey": "VK_DELETE",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"End": {
			"vkey": "VK_END",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"PageDown": {
			"vkey": "VK_NEXT",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"ArrowRight": {
			"vkey": "VK_RIGHT",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"ArrowLeft": {
			"vkey": "VK_LEFT",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"ArrowDown": {
			"vkey": "VK_DOWN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"ArrowUp": {
			"vkey": "VK_UP",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"NumLock": {
			"vkey": "VK_UNKNOWN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"NumpadDivide": {
			"vkey": "VK_DIVIDE",
			"value": "/",
			"withShift": "/",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"NumpadMultiply": {
			"vkey": "VK_MULTIPLY",
			"value": "*",
			"withShift": "*",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"NumpadSubtract": {
			"vkey": "VK_SUBTRACT",
			"value": "-",
			"withShift": "-",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"NumpadAdd": {
			"vkey": "VK_ADD",
			"value": "+",
			"withShift": "+",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"NumpadEnter": {
			"vkey": "VK_RETURN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Numpad1": {
			"vkey": "VK_END",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Numpad2": {
			"vkey": "VK_DOWN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Numpad3": {
			"vkey": "VK_NEXT",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Numpad4": {
			"vkey": "VK_LEFT",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Numpad5": {
			"vkey": "VK_CLEAR",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Numpad6": {
			"vkey": "VK_RIGHT",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Numpad7": {
			"vkey": "VK_HOME",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Numpad8": {
			"vkey": "VK_UP",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Numpad9": {
			"vkey": "VK_PRIOR",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Numpad0": {
			"vkey": "VK_INSERT",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"NumpadDecimal": {
			"vkey": "VK_DELETE",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"IntlBackslash": {
			"vkey": "VK_UNKNOWN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"ContextMenu": {
			"vkey": "VK_APPS",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Power": {
			"vkey": "VK_UNKNOWN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"NumpadEqual": {
			"vkey": "VK_CLEAR",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F13": {
			"vkey": "VK_F13",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F14": {
			"vkey": "VK_F14",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F15": {
			"vkey": "VK_F15",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F16": {
			"vkey": "VK_F16",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F17": {
			"vkey": "VK_F17",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F18": {
			"vkey": "VK_F18",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F19": {
			"vkey": "VK_F19",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F20": {
			"vkey": "VK_F20",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F21": {
			"vkey": "VK_F21",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F22": {
			"vkey": "VK_F22",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F23": {
			"vkey": "VK_F23",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"F24": {
			"vkey": "VK_F24",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Help": {
			"vkey": "VK_UNKNOWN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Undo": {
			"vkey": "VK_UNKNOWN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Cut": {
			"vkey": "VK_UNKNOWN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Copy": {
			"vkey": "VK_UNKNOWN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Paste": {
			"vkey": "VK_UNKNOWN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"AudioVolumeMute": {
			"vkey": "VK_VOLUME_MUTE",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"AudioVolumeUp": {
			"vkey": "VK_VOLUME_UP",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"AudioVolumeDown": {
			"vkey": "VK_VOLUME_DOWN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"NumpadComma": {
			"vkey": "VK_ABNT_C2",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"IntlRo": {
			"vkey": "VK_OEM_102",
			"value": "\\",
			"withShift": "_",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"KanaMode": {
			"vkey": "VK_UNKNOWN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"IntlYen": {
			"vkey": "VK_OEM_5",
			"value": "\\",
			"withShift": "|",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Convert": {
			"vkey": "VK_CONVERT",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"NonConvert": {
			"vkey": "VK_NONCONVERT",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Lang1": {
			"vkey": "VK_UNKNOWN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Lang2": {
			"vkey": "VK_UNKNOWN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Lang3": {
			"vkey": "VK_UNKNOWN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Lang4": {
			"vkey": "VK_UNKNOWN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"ControlLeft": {
			"vkey": "VK_CONTROL",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"ShiftLeft": {
			"vkey": "VK_SHIFT",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"AltLeft": {
			"vkey": "VK_MENU",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"MetaLeft": {
			"vkey": "VK_LWIN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"ControlRight": {
			"vkey": "VK_CONTROL",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"ShiftRight": {
			"vkey": "VK_SHIFT",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"AltRight": {
			"vkey": "VK_MENU",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"MetaRight": {
			"vkey": "VK_RWIN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"MediaTrackNext": {
			"vkey": "VK_MEDIA_NEXT_TRACK",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"MediaTrackPrevious": {
			"vkey": "VK_MEDIA_PREV_TRACK",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"MediaStop": {
			"vkey": "VK_MEDIA_STOP",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"Eject": {
			"vkey": "VK_UNKNOWN",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"MediaPlayPause": {
			"vkey": "VK_MEDIA_PLAY_PAUSE",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"MediaSelect": {
			"vkey": "VK_LAUNCH_MEDIA_SELECT",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"LaunchMail": {
			"vkey": "VK_LAUNCH_MAIL",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"LaunchApp2": {
			"vkey": "VK_LAUNCH_APP2",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"LaunchApp1": {
			"vkey": "VK_LAUNCH_APP1",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"BrowserSearch": {
			"vkey": "VK_BROWSER_SEARCH",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"BrowserHome": {
			"vkey": "VK_BROWSER_HOME",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"BrowserBack": {
			"vkey": "VK_BROWSER_BACK",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"BrowserForward": {
			"vkey": "VK_BROWSER_FORWARD",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"BrowserStop": {
			"vkey": "VK_BROWSER_STOP",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"BrowserRefresh": {
			"vkey": "VK_BROWSER_REFRESH",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		},
		"BrowserFavorites": {
			"vkey": "VK_BROWSER_FAVORITES",
			"value": "",
			"withShift": "",
			"withAltGr": "",
			"withShiftAltGr": ""
		}
	}
}

code-serverからログアウトし、再度ログイン。

左上の三からメニューを表示し、「Sign out of code-server」をクリック
ログアウト方法

最後に一番最初のKeyboad Layoutの選択で「Japanese (User configured layout)」を選択すると日本語キーボードでもショートカットが使えるようになる。

変更されると右下の表示が「Layout: Japanese」になります。
こうなったらOK!

以上!

カテゴリー
その他 社内SE

Chromebook用メモ帳(Text editor PWA)

Chromebook (Chrome OS)用のテキストファイル用文字化け対策済みのアプリ(PWA)を以下リンクに公開します。PWAをインストールすれば完全にオフラインでも利用可能です。(ChromebookでSJISのテキストファイルを開けるようになります。)

メモ帳アプリ

PWA インストール方法

通常のPWAのインストールと同様です。メモ帳アプリを開いて上部アドレスバーに表示されるアイコンからインストールです。(表示されない場合は、アドレスバーでEnterを押して再読み込みしてみてください。)

PWAインストールボタン
PWAインストール確認画面

これでアプリとして「メモ帳」が登録されているので、検索ランチャーなどから呼び出せます。

ファイルから直接メモ帳を起動したい場合

ファイルをダブルクリックで表示など、ファイルから直接「メモ帳」を起動したい場合は、最初に実験的機能から、File Handling APIを選び、Enabledに設定します。

  1. アドレスバーにchrome://flagsと入力し、実験的機能を呼び出す。
  2. File Handling APIを探し、Enabledにする。
  3. Restart(再起動)する。(Chromebookが再起動されます。)
File Handling API

この状態でファイルアプリから適当なファイルを選び、右クリックから、以下の画像の要領で先程登録したメモ帳アプリを呼び出します。(画像のアプリ名は開発中のため異なります。。。)途中、許可を求められるので適宣許可ください。

ファイルから呼び出し

上の画像で「デフォルトを変更」を選ぶとテキストファイルをダブルクリックで開けるように設定もできます。

注意点

SJISのテキストファイルを読み込み表示/編集できますが、保存するとUTF-8になります。最近のWindowsのメモ帳はUTF-8がデフォルトですので、特に問題ないかとは思いますが、利用の際は注意ください。

その他

一度インストールすると完全にオフラインで動作します。サーバにファイルなどを送ることもないのでセキュリティ上も安心かと思います。

Shift-JISの他、EUC-JPも読めるようにしていますが、テストしていない(手元にEUC-JPのファイルがない)ので動かないかもしれません。

経緯

ChromeOSのTextアプリがShift-JISに対応していないため、古いテキストファイルを開くと文字化けていることがあり、その対策としてオープンソースソフトのSmart Text Editorを改変して作りました。本家のいらなそうな機能はバッサリ削っています。日本語対応以外で追加した機能は「名前を付けて保存」くらいです。短時間テストなしで改変したので、バグあるかもしれません。ソースはこちらに公開しています。(本家もかなりぐちゃぐちゃなコードです。何も気にせずぐちゃぐちゃ改変できるのでやりやすいといえばやりやすいのですが。。)

カテゴリー
その他 社内SE

HP Chromebook x360 14c レビュー(14c-cc 型番:518T8PA-AAAB)

家族で使用するためにChromebookを購入した。色々悩んだが、少し良いものをということで、HPの上位機種を選択した。スペックは「Core i3-1125G4 8GB 128GB SSD 14インチ フルHD」である。フルHDとあるが、設定から2194×1234まで解像度をあげられる。自動更新スケジュールは2029年6月までであった。

使って1週間ほどだが、総論としてとても気に入っている。思ったより軽く扱いやすいし、何よりフルHD IPSディスプレイがきれいである。WindowsやMACとは異なるOSなのでできることに制限はあるが、家族で利用する分には問題ない。Androidのアプリが使えるのも地味に良い。余談だが、子供の保育園の連絡帳がスマホアプリになり、スマホが苦手な私にとっては、ChromeBookを使ってキーボードで書けるようになりその点も嬉しい。

操作性

HPのChromebookというより、ChromeOSの操作性なのだと思うが、タッチパッドがよくできていて、マウスいらずである。それに加え、本製品はタッチディスプレイなのでマウスの出番はまったくない。この操作性の良さはMACのノートに近い。キーボードもキーピッチが20mm前後なので、特に打ちにくいこともない。

最近Windowsのノートも改善してきているが、タッチパッド絡みで言えば、やはりWindowsを使うならマウスのほうが良いし、それが残念ながら面倒なのだ。

動作

WEBを見る分には申し分ない。1週間でなれてしまったが、買って届いた日は、WEBの表示速度に「おっ」と驚いてしまった。起動は5,6秒ぐらいである。起動が速いので「ノートPC立ち上げるか。。。」のような億劫感は少なく、使いたいときにパッと使えるのが良い。この製品はシェルを開くと起動してくれるので起動ボタンを押す手間もない。ただ、起動時間に関して言えば、最近Windowsも頑張っているので、こちらのほうはよく見るChromeBookの宣伝ほどの驚きはなかった。

妻曰く、かなり良いとのことである。音にこだわりのない私の印象は、外付けスピーカーの音に比べると軽いという印象だったが、10年以上音楽をやっていた妻が言うなら良いのであろう。

映像、ディスプレイ

きれいである。Youtubeで自然ドキュメント系のフルHDの映像を見たが、ずっと見ていられる綺麗さであった。(ちなみに他の解像度の低い手持ちのデバイスではすぐに飽きてしまう映像である。)

また、上でも書いているが、フルHDなのに、設定から2194×1234まで解像度をあげられる。ただ、ここまで解像度を上げると字が小さくなりすぎるので、デフォルトの解像度は1536×864のまま今のところは使っている。

それと、主観ではあるものの、解像度1536×864のまま、YoutubeでフルHDの映像を見たときの映像の細かさはちゃんとフルHDが出ていそうである。あまり映像にこだわりのない私の感想ではあるが、解像度を上げてフルHDを見ても違いが見えないので多分Chrome OSにそういう機能があるのでは、と思っている。調べると以前は設定すればフォントやシェルフ以外の解像度を上げる機能がChromeOSにはあったらしい。今はその設定がなくなっているのでデフォルトになったのかもしれない。

カメラ

一応カメラアプリから自分を映して見てみたが、92万画素なのでそれなりである。WEB会議などで使う分には問題ないだろう。妻曰く、あまり細かく映るとアラが見えるおそれがあるため、少しボケてるぐらいが良いらしい。

電池持ち

ChromeBookの宣伝通り良い。フル充電で充分1日使える。家族がたまに(週に1、2時間ぐらい)使う分なら1ヶ月ぐらい充電無しで使えそうである。USBタイプCで充電可能なのもスマホの充電ケーブルと共用できて良い感じである。

購入の経緯

これまで、家族用のデバイスとして、メモリ2GBのタブレットをメインに、サブで10年前のMAC(Core i7 + SSD)を使っていた。最近タブレットが重くなり、かといってMACをいちいち出すのは億劫で、いろいろ考えた末、最近良く目にするChrombookの購入に至った。ちなみに自分用としてWindowsノートも2台持っているし、仕事柄、会社でもPCを色々購入しており、PCを見る目はなんとなくあるつもりである。

ChromeBookの選定にあたっては、はじめからHP製かFujitsu製のどちらかを購入するつもりであった。Asus製も目に入ってはいたが、これまで2度ほどAsus製品を購入し、どちらもすぐに壊れて印象が悪いので外した。Fujitsuの軽いPCとHPのコスパと迷った末にAmazonでセールとなっていたHP製の購入となった。

カテゴリー
OS 社内SE

さくらVPS 512MBにCode-serverを入れてみた

ここ数年、個人の開発環境はVS CodeでRemote Developmentを使って開発を行っている。これを最近話題のCode-serverでクラウド化すれば、PCを変えるたびに、ローカルにVS Codeをインストールする手間がなくなる。

ただ、開発環境はさくらインターネットのVPSの一番下の512MBプランなのでcode-serverを入れて重くなるのも嫌だな、となかなか手を付けずにいたが、今回試してみた。

OSや入っている主要プログラムは以下である。

Ubuntu 20.04 / Nginx / OpenLiteSpeed / Postfix / MariaDB / PostgreSQL / SSH / Code server (今回追加)

WEB系はNginxで受けて、裏で動いているOLSやCode-serverにproxyしている。

結論から言うと、この環境でもcode-serverはPHP程度の開発では問題ないレベルで動作している。「ローカルより若干遅いかな」、とか、「見た目が少し違うのでやりにくいな」と最初は感じたが、しばらくすると慣れて全く問題なくなった。

メモリはかなりカツカツで、コンパイルが必要な開発は無理そう。

セキュリティはクライアント認証をNginxに設定し、そこからProxyでCode-serverに繋いでいる。Code-server単体ではpassword設定しかできず若干不安があった。

同じくセキュリティ絡みで言えば、code-serverの起動オプションに[–disable-telemetry]を付けて起動している。これを付けないと、code-serverの開発元に諸処の情報が送付される。code-serverのインストール解説サイトで言及されていることがないため、たいした情報が送られているわけでもないかもしれないが念の為。

ちなみに、Code-serverのインストールに際し、HTTPのフロントエンドもApacheからNginxに変更した。理由はどうしても、ApacheのReverseProxyでCode ServerのWebsocketを通せず、やむなくNginxへの変更となった。軽い軽い言われているNginxだが、私の開発環境でProxyオンリーのフロントエンド利用ではApacheより遅く感じた。あくまで体感だが、1コアで最小限のセッティングにした場合、Apacheに分がありそう。

Apache Proxyで通らなかったCode ServerのWebsocketは「ProxyWebsocketFallbackToProxyHttp」(Apache 2.4.47)や、「ProxyWebsocketIdleTimeout」(Apache 2.5)を使えば動いた気がしたが、 Ubuntu 20.04のApacheのバージョンが2.4.41でそこまで試す気もなくあきらめた。

今回個人の開発環境を変更したが、会社の開発環境もCode server化したくなった。ただ、FreeBSD環境があったり、クローズドな社内ネットワーク内にサーバがあったりするので、保留。

カテゴリー
OS 社内SE

OpenLiteSpeedで実行ユーザを変更する

ApacheからOpenLiteSpeedへのサーバ変更で困ったことの一つが、OpenLiteSpeedの実行ユーザを変更することがうまくいかないことであった。OpenLiteSpeedのユーザとグループはApacheと同じもので動かしたい。

設定ファイル”/usr/local/lsws/conf/httpd_config.conf”を見ると、上のほうにuser/groupの設定がある。単純にこの設定を変えてOpenLiteSpeedを再起動すると、一見、正常に動いているように見えるのだが、Admin consoleからServer logやライブフィードが見られないなどPHPでファイルアクセスした際のユーザがらみと思われる異常が散見された。

解決方法は上記のファイルでユーザ、グループを変更後、以下のコマンドでOpenLiteSpeedを再インストールすることであった。

apt -y install --reinstall openlitespeed
# 念のため(不要かも)
rm -rf /tmp/lshttpd
systemctl restart lshttpd

正直、なぜ必要なのかはわからないが、これをやらないとOpenLiteSpeed経由で作成するファイルのユーザ/グループが設定ファイルのユーザ/グループにならない。

当該サーバはubuntuを使用しているため、aptでの再インストールとなっている。試していないが、Debian系特有の現象で、CentosなどのRedhat系ならこういった作業は不要なのかもしれない。

カテゴリー
OS 社内SE

OpenLiteSpeedでphp.ini Overrideが効かない

ApacheからOpenLiteSpeedにサーバを変更したのだがいくつか困ったことがあった。その一つが、OpenLiteSpeedでは”.user.ini”が効かなく、virtualhost毎にPHPの設定を微妙に変更できなくなってしまったことだ。

Admin console画面から設定を見ていると、virtualhostの[general](一般)タブの下に「php.ini Override」という設定があり、PHPの設定の一部上書きが出来ると書いているではないか。これは幸いと設定、console画面から「穏やかな再起動」をしてみたが動かない。

何度も設定をやり直した挙句、弱って直接confファイルを修正して、systemctl restart lshttpd とコマンドラインから再起動したところ、難なく動作した。

その後は、Admin consoleから設定、再起動しても問題なく設定が反映されるようになった。

理由は不明。単に何か間違えていた可能性もあるが、コマンドラインから修正と再起動を行うと動くこともあるという参考までに。

ちなみに行った設定は以下。

phpIniOverride  {
  php_value default_charset "SJIS"
  php_value mbstring.language "neutral"
  php_value mbstring.internal_encoding "SJIS"
  php_value date.timezone "Asia/Tokyo"
  php_value error_reporting E_ERROR
}

1990年代にWindowsで動かしていたコードやDBを引き継ぎ続けているため、こんな設定になっている・・・。