どうしてもWindows10の起動サウンドを鳴らしたい

期限が迫っているのに、どーでもいいことが気になって時間食ってしまう💦
どーでもいいプログラムを書く時間です。

歴代のWindowsで一番気に入ってるスタートアップサウンドは、Windows2000とMe の時のピアノ音。あれが一番心地よい。まぁ人それぞれなんですが・・・

最近のWindowsって起動サウンドが鳴らないんですね・・・ググると Windows8ぐらいからデフォルトで無効にされているみたいですね。まぁ仕事場のパソコンは別にいいとして、家で使うPCぐらい鳴らしてもいいんじゃないすかねぇ。

で、そもそも コンパネのサウンドの設定で、起動時のサウンドを鳴らす設定が消されています。なんで?
これもググるとレジストリをいじることで有効になるみたいですが、結局はシステムにブロックされて起動サウンドは鳴らないみたいでつね。。。

しかたないので、タスクスケジューラに登録することにした。起動サウンドのWAVファイルは Windows2000のインストールCDから抜いた。ライセンス的に不味いかもしれん。が、別にばら撒くわけでもなし。

基本タスクを作成し、トリガーとして「ログイン時」を選択。次に登録するプログラムなんですが・・・Windows標準で、サウンドファイルを再生するコマンドはないみたいです・・・
これもググると Powershell のワンライナーがヒットします。。。というか、これしかヒットしません。
要点は・・・コマンドプロンプトで下記コマンドを打つだけ。

>> powershell -WindowStyle hidden -c (New-Object Media.SoundPlayer "wavファイルのパス").PlaySync();

このコマンドをそのままタスクスケジューラに登録してもいいんですが・・・コンソールウィンドウが立ち上がってしまいます。

なんか、すっげぇカッコ悪りぃ!

標準でできないならプログラムを組むしかない。 上記のコマンドラインは .NET Frameworkのクラスライブラリ System.Media.SoundPlayer のインスタンスを生成してサウンドファイルを渡すだけなので、C#でも数行で済みそうです。というわけで組んでみる・・・組むというレベルでもない。

/*******************************************
  * JUST ONLY PLAY SOUND FILE(WAV)

  File name : playsound.cs
  build: 
     >> csc -target:winexe  playsound.cs
  
  usage:
     >> playsound logon.wav

  namespaceは適当に変えてね。
*******************************************/
using System.IO;
using System.Media;

namespace jp.ptsv.windows
{
  class PlaySound
  {
    static void Main(string [] args)
    {
      if(args.Length > 0 && File.Exists(args[0]))
        (new SoundPlayer(args[0])).PlaySync();
    }
  }
}

主要部分は一行ですね(笑)
これを、-target:winexe 付きでビルドするとコンソールウィンドウなしのプログラムができるので、このプログラムを適当のフォルダに配置してサウンドファイルとともにタスクスケジューラに登録します。
c:\your\binary\path\playsound.exe logon.wav

やっとこさ、ログイン時に あの Windows2000 の心地よい起動サウンドが聞けるようになったとさ。おわり。

一応実行バイナリを置いておきますが、自己責任で。いかなる損害も補償は一切いたしません。あしからず。

Windows10でこれだけ知ってれば飯食える(大嘘)基本キーボード操作

Linuxでターミナル中心にCUIでゴニョゴニョやってると、脳内がGUIからCUIになりつつあります。そりゃそうだよね、マウスでごちゃごちゃやるより、コマンド一発叩けば処理完了すんだから。

で、脳内がCUIに侵されつつある今、Windows10でもそれをやろう、というわけです。原点回帰です。MS-DOSは良かったな!的な。
Windows10ではすでにWSLがあるので、テキスト処理はもう快適です。コマンドプロンプトでの type とか findstr とかいう、意味わかんねーコマンドを叩く必要はありません。WSLで cat, grep できます。WSLで標準出力をクリップボードにも転送できるし、もちろん Windowsのコンソールプログラムにパイプで接続できますし、正直、昔のマイクロソフトはなんだったんだ?ってな具合です。

閑話休題。

本題です。脳内がCUIに侵されつつあるので、できるだけ Windowsでもマウスを触りたくないのです。特にエディタ(gVimとか)でガシガシコーディングしてると、キーボードから手を放したくないのです。

よく忘れるので、備忘録として残してます。

キーボードショットカット編
※ WIN は ウィンドウズキーでキーボードのWindowsのロゴがプリントされているキー。

( 1)WIN + SHIFT + S: スクショ
( 2)WIN + PAUSE: コントロールパネル⇒システム
( 3)WIN + . (ピリオド) :絵文字入力パレットを出す
( 4)WIN + , (カンマ) :押している間だけ 全ウィンドウを非表示(デスクトップ上のアイコン確認用途?)
( 5)WIN + +(プラス): 拡大鏡(拡大)
( 6)WIN + – (ハイフン):拡大鏡(縮小)
( 7)WIN + E :エクスプローラのE (エクスプローラ起動)
( 8)WIN + R :実行(Run) の R (コマンドを指定して実行ダイアログ)
( 9)WIN + D :デスクトップのD (全ウィンドウ表示・非表示の切り替え)
(10)WIN + I :INSTITUTE?の I (Windowsの設定を開く)
(11)WIN + G :GAMEのG (ゲーム用の情報FPSとか?を出す)
(12)WIN + V : なんのVだ? クリップボードの履歴表示

POWERSHELL編
※ コマンドの後に パイプで ogv に渡すとグリッドビューウィンドウで表示してくれる
 ( ogvは Out-GridView のエイリアス)

(1)gip LANインターフェイスのIPアドレス他の情報表示( Get-NetIPConfigurationのエイリアス)
   ipconfigコマンドよりこっちのほうがプロっぽいでしょワラ
(2)gin コンピュータの情報一覧 msinfo32のコンソール版?(Get-ComputerInfoのエイリアス)
(3)Get-NetAdapter (認識されているLANアダプター一覧)
(4)Get-NetFirewallRule (Windowsファイヤーウォール規則の一覧表示)

Powershellは.NET Fremeworkのほぼ100%にアクセスでき、NET Frameworkのクラスライブラリのほぼすべてのインスタンスを生成して使用することができる最強のシェルです。またレジストリを普通のファイル・ディレクトリのように扱えたりできて、マイクロソフトが提供するコマンドレット・ライブラリによってWindowsの設定、各種機能のインストールなど、Windowsのすべてを制御できるWindows=PowerShellといっても過言ではないでしょう。 水を飲むように、呼吸するように、Powershellを使えなければWindowsで飯を食うのは難しいでしょう。(そんなこたぁーねぇよ)

コマンドプロンプト編(POWERSHELL上でも可能)WSLなしでもOK
(1)where : unix系コマンドでいうところの which コマンドです。
(2)clip : 標準出力をパイプでつないでクリップボードにコピー。ex) dir | clip
(3)nbtstat -a コンピュータ名 :LAN内のNETBIOSコンピュータ名から情報を取得
(4)curl:ファイル送受信コマンド(最新のWindows10では標準で使えるようになってます)
(5)scp :リモートファイルコピーコマンド (最新のWindows10で OpenSSHがサポートされてます)

要望としてはnetcatも標準でサポートして欲しい。。。powershellではスクリプト組めばなんとかできそうだけどね。netcat相当のコマンドレットも提供して欲しいよ、標準で。

随時追加中。。。

gVimでのシェル切り替え

Visual Studio 2019 Community インストール。
まぁ、たまにC#とか、昔のC++で書いたツールをビルドするのにやっぱ必要。
IDEはほとんど立ち上げず、gVimで編集、編集。もうカーソル移動が HJKLバインドじゃないと苦痛を感じるレベルまで悪化。
xkeymacs ならぬ、xkeyvim ってググるおっさんがここにいる。

そんなことはさておき。

gVimでC#とかC,C++(Win32 API)のコードを叩いていると、terminal でビルドしたくなります。だけど、おっさんはgVimのshellオプションをWSL(Bash)に変えてあるので、困った、困った、こまどり姉妹になるわけです。

困るので、gVimの複数のオプションを一括変更するだけのコマンドを書く・・・なんか激しく無駄なことをしている気がしないでもないが・・・CMD と WSLを行ったり来たりするにはこれしかない。

" Set CMD 既定値に戻す
function! Fsetcmd()
  set shell&
  set shellcmdflag&
  set shellslash&
  set shellquote&
  set shellxquote&
  set shellxescape&
  set grepprg&

  echo 'change shell to default windows cmd'
endfunction

" Set WSL
function! Fsetwsl()
  let &shell = 'bash'
  let &shellcmdflag = '-c'
  let &shellslash = 1
  let &shellquote='"'
  let &shellxquote = ''
  let &shellxescape = ''
  let &grepprg = 'grepwsl -n'

  echo 'change shell to WSL bash'
endfunction

command! Setcmd call Fsetcmd() 
command! Setwsl call Fsetwsl() 

vimスクリプトで、オプション変数を初期値に戻すにはどう書けばいいのかなぁ・・・???
追記:
オプション変数を規定値に戻すのは set {option}& にすればいいようで・・・ヘルプに書いてますね・・・反省

普段は シェルを wsl-bash にしているので、 :Setcmd とすれば、:termや:shell や :r !hogehoge でcmd.exeを使うデフォルトに戻れる。
こんなアホなことしてんのおっさんだけだよなぁ。。。

gvim(+kaoriya) + WSL Part3

:prev の続き

※この内容は事前に Part1で記述したように shell,shellcmdflagとかの変数をWSL用に変更する必要があります。

とりあえず、gVim(+kaoriya) と WSLの連携をある程度スムーズにできるようになりましたが、問題が一つ発生。
ローカルドライブだと問題はないのですが、リムーバルディスクとかネットワークドライブだと、WSL内の /etc/fstab に記述して自動マウントしてても、Windows10アプリケーションからWSLに移行した時点でカレントディレクトリが引き継げません。

ネットワークドライブを ドライブレター(Z: とか)にアサインして、cmd.exeで cd /d z: としてカレントディレクトリを変更し、bash.exe(or wsl.exe)しても、ホームディレクトリに飛ばされます。。。
カレントディレクトリを引き継いでくれるのは、c:ドライブとか、ローカルハーディスクだけのようです。ディスクタイプによって判断しているんでしょうか・・・。

これが一番困るのは、:grep コマンド。:grep コマンドの結果をQuickFixで開けるようにしているけど、カレントディレクトリ以下でローカルドライブだとなんとか使えるけど、リムーバルドライブとか、ネットワークドライブだと、パスの関係で全滅。WSLのフルパスで検索対象を渡せば grep は機能するが、QuickFixウィンドウに表示されるのはWSL側のフルパスなので 当然 gVim ではそのパスが理解できないので、結局使えない。

解決方法は、3つ。

(1) :grep をあきらめ、:vim(grep) で代替。
  ⇒ (ネットワークドライブだと特に)遅い。常用できないほど遅い。

(2) Msys の grep.exe で代替
 ( _vimrc にて set grepprg=/mnt/c/Msys64/usr/bin/grep.exe\ -n

  ⇒ WSLのみでなんとかする、という最初の趣旨から外れてしまうが・・・しょうがない。

(3) WSL側に grepの結果からパス名部分を変換するフィルタスクリプトをかます
 ( _vimrc にて set grepprg=grepwsl\ -n

  ⇒ ネットワークドライブ内のファイルを編集している時だけ検索パスをフルパス(WSL)を指定しないといけない。
  ⇒ また、若干遅くなるが、許容範囲内。。。WSLだけで完結できる。

というわけでとりあえず しばらく(3)を常用することにした。すでに Msys入れている場合は(2)の方が簡単かも・・・。ネットワークドライブのときだけ検索パスを絶対パスにする必要があるが、まぁしょうがない。

まずネットワークドライブ(例: Y)をドライブレターにアサインし、 sudo mkdir /mnt/yでディレクトリを作成し、/etc/fstabに登録する。

# /etc/fstab
LABEL=cloudimg-rootfs   /        ext4   defaults        0 0
Y: /mnt/y drvfs defaults,noatime,uid=1000,gid=1000 0 0

WSL側のpathが通っているところに(たとえば /usr/local/bin/ とか)grepwsl を作成しsudo chmod +x /usr/local/bin/grepwsl

#!/bin/sh
##############################################################################
#  wslgrep  .... WSLに入っているwslpathコマンドを使用してパスを変換 
#  2018/08/29 絶対パスに変換するオプション(-a)を追加/正規表現ちょい修正
##############################################################################
grep $@ | perl -pe 's/^([^:]+)/`wslpath -m -a $1 | tr -d "\n"`/e;'

これは単にgrepの結果を perl に渡して変換処理をしてるだけ。sedでもawkでもなんでも。単にperlに慣れているだけ。

んで、~/_vimrc に追記

;;; ~/_vimrc
set grepprg=grepwsl\ -n

ってなけで、とりあえず、なんとかなった!(^^;

gvim(+kaoriya) + WSL

ちょっと躓いたので、備忘録。

gvim(+Kaoriya)で特に何も設定しないと、シェルは cmd.exe が使われますよね。8.1から:terminalが使えるようになったので、とりあえず %USERPROFILE%\_gvimrc に 以下の記述をつけてシェルをWSLのbashにしました・・・。

set shell=C:\WINDOWS\System32\bash.exe

一瞬だけ自己満に浸ってしまいましたが・・・コマンドラインモードで次を実行すると・・・

:r !date

テンポラリファイルがオープンできない旨のエラーが出て撃沈。

困ったときのグーグル先生で検索するも探し方が悪いのか解決できない。基本に立ち戻り、vimのヘルプを参照(^^; ( :help options )

shell を変更する場合は、shellcmdflag,shellquote,shellxquote等も変更してね・・・ということらしい。
はじめからこちらを見てれば問題なかった・・・。
ヘルプのとおりに以下のように設定すると、問題なくでけた!

set shell=C:\WINDOWS\System32\bash.exe
set shellcmdflag=-c
set shellquote=\"
set shellxescape=
set shellxquote=

※修正:shellxquoteを空にすると perl のファイルを開く時に ftplugin/perl.vim で標準入力待ちになって帰ってこなくなったので、よくわからないけど 引用符をいれたらなんか治った・・・よくわからん。まぁいいや。
※修正の修正:shellxquoteを設定したら今度は !command が動かなくなった・・・ということで戻す・・・。該当ファイル(ftplugin/perl.vim)を見たら perlpath = system('perl -e "join ....");の部分で perlpath を設定しているみたいなので、仕方ないので _gvimrc に let g:perlpath = “ほにゃららら” とかでお茶を濁して切り抜けた。

紆余曲折がありましたが・・・:terminal のおかげで、なかなかスマートに事を為しとげることができ、いとをかし。。。

スクリプトをせっせと書きつつ、コード片を スクリプトに流し込み、動作確認、CTRL-W N で端末ノーマルモードに移行しコピって、スクリプトにペーストとかもうキーボードから手を放さず全部できちゃう!

今までのようにコンソール画面をマウスでチマチマ選択しながらコピペ・・・とかもうおさらばさ!もうWindowsはダサいとか言わせないぜ!・・・・とかいいつつ、使ってるツール、環境は全部Linux由来なんだけど・・・(^^;;; WSLのおかげで、gvimの端末からフツーのWindowsアプリも起動できるし、いうことなし。\(^o^)/。

ただ、一点惜しむらくは、:term command とすると、当然環境変数PATHからcommandを探そうとします。これを WSL の中で行わせるには、:term bash -c command とかやらないと無理っぽい。この “bash -c “っていうのはイチイチ打つのはメンドイ。しかし、初心者のおいらにはこれまた解決方法が分からず、一向に初心者からなかなか抜け出せないな・・・。

:continue
つづきは part2で