3流プログラマのメモ書き

元開発職→現社内SEの三流プログラマのIT技術メモ書き。 このメモが忘れっぽい自分とググってきた技術者の役に立ってくれれば幸いです。(jehupc.exblog.jpから移転中)

古めのシンクライアントでフォントスムージング(ClearType)を有効にしたい

最近はClearType前提のフォントが増えてきたのに、使用しているシンクライアントではそれらのフォントがギザギザ、ジャギーになってしまっています。 その対応方法について調査してみました。

リモートセッションでフォントスムージングを使用するには、サーバー、クライアント双方の設定が必要です。
(ただしWindows Server 2008: Presentation Virtualization with Enhanced Terminal Servicesによるとフォントスムージングにより必要とする帯域幅が4~10倍ほど増大するようです)

サーバ側はWindows Server 2008以降であればデフォルトでリモートセッションでのClearType機能を提供するようになっています。
以下のグループポリシーが未定義(デフォルト)あるいは無効なら、フォントスムージングは有効です。
コンピューターの構成 - 管理テンプレート - Windowsコンポーネント - リモートデスクトップサービス - リモートデスクトップセッションホスト - リモートセッション環境 - フォントスムージングを許可しない

つまり、2008以降なら特にサーバ側で何もすることはないということですね。

さて次はクライアント側です。サーバ側でフォントスムージングが有効なっていてもクライアント側でそれを使用する設定になっていなければClearTypeは使用できません。

Windows標準のリモートデスクトップクライアントアプリであれば、オプションの エクスペリエンス - フォントスムージング にチェックを入れると有効になり、なめらかに表示されます。

問題となるのは、それ以外のリモートクライアントソフトです。特にWindows系以外のシンクライアント端末です。

今回フォントスムージングが有効にならず困っているのは SunRay2(SunRay Connector for Windows2.1→RDP使用)、FUTRO A300(ICA Client) です。
用意されているUIにはフォントスムージングの設定をするようなところはありませんでした。

FUTRO A300はClearTypeの設定があった!(ICAのみ)

FUTROでICA Clientを使っている場合、GUIメニューとかでは用意されていませんが、コンフィグファイルに直接設定を入れれることが判明しました。(FUTROに入っているCitrixReceiverのバージョンははっきりとはわかりませんがおそらく12くらいだと思います。ちなみにRDPの場合のフォントスムージング有効設定はわかりませんでした。)

まずコンソールを立ち上げます。
(コンソールの追加はeLux RL の設定UIより、[Configuration]タブ-[New]-[Local]タブ で XTERM を選び、登録します。eLuxの[Application]タブに追加したコンソールが表示されるのでそこから立ち上げます)

wfclient.iniに、ClearType有効の設定を入れます。

elux> vi /setup/ica/wfclient.ini

[WFClient]
FontSmoothingType=3 ←追加

これで保存すると、次回ログオンよりClearTypeが有効になりました。
上記の設定はCitrix Doc 操作性の向上に書いてます。

リモートセッションで強制的にClearTypeを有効にする方法(PowerShellスクリプト使用)

SunRayではClearTypeを有効にするコマンド引数が見つかりませんでした。
(SRSS ver5時代のWindowsConnecorだとWEB見る限り設定がありそうです。使ってるのはSRSS v4世代で10年以上前なのでなくて当たり前かも...)

しかし、2008にリモート接続後、[ClearTypeテキストチューナー]を立ち上げ、[Clear Type を有効にする]にチェックを入れウィザードを完了させるとフォントスムージングが機能するようになりました。
([ClearTypeテキストチューナー]は、ファイル名を指定して実行で cttune とするか、コンパネ-ディスプレイ-ClearTypeテキストの調整 から立ち上げできます。)

が、再ログオンするとチェックが無効になってしまいます。

要はこのチェックをログイン毎に有効にすればいいのでは と考えました。
チェック有効前後のユーザーのレジストリを比較すると、以下のようになっていました。

有効前:
[HKEY_CURRENT_USER\Control Panel\Desktop]
"FontSmoothingGamma"=dword:00000000
"FontSmoothingType"=dword:00000002

[HKEY_CURRENT_USER\Software\Microsoft\Avalon.Graphics\DISPLAY1]


有効後:
[HKEY_CURRENT_USER\Control Panel\Desktop]
"FontSmoothingGamma"=dword:000004b0
"FontSmoothingType"=dword:00000001

[HKEY_CURRENT_USER\Software\Microsoft\Avalon.Graphics\DISPLAY1]
"ClearTypeLevel"=dword:00000064
"EnhancedContrastLevel"=dword:00000032
"TextContrastLevel"=dword:00000000

このレジストリを設定してみましたが、現象は変わりません。

いろいろ調査してるとwindows 7 - Enable/disable ClearType in Windows7 - Stack Overflowに有意義な情報を発見。

SystemParametersInfo API関数を使って、ClearTypeを有効にさせてしまおうという方法です。(SystemParametersInfo APIは壁紙を変えたりタなど、ユーザーがWindows環境をカスタマイズする時に用いる関数です。詳しくは[ S00_SystemParametersInfo 関数サンプル 概要 ] - Mr.XRAYで幾つかの機能がわかりやすく掲載されてます。)

WinAPIなので、いろいろな呼び出し方法ができますが、上記フォーラムに載っていたPowerShellから呼び出す方法を取ることにしました。
このスクリプトをユーザのログオンスクリプトとして実行すれば、再ログオンし設定がリセットされても大丈夫という理屈です。

フォーラム上のコードは引数が1ならClearType有効、0なら無効ですが、グループポリシーログオンスクリプトでの引数の設定がうまく行かなかったので、コード内で無理やり1にしました。

コードは以下となります。

#requires -version 2.0
#param([bool]$enable) ←ログオンスクリプトでうまくいかないのでコメントアウト。(PowerShellコンソールからならうまくいく)

$enable = 1
#↑コード内でフォントスムージング有効のフラグをハードコーディング。

$signature = @'
[DllImport("user32.dll")]
public static extern bool SystemParametersInfo(
    uint uiAction,
    uint uiParam,
    uint pvParam,
    uint fWinIni);
'@

$SPI_SETFONTSMOOTHING      = 0x004B
$SPI_SETFONTSMOOTHINGTYPE  = 0x200B
$SPIF_UPDATEINIFILE        = 0x1
$SPIF_SENDCHANGE           = 0x2
$FE_FONTSMOOTHINGCLEARTYPE = 0x2

$winapi = Add-Type -MemberDefinition $signature -Name WinAPI -PassThru

if ($enable)
{
    [void]$winapi::SystemParametersInfo($SPI_SETFONTSMOOTHING, 1, 0, $SPIF_UPDATEINIFILE -bor $SPIF_SENDCHANGE)
    [void]$winapi::SystemParametersInfo($SPI_SETFONTSMOOTHINGTYPE, 0, $FE_FONTSMOOTHINGCLEARTYPE, $SPIF_UPDATEINIFILE -bor $SPIF_SENDCHANGE)
}
else
{
    [void]$winapi::SystemParametersInfo($SPI_SETFONTSMOOTHING, 0, 0, $SPIF_UPDATEINIFILE -bor $SPIF_SENDCHANGE)
}
#↑ハードコーディングしてるので、elseの中(ClearType無効化)は通らない

これを拡張子ps1を付けて保存し、グループポリシーにてユーザーのログオンスクリプトとして設定します。
(今回始めてPowerShellをログオンスクリプトに登録したのですが、ログオン設定ダイアログの中の[PowerShellスクリプト]タブで設定ができます。。パラメーターはうまくいきませんでした。順序は、[Windows PowerShellスクリプトを最後に実行] にしました。)

また、PowerShellスクリプトファイルでデフォルトでは実行できないポリシーとなっているので、各サーバで以下のPowerShellを実行し、スクリプトファイルの実行を許可します。

PS > set-executionpolicy remotesigned
実行ポリシーの変更
実行ポリシーは、信頼されていないスクリプトからの保護に役立ちます。実行ポリシーを変更すると、about_Execution_Policies
のヘルプ トピックで説明されているセキュリティ上の危険にさらされる可能性があります。実行ポリシーを変更しますか?
[Y] はい(Y)  [N] いいえ(N)  [S] 中断(S)  [?] ヘルプ (既定値は "Y"): y

(set-executionpolicy に指定する値の意味については@IT:WindowsでPowerShellスクリプトの実行セキュリティポリシーを変更するが参考になります。 RemoteSignedはローカル保存は実行可、ネットからのダウンロードは署名必要 という設定です。共有フォルダに配置しているものも、この権限で動きました。)