pslaboが試したことの記録

はてなダイヤリーからはてなブログに引っ越してきました

この日記は現在実行中の減量記録を含む個人的なメモとして始めましたが、最近はコンピュータやガジェット、ハック、セキュリティネタのほうがメインになっております。

はてなダイヤリー時代はカテゴリ分けが適当だったのですが、これはそのうち直します。


Delphi/C++BuilderのFireDACでPostgreSQLを利用するためにodbcドライバをインストールする

FireDACでLinux上のPostgreSQLに接続する必要が出て、エンバカデロのオフィシャルなドキュメントを見てみたのですが、ドライバの入手方法が明示されていないのですね。

docwiki.embarcadero.com

ドキュメントによると、たとえば 9.0 向けの場合は以下のファイルが必要、みたいなぼんやりした説明しかなされていない。

libpq.dll
ssleay32.dll
libeay32.dll
libintl-8.dll
libiconv-2.dll

そこでウェブ検索で調べてみると、ソースからビルドするだとか、個人の方のウェブページからのダウンロード方法が紹介されていたりとかで、いまいちオフィシャルなバイナリが見当たらないようでした。

しかし、もっとよく調べてみると、postgresql.org の下記ページで PostgreSQL 向けの Windows 向けODBC ドライバが配布されていることに気がつきました。

www.postgresql.org

今回欲しいのはあくまで必須のDLLだけなのですが、このODBCドライバをインストールすると必要なDLLがインストールされるようです。これで、出どころが明らかなバイナリで PostgreSQL への接続が行えそうです。

Windows10のタブレットモードのときにアプリからタッチキーボードを強制的に表示させる

とりあえずのメモ書きです。

Surface Go で利用するアプリをDelphiでプロトタイプ的に作成していたら、タブレットモードのときに強制的にタッチキーボードを表示させたくなったのでしらべてみた。

ソフトウェアキーボードは2種類ある

昔ながらのオンスクリーンキーボードは osk.exe で起動します。

しかしWindows10 のタブレットモードではosk.exeではなくTabTip.exeが動作しているようです。

TEdit などの imeMode はosk.exeとtabtip.exeでは挙動が違うようだ

osk.exeの場合はimeModeによる制御は物理キーボードと同じように効くようだ。

しかしtabtip.exeの場合はimeDisableとそれ以外しか受け付けないように見える。

ソフトウェアキーボードを表示させたくなったらどうすればよいのか?

アプリケーションフォームへの onFocus でosk.exe と tabtip.exe のどちらも起動していないときに、使わせたいソフトウェアキーボードを起動すればよさそう。

WPFでの実装例がここにあるので、これを参考にしつつ実装すればよさげ。

iyemon018.hatenablog.com

ソフトウェアのダウンロードリンクがCDNを使っている場合はダウンロード時間短縮のために分割ダウンローダを使ってみる

ファイルをダウンロードする際に wget などを利用する場合は最初から最後まで1つのコネクションでダウンロードしますが、ウェブサーバ側が Range request に対応していれば、axel のような分割ダウンローダを使うことで同時に複数のコネクションを張っての並列ダウンロードできます。

ですがこの方法は一般的には避けるべき方法です。ダウンロードサイトのサーバや途中経路に負担がかかる方法です。

ただしダウンロードリンクがAkamaiのようなCDNを使っているなら、そういったことをあまり気にしなくても良いのではと思います。CDNを使うのは、オリジンサーバの負担を減らしつつ強力な配信インフラをサービスとして使うためですから、ありがたく活用しても良いだろうと思います。

CDNを使っているかどうかを確認するには?

DNSサーバにホスト名で問い合わせてみて、帰ってきた情報の中に akamai.net などの CDN のホスト名が含まれていれば当たりです。

$ nslookup ダウンロードサーバのホスト名
Server:         xxx.xxx.xxx.xxx
Address:        xxx.xxx.xxx.xxx#53

ダウンロードサーバのホスト名    canonical name = ______.g.akamai.net.
Name:   ______.g.akamai.net
Address: xxx.xxx.xxx.xxx
Name:   ______.g.akamai.net
Address: xxx.xxx.xxx.xxx

このようにしてもCDN経由かどうかの確証が持てない場合は普通に wgetcurl を使いましょう。

分割ダウンロードによりどれくらいの差がでるのか?

とある7GBのファイルを axel で10分割ダウンロードしたら、およそ11分でダウンロードできました。

$ axel -n 10 -a http://[Akamai経由のソフトウェアダウンロードリンク]
Initializing download: http://[Akamai経由のソフトウェアダウンロードリンク]
File size: 75________ bytes
Opening output file xxxxxxxxxx.xxx
Starting download

[ 18%] [.0       .1       ..2      ..3      .4       .5       ..6      ..7      ..8      ..9      ] [   9.1MB/s] [10:45]
...
Downloaded 7.0 Gigabyte in 11:15 minute(s). (10855.48 KB/s)

wget だと20分以上かかりそうです。

$ wget http://[Akamai経由のソフトウェアダウンロードリンク]
Will not apply HSTS. The HSTS database must be a regular and non-world-writable file.
ERROR: could not open HSTS store at '/home/pslabo/.wget-hsts'. HSTS will be disabled.
--2019-07-22 11:19:19--  http://[Akamai経由のソフトウェアダウンロードリンク]
Resolving サーバ名 (サーバ名)... xxx.xxx.xxx.xxx
Connecting to サーバ名 (サーバ名)|xxx.xxx.xxx.xxx|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 75________ (7.0G) [application/octet-stream]
Saving to: ‘xxxxxxxxxx.xxx’

xxxxxxxxxx.xxx   4%[=>                                                ] 324.97M  3.65MB/s    eta 20m 44s

検証用のWindows Server仮想マシンの自動ログイン設定をregコマンドで作る

Windows Serverで環境を作っては試し、また初期状態から再度つくる、みたいなテストを繰り返していたらログインが面倒になってきました。しかしレジストリ設定を手作業でレジストリエディタで書くのもそれはそれでめんどくさいし、.reg ファイルを作って読み込ませるのも微妙にめんどくさい。

そこで reg コマンドのコピペだけですませることにしました。

以下のコマンドのパスワード部分だけを書き換えてコピペすれば設定が完了します。

reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v AutoAdminLogon  /t REG_SZ /d "1"
reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v DefaultUserName /t REG_SZ /d "Administrator"
reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v DefaultPassword /t REG_SZ /d "パスワード"

Windows向けのsudo的なコマンドをDelphiで書く

先日、こういう記事をポストしたのですが、ここで調べた内容に基づいて Delphi で sudo 的なコードを書いてみました。

pslabo.hatenablog.com

やりたいことは、別のコマンドを管理者権限で実行したいだけなので、Delphi コマンドラインアプリケーションのプロジェクトを選択し、ShellExecute を 'run as' で実行するだけの簡単な実装です。

実行するコマンドとパラメータを以下のように取得して ShellExecute に渡しています。

  • ParamStr(1) で実行すべきコマンド名が渡される
  • ParamStr(2) - ParamStr(ParamCount) にコマンドへの引数が入る

実際の実装はこちら。

program sudo;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  Windows,
  ShellAPI,
  System.SysUtils;

var
  LParamIndex: Integer;
  LCommand   : String;
  LParameters: String;
  LCurrentDir: String;
  LhInstance : HWND;
begin

  if ParamCount >= 1 then
    try
      LCommand := ParamStr(1);

      if ParamCount >= 2 then
        for LParamIndex := 2 to ParamCount do
          LParameters := LParameters + ParamStr(LParamIndex) + ' '
      else
        LParameters := '';

      LCurrentDir := ExtractFilePath(ParamStr(0));

      LhInstance := ShellExecute(
        0,
        'runas',
        PChar(LCommand),
        PChar(LParameters),
        PChar(LCurrentDir),
        SW_SHOW);
    except
      on E: Exception do
        Writeln(E.ClassName, ': ', E.Message);
    end;

end.

Windows 向けにChocolateyでインストールできるsudoの内部実装がVBScriptだったので、代替案を探す

セキュリティポリシー等の問題でVBScriptが禁止になったのだけど、Chocolateyでインストールできるsudoは内部実装でVBScriptが使われていたので、代替案を探すことにします。

とりあえず、検索して見つかったものをいくつか列挙してみました。

qiita.com

orebibou.com

tkntkn.hatenablog.jp

できればコマンドプロンプトPowerShellの両方で使いたいだけど、良い代替方法がいまいち見当たらない感じ。

場合によっては、自分で実装してしまうというのも一つの解決策かもしれません。あるいは BitBucket や GitHub で公開されているコードをビルドするとか。

qiita.com

自分が欲しい機能は管理者権限が必要なプロセスを起動させたい、というだけです。UNIX の sudo のように一般ユーザ権限のコマンドからパイプで sudo 経由で実行したコマンドに何かを渡したいという要望はありません。

そうすると、手元にある Delphi で Win32/Win64 コマンドラインアプリケーションとして作成し、ShellExecute するアプリを作ればよいような気がしてきました。

複数の画像を順番どおりにPowerPointのファイルに差し込む作業を自動化する

とある事情でキャプチャ画像を順番通りにPowerPointのスライドに差し込む必要が出たのですが、こんなのを手作業でやるのはめんどくさいのでで自動化する方法を探したところ、RubyPowerPoint ファイルを生成できるものを見つけました。

github.com

そこで、これを使って画像を pptx に差し込む処理を汎用的に使えるようなスクリプトにしてみました。現時点ではとりあえず動くレベルの試験実装ですが、最低限の目的は達せられました。awk が動く環境なら、Linux (Windows Subsystem for Linux), macOS, cygwin のどれでも動くはずです。

作業に必要な powerpoint gem のインストール

gem install powerpoint でOKです。(必要に応じて su とか sudo してください)

画像一覧を標準入力から受け取って powerpoint gem で画像を差し込むスクリプトを生成する処理をつくる

とりあえずこんなふうに awk で実装してみました。ファイル名は generateImagePptx.awk とでもつけておきます。

#!/usr/bin/awk -f
BEGIN {
        print "#!/usr/bin/ruby"
        print ""
        print "require \"powerpoint\""
        print "@deck = Powerpoint::Presentation.new"
        print ""
}

{
        printf "title      = \"%s\"\n", $1 ;
        printf "image_path = \"%s\"\n", $1 ;
        print  "@deck.add_pictorial_slide title, image_path" ;
        print ""
}

END {
        print  "@deck.save('images.pptx')"
}

これで images.pptx に対して、指定されたファイル一覧を差し込む(正確には新規作成する)処理が生成できます。

実行してみる

png形式のファイルをまるごと渡すとスクリプトが作られるので、たとえば次のように実行するとよいでしょう。

 ls *.png | generateImagePptx.awk | ruby

こうすれば、生成されたスクリプトがそのまま ruby 経由で実行されます。

差し込まれる画像の順番が思ったとおりにならない場合の対処

ファイル名の命名規則によっては思った通りの順番にならないことがあります。たとえばファイル名が slide-1.png, slide-2.png のように命名されていると、ls の結果が次のようになってしまい、意図通りの順になりません。

$ ls -l *.png
-rw-r--r--  1 pslabo  staff  0  6 15 06:48 slide-1.png
-rw-r--r--  1 pslabo  staff  0  6 15 06:48 slide-10.png
-rw-r--r--  1 pslabo  staff  0  6 15 06:48 slide-2.png
-rw-r--r--  1 pslabo  staff  0  6 15 06:48 slide-3.png
-rw-r--r--  1 pslabo  staff  0  6 15 06:48 slide-4.png
-rw-r--r--  1 pslabo  staff  0  6 15 06:48 slide-5.png
-rw-r--r--  1 pslabo  staff  0  6 15 06:48 slide-6.png
-rw-r--r--  1 pslabo  staff  0  6 15 06:48 slide-7.png
-rw-r--r--  1 pslabo  staff  0  6 15 06:48 slide-8.png
-rw-r--r--  1 pslabo  staff  0  6 15 06:48 slide-9.png

画像ファイルのタイムスタンプが時系列に並んでいるならば、-tr をつけてあげれば次のように意図通りに並びます。

$ ls -ltr *.png
-rw-r--r--  1 pslabo  staff  0  6 15 06:48 slide-1.png
-rw-r--r--  1 pslabo  staff  0  6 15 06:48 slide-2.png
-rw-r--r--  1 pslabo  staff  0  6 15 06:48 slide-3.png
-rw-r--r--  1 pslabo  staff  0  6 15 06:48 slide-4.png
-rw-r--r--  1 pslabo  staff  0  6 15 06:48 slide-5.png
-rw-r--r--  1 pslabo  staff  0  6 15 06:48 slide-6.png
-rw-r--r--  1 pslabo  staff  0  6 15 06:48 slide-7.png
-rw-r--r--  1 pslabo  staff  0  6 15 06:48 slide-8.png
-rw-r--r--  1 pslabo  staff  0  6 15 06:48 slide-9.png
-rw-r--r--  1 pslabo  staff  0  6 15 06:48 slide-10.png

しかしなんらかの理由でタイムスタンプが時系列順ではない場合は、この方法では思った通りの順番で出力できません。

$ ls -ltr *.png
-rw-r--r--  1 pslabo  staff  0  6 15 06:48 slide-1.png
-rw-r--r--  1 pslabo  staff  0  6 15 06:48 slide-3.png
-rw-r--r--  1 pslabo  staff  0  6 15 06:48 slide-4.png
-rw-r--r--  1 pslabo  staff  0  6 15 06:48 slide-6.png
-rw-r--r--  1 pslabo  staff  0  6 15 06:48 slide-7.png
-rw-r--r--  1 pslabo  staff  0  6 15 06:48 slide-8.png
-rw-r--r--  1 pslabo  staff  0  6 15 06:48 slide-9.png
-rw-r--r--  1 pslabo  staff  0  6 15 06:49 slide-10.png
-rw-r--r--  1 pslabo  staff  0  6 15 06:50 slide-5.png
-rw-r--r--  1 pslabo  staff  0  6 15 06:50 slide-2.png

この場合は sort コマンドを間に挟みつつ slide-number.png-t - で slide と number.png に分割し、number.png の部分を -k 2 -n で数値順ソートすれば意図通りの順番に並べることができます。

$ ls *.png | sort -t - -k 2 -n | xargs -n 1 ls -l
-rw-r--r--  1 pslabo  staff  0  6 15 06:48 slide-1.png
-rw-r--r--  1 pslabo  staff  0  6 15 06:50 slide-2.png
-rw-r--r--  1 pslabo  staff  0  6 15 06:48 slide-3.png
-rw-r--r--  1 pslabo  staff  0  6 15 06:48 slide-4.png
-rw-r--r--  1 pslabo  staff  0  6 15 06:50 slide-5.png
-rw-r--r--  1 pslabo  staff  0  6 15 06:48 slide-6.png
-rw-r--r--  1 pslabo  staff  0  6 15 06:48 slide-7.png
-rw-r--r--  1 pslabo  staff  0  6 15 06:48 slide-8.png
-rw-r--r--  1 pslabo  staff  0  6 15 06:48 slide-9.png
-rw-r--r--  1 pslabo  staff  0  6 15 06:49 slide-10.png

したがって、次のように実行すればファイルのタイムスタンプによらず順番に画像を差し込んだ pptx を生成できます。

 ls *.png | sort -t - -k 2 -n | generateImagePptx.awk | ruby

これでとりあえず最低限の目的は達せられていますが、ruby を別コマンドで実行しなければならない点がイマイチです。ここは print や printf の後に | "/usr/bin/ruby" をつけて awkスクリプト内で ruby と連携したほうがよいですね。