Apr 05, 2019

Windows 10の環境構築

会社で新しくWindows 10 PCをメイン環境として使い始めようとしていて、セットアップするのになんやかや詰まったので記録を残しておきます。

任意のホームディレクトリ名でアカウントを作る

何も考えずにMicrosoftアカウントで使い始めると、例えば shimoda.hiroshiみたいなMicrosoftアカウントだったら C:\Users\shimo みたいな適当にぶった切られた名前でホームディレクトリができてしまう。C:\Users\piro みたいに任意の名前のホームディレクトリにするためには、以下の手順を踏まないといけない。

  1. 使いたいホームディレクトリの名前でローカルアカウントを作成する
  2. そのローカルアカウントを管理者にする。
  3. そのローカルアカウントでログオンする。
  4. そのローカルアカウントからMicrosoftアカウントに切り替える。
  5. 再起動後、古いホームディレクトリ(C:\Users\shimo とか)を管理者権限で削除する。

コンピューター名を変える

コンピューター名はWindowsの通常使用だと意識する事はあまりなくて、LAN内で参照する時に使う程度だけど、WSLでホスト名として常時目にする事になる。これがランダムっぽい名前だと結構いらつくので、最初に変えておく。(以後はWSLでも勝手にこの情報を参照してくれる)

WSLの初期設定

WSLを有効化してストアからUbuntuをインストールした後にやること。

  1. 起動時の初期ディレクトリをWindowsのホームではなくWSL上のhomeにする。 Windows Terminalを使う場合、Windows Terminalの設定(settings.json)のWSL用の項目の "source": "Windows.Terminal.Wsl" をコメントアウトして、代わりに "commandline": "wsl.exe ~ -d Ubuntu" と書いておく。
  2. Windowsのファイルシステム上でWSLのファイルのパーミッションを保存できるようにするために、 sudo vim /etc/wsl.conf で設定ファイルを開いて以下の内容を保存する。

    [automount]
    options = "metadata,umask=22,fmask=111"
    

    マウントした既存のファイルや新たに作成したファイルが全部実行権限付きで認識されるとGitを使うのに不便なので、maskを指定して実行権限がつかないようにしておく。

  3. WSLのシェルを一旦閉じて、サービス一覧から LxssManager を探し、再起動する。これで、上記の設定が反映される。
  4. ln -s /mnt/c/Users/username/Destop ~/Desktopln -s /mnt/c/Users/username/Documents ~/Documentsln -s /mnt/c/Users/username/Downloads ~/Downloadsln -s /mnt/c/Users/Public ~/Public などとして、WSLでよく使うWindowsのフォルダにシンボリックリンクを作っておく。
  5. シェルでよく使う基本の設定をする。

    1. ~/.bashrc に以下の内容を加えて、コマンド履歴の逆方向検索に Ctrl-S を使えるようにする。

      stty stop undef
      stty start undef
      
    2. ~/.bashrc に以下の内容を加えて、複数のシェルでコマンド履歴を共有するようにする。

      function share_history {
        history -a
        tac ~/.bash_history | awk '!a[$0]++' | tac > ~/.bash_history.tmp
        [ -f ~/.bash_history.tmp ] && mv ~/.bash_history{.tmp,} && history -c && history -r
      }
      PROMPT_COMMAND='share_history'
      shopt -u histappend
      export HISTSIZE=99999
      
    3. ~/.bashrc に以下の内容を加えて、よく使うエイリアスを使えるようにする。

      export LESS='--no-init --RAW-CONTROL-CHARS --LONG-PROMPT --shift 4'
      alias grep!='grep --color=always'
      alias jq!='jq --color-output'
      alias cd='pushd > /dev/null'
      
     
  6. SSHの秘密鍵を設置して、他のホストにSSHで接続できるようにする。 基本方針として、WSLのsshクライアントから直接秘密鍵を触らずに、Windows 10に最初から入ってるOpenSSHのssh-agentに鍵を読み込ませて、必ずrupor-github/wsl-ssh-agent経由で利用することにする。

    1. Windowsの「管理ツール」の「サービス」で「OpenSSH Authentication Agent」を手動で有効化し、自動起動するように設定する。
    2. rupor-github/wsl-ssh-agentのリリース一覧から最新版のバイナリのwsl-ssh-agent.7zをダウンロードしてきて展開し、中身をC:\Program Files (x86)\wsl-ssh-agent\あたりに置く。
    3. wsl-ssh-agent-gui.exe へのショートカットを C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp(全ユーザー向けの場合)か、%AppData%\Microsoft\Windows\Start Menu\Programs\Startup(自分のみの場合。Win-Rで shell:startup を実行して開かれるスタートアップフォルダ)に作る。
    4. 作成したショートカットのプロパティを開いて「リンク先」に -socket "%temp%\ssh-agent.sock" と起動オプションを付け足す。これで、毎回起動時にssh-agentのためのソケットが作られるようになる。
    5. この時点ではまだ wsl-ssh-agent-gui.exe が起動していないので、ショートカットをダブルクリックして起動する。
    6. WSLのbashを起動する。
    7. ~/.bashrcexport SSH_AUTH_SOCK=/mnt/c/Users/$USER/AppData/Local/Temp/ssh-agent.sock という行を足す。これで、WSLの環境に入ると自動的にWindows側のssh-agentと繋がるようになる。
    8. source ~/.bashrc を実行して設定を反映する。
    9. 旧環境から ~/.ssh (秘密鍵、公開鍵、設定ファイル)を持ってくる。
    10. chmod 700 ~/.ssh で、ディレクトリのパーミッションを他のユーザーから参照不可能なようにする。
    11. ssh-add ~/.ssh/(秘密鍵) を実行し、秘密鍵を ssh-agent に読み込ませる。
    12. ほかのホストにログインできることを確認する。

    (以下は、Windows 10のOpenSSHを使うようになるまで使ってた、PuTTYのPageantに鍵を読み込ませて、必ずweasel-pageant経由で利用する場合の手順。歴史的資料として残す。

    1. C:\Users\username\.ssh/mnt/c/Users/username/.ssh)を作成し、旧環境からファイルをコピーする。
    2. PuTTYをインストールする。
    3. puttygen.exeで秘密鍵のid_rsaをインポートして、PuTTY形式の秘密鍵 id_rsa.ppk として保存する。
    4. Win-Rで shell:startup を実行してスタートアップフォルダを開き、pageant.exe のショートカットを作成する。
    5. pageant.exe を起動して、先の id_rsa.ppk を読み込ませる。
    6. weasel-pageantの最新リリース版バイナリをダウンロードし、展開したファイルを C:\Program Files (x86)\wsl-pageant に置く。
    7. マウントオプションで実行権限がつかないようにしているので、chmod +x /mnt/c/Program\ Files\ \(x86\)/weasel-pageant/weasel-pageant /mnt/c/Program\ Files\ \(x86\)/weasel-pageant/helper.exe で明示的に実行権限を設定する。
    8. echo 'eval $(/mnt/c/Program\ Files\ \(x86\)/weasel-pageant/weasel-pageant -r)' >> ~/.bashrc で、weasel-pageantを自動起動するようにする。(weasel-pageantにどのようなオプションを設定するべきかについては、必ず最新の解説を参照すること。)
    9. mkdir ~/.ssh; chmod 700 ~/.ssh で、設定ファイル等の置き場所を用意する。 ln -s /mnt/c/Users/username/.ssh ~/.ssh でシンボリックリンクとして作成してしまうと、次項の設定をしてもSSH接続を受け付けられなくなってしまう(~/.ssh のパーミッションを適切に設定できなくなる)ので、必ずここは普通のディレクトリとして作成しておく
    10. ほかのホストにログインできることを確認する。

  7. 他のホストからSSHで接続できるようにする。 常時使うわけではないが、必要な時はできるようにしておく。WSLのUbuntuにはopenssh-serverが最初から入っているので、後は必要な設定をするだけで使える。
    1. 前項で /mnt/c/Users/username/.ssh/ 以下に公開鍵等もコピーできているはずなので、/mnt/c/Users/username/.ssh/authorized_keys があるのであれば ~/.ssh/authorized_keys にコピーする。なければ、/mnt/c/Users/username/.ssh/id_rsa.pub~/.ssh/authorized_keys にコピーする。
    2. chmod 600 ~/.ssh/authorized_keys として、パーミッションを適切に設定する。
    3. sudo service ssh start してsshdを起動する。
    4. ssh localhost でログインできることを確認する。
    5. Windows Defenderのファイアウォールの詳細設定で、「受信の規則」で以下の内容の規則を作成する。
      • 種類:ポート
      • プロトコル:TCP
      • ポート:22
      • プロファイル:「ドメイン」と「プライベート」だけ残して、「パブリック」はチェックを外す(怖いので)。
      • 名前:ssh
    6. 他のホストからログインできることを確認する。
    7. sudo service ssh stop してsshdを停止する。(以後は、必要な時にだけ起動する)
  8. pecoを使えるようにする。
    1. mkdir -p ~/local/bin で、ユーザー固有のバイナリ置き場を用意する。
    2. echo 'export PATH="~/local/bin:$PATH"' >> ~/.bashrc してパスを通しておく。
    3. pecoの最新リリース版から適切なバイナリをダウンロードする(今回は peco_linux_amd64.tar.gz を使った)。
    4. unar peco_linux_amd64.tar.gz でファイルを展開する。
    5. 取り出されたファイル群に含まれる peco~/local/bin/ に移動し、chmod +x ~/local/bin/peck で実行権限を設定する。
    6. 私的によく使う設定のまとめをraw形式でダウンロードし、echo 'source ~/peco-commands.sh' >> ~/.bashrc で自動的に読み込むように設定する。
  9. bash-git-promptを使うようにする。

    1. cd ~/ して git clone https://github.com/magicmonty/bash-git-prompt.git ~/.bash-git-prompt --depth=1 で必要なファイルをローカルに用意する。
    2. 以下の内容を ~/.bashrc に追加して、機能を有効化する。

      GIT_PROMPT_ONLY_IN_REPO=1
      source ~/.bash-git-prompt/gitprompt.sh
      GIT_PROMPT_THEME=Single_line_Ubuntu
      
    3. 時刻表示の部分が余計なので、以下のように編集する。

      diff --git a/themes/Single_line_Ubuntu.bgptheme b/themes/Single_line_Ubuntu.bgptheme
      index 7dd3a4f..542b259 100644
      --- a/themes/Single_line_Ubuntu.bgptheme
      +++ b/themes/Single_line_Ubuntu.bgptheme
      @@ -15,7 +15,7 @@ override_git_prompt_colors() {
         GIT_PROMPT_COMMAND_OK="${Green}✔ "
         GIT_PROMPT_COMMAND_FAIL="${Red}✘ "
      
      
      -  GIT_PROMPT_START_USER="_LAST_COMMAND_INDICATOR_ ${White}${Time12a}${ResetColor} ${Cyan}${PathShort}${ResetColor}"
      -  GIT_PROMPT_END_USER="${ResetColor} $ "
      -  GIT_PROMPT_END_ROOT="${BoldRed} # "
      +  GIT_PROMPT_START_USER="${Cyan}${PathShort}${ResetColor}"
      +  GIT_PROMPT_END_USER="${ResetColor}\$ "
      +  GIT_PROMPT_END_ROOT="${BoldRed}# "
      
     
  10. sudo update-alternatives --config editor でデフォルトのエディタをvim.basicに切り替えておく。

ファイルの移行

ここまででWSL上のrsyncが使えるようになっているので、旧環境から rsync -a xxx.xxx.xxx.xxx:~/path/to/directory/ ~/Public/ みたいにしてパーミッションの情報込みでファイルを持ってこれる。 (シンボリックリンクまで勝手に辿らせると大変なことになりかねないので、シンボリックリンクの先は個別に辿るのがよい気がする。)

今回は移行元がハードウェア上にインストールされたUbuntuだったけれども、移行元がWindows 10マシンの場合も上記の要領であらかじめsshdを起動しておけば、同様にrsyncでファイルを持ってこれる。

Firefoxのビルド環境を整える

最近のMozillaBuildとmozilla-centralはよくできてて、だいたい一発で環境ができあがる。以下、前半は会社のブログに書いた手順の通り。

  1. MozillaBuildの最新版リリースをダウンロードし、インストールする。一般的にはc:\mozilla-buildにインストールする。
  2. C:\mozilla-sourceの位置にフォルダを作る。Firefoxのソースコード一式はこの配下に置く事になる。
  3. c:\mozilla-build\start-shell.batを実行して、MozillaBuildのシェル(Bash)を起動する。
  4. echo 'export PATH=$PATH:~/.cargo/bin' >> ~/.bash_profile を実行して、MozillaBuildのシェルを一旦終了し、c:\mozilla-build\start-shell.batで起動し直す。
  5. cd /c/mozilla-source して、 hg clone https://hg.mozilla.org/mozilla-central でmozilla-centralをcloneする。
  6. cd mozilla-central してリポジトリに入り、./mach bootstrap を実行する。これにより、Visual StudioやRustなどのビルドに必要なソフトウェア群が自動インストールされる。
  7. ./mach build して、ビルドできる事を確認する。
  8. ./mach run して、ビルドしたFirefoxを起動できる事を確認する。
  9. WSLとホームを共用してない関係でBashの設定が素のままなので、~/.bash_profileに以下を追記する。

    # Ctrl-Sで履歴を逆検索できるようにする
    stty stop undef
    stty start undef
    
    # MozillaBuildの環境にはtacが無いので、関数で代用する
    function tac {
      exec sed '1!G;h;$!d' ${@+"$@"}
    }
    
    # 複数のシェルで履歴を共有する
    function share_history {
      history -a
      tac ~/.bash_history | awk '!a[$0]++' | tac > ~/.bash_history.tmp
      [ -f ~/.bash_history.tmp ] && mv ~/.bash_history{.tmp,} && history -c && history -r
    }
    PROMPT_COMMAND='share_history'
    shopt -u histappend
    export HISTSIZE=99999
    
  10. Mozillaのサーバーに認証を求める時のユーザー名指定を省略できるようにするために、~/.ssh/configに以下を追記する。

    Host hg.mozilla.org
      User yuki@clear-code.com
    
  11. ssh hg.mozilla.org してみて、認証できるかを確認する。(シェルには入れないでそのまま接続が切れるが、それでOK。)

  12. tryserverを使うために、~/.hgrcに以下を追記する。

    [paths]
    try = ssh://hg.mozilla.org/try
    
  13. ./mach try empty で空のリクエストを送れるかどうか確認する。

  14. Phabricatorを使うための準備をする
  15. hg grepfileでワーキングコピーのファイルを対象に検索できるようにするために、hg-grepfileをインストールする。ただし2019年4月16日現在のバージョンは最新のMercurialで動かないため、修正のプルリクエストがマージされるまでの間は独自の修正版を使う必要がある。

タスクビューをすぐに出せるようにする(仮想デスクトップをすぐに切り替えられるようにする)

最近までWindows 10標準で仮想デスクトップ機能があるということを把握してませんでした。今回調べて初めて知りました。

Ubuntuではメインの作業画面とThunderbirdを使う(メールを読み書きする)画面とを分けていて、画面の端にカーソルでちょいっと触れると仮想デスクトップ切り替えの画面が出てくるようになってたんだけど、そういう事をできるようにするにはユーティリティが必要。タスクビューの切り替え画面を出すこと自体は、Windowsキー+Tabでできるので、任意のジェスチャでこのキー操作を代替すればよい。

マウスジェスチャーソフトの「MouseGestureL.ahk」でマウスホイールにWindows10の「タスクビュー」を割り当てる | PC ウェブログという記事を参考に、以下のようにした。

  1. MouseGestureL.ahkをダウンロードする。
  2. zipを展開してC:\Program Files配下あたりに適当に置く。
  3. Setup.vbsを実行する。
  4. インストールされて設定画面が開かれる。
  5. 「ジェスチャー」タブに切り替えて、以下のジェスチャーを追加する。
    • 名称:screen-edge
    • ジェスチャ-1:CRB_(画面右下角に接触)
    • ジェスチャー2:CLB_(画面左下角に接触)
  6. 「メイン」タブに切り替えて、「デフォルト」の割り当て済みジェスチャーをscreen-edge以外すべて削除する。
  7. screen-edgeのアクションスクリプトを以下の通りに書く。

    ;キー操作を発生させる
    Send, #{TAB down}{TAB up}
    
  8. 「その他」タブに切り替えて、「スタートアップに登録」で自動起動するようにする。

これで、画面の端に触れるだけで仮想デスクトップを切り替えられるようになる。

2020年5月1日追記。初期設定ではRB(右ボタン)で始まるジェスチャがいくつか定義されてるんだけど、これがあると、Windows全体で右ボタンの動作に影響が及んでしまう。具体的には、window.addEventListener('mousedown', ...)みたいな方法でマウスのボタンが押し下げられたことを検知しようとしても、右ボタンだけmousedownが取れなくなる(ボタンを放したときに初めてmousedownが発火するようになる)。自分はscreen-edgeをトリガーにした操作しか使わないので、RBで始まるジェスチャは全部削除した。

Selection Clipboard的なこと(文字列を選択するだけでコピー)を実現する……のは諦めた

Ubuntuではテキストを選択すると通常のクリップボードとは別の専用のバッファにテキストが格納されてミドルクリックで貼り付けるという動作になってた(これ自体はXの機能とのこと)んだけど、GNOME Terminal(端末)でコピー&ペーストのキーバインドが他のGUIアプリと違っていたこともあって自分でも驚くくらいに意外と多用していて、Windows環境でWSLを使っているとそのときの感覚が抜けなくてつい戸惑ってしまう。

代わりになりそうなものを探してみたらいくつか情報が見つかったんだけど、どれも今使うにはちょっと厳しい感じだった。

  • copipex:32bitアプリだからなのか、64bit版Firefoxや秀丸エディタでは反応してくれなかった。作者の方によると、64bit版作成の予定は無いとのこと。
  • True X-Mouse Gizmo:Xのマウス関連操作を再現することを意識しているらしく、Selection Clipboard以外の余計な機能が多くて辛い。特に、mouseoverでフォーカスを切り替える機能のせいでタスクバーがまともに使えなくなるのが致命的。
  • AutoCopyX:なんかWindows Defenderでマルウェア判定されるので怖い。

もうちょっと悪あがきしてみようと思って「Windows selection auto copy」という感じのキーワードで検索してみたら、AutoHotKey用のスクリプトの例が出てきた。自分は結局AutoHotKeyは入れずにMouseGestureL.ahkだけで使ってるんだけど、これの実態がほぼ同じ物のようで、MouseGestureL.ahkのインストール先にあるMG_User.ahkのユーザー定義サブルーチンの所に以下のスクリプトを追加してMouseGestureL.ahkを再起動したら普通に使えた。

ただ、Ubuntuの時と違って専用のバッファが使われる訳ではないから、選択→Ctrl-Cでコピー→貼り付けたい箇所にある邪魔なテキストを選択→Ctrl-V という事をしようとすると、貼り付け先の邪魔なテキストの方がクリップボードに入ってしまうという難点があった。なので解説を見ながら試行錯誤して、クリップボードとは別のバッファを持つようなスクリプトを作ってみた。MouseGestureL.ahk単体版ではなくAutoHotKeyの方を使う場合は、上記の内容をSelectionClipboard.ahkという名前で保存し、ファイル名を指定して実行→shell:startupで開かれるスタートアップフォルダの中に置けばいいみたい。

で、しばらく試してみてたんだけど、以下の問題をどうしても解決できなかった。

  • テキストが選択されてない状態でも左ボタンのドラッグやダブルクリックで常にCtrl-Cが送信されるので、Windowsのエラー音がその度に鳴ってうざい
  • WSLのウィンドウをタイトルバーのドラッグで移動したりリサイズしたりすると、Ctrl-Cが送信されてSIGINTになって実行中のプロセスが終了してしまう(致命的)

Ctrl-Cでクリップボードへのコピーを試行するのが元凶なので、それ無しで選択範囲のテキストを取得できる方法があればいいんだけど、それはエディットコントロールに対してのみ動作する関数しか用意されてなくて、オフィシャルのサンプルの時点で「標準のエディットコントロール以外でも使えるのはCtrl-Cを使う方法だ」と紹介されてるレベルだったので、AutoHotKeyの制限事項としてどうにもならないというのが結論のようです。残念。

Aero Shake(ウィンドウのタイトルバーを付かんで揺すると他のウィンドウが最小化される)を無効化する

これ機能として欲しくなることが無くてまず誤爆で困るばかりなんですけど?

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\AdvancedDisallowShakingというDWORDの値を作ってデータを1にすると、この機能が無効化されるそうです。

なんで自動化してないの

そんなに頻繁にやるわけじゃなくて、数年に1回やる程度なので、

  • そのためだけにPowerShell覚える気になれない。一生懸命覚えてもLinuxとかBSDとかmacOSとかで使えないし。→と思ってたら他のプラットフォームでも動かせるという指摘を頂きました
  • 数年に1回の実行ペースでは、下手に自動化してると、前回実行時から色々前提が変わっていて途中でこけてドツボにはまりそうで怖い(実際今回もweasel-pageantの推奨設定が以前調べた時と変わっていた)。

という風に思ってます。

毎月やるとか、まとめて10台くらいやるとか、そういう前提が出てきたら重い腰を上げてPowerShell覚えるかもしれないですね。

 

まだ後から書き足しそう。

後日談:これとは別のPCについて行った、Bash on Ubuntu on WindowsからストアアプリのUbuntuへの環境引き継ぎの話。ここに書いた話を一部参照した。

エントリを編集します。

wikieditish message: Ready to edit this entry.











拡張機能