Windows11再インストール時にネットワークアダプタードライバが消えていた時の対処
家でサブマシンとして使っていたノートPC (ThinkBook 13s Gen 4) が少し前から電源周りの調子が悪く、スリープから復帰しないのでしばしば電源ボタン長押しでシャットダウンするのを繰り返していたら、ある日Windowsを全くブートできない状態になってしまいました。
仕方がないので USB起動ディスクを作成 し、USBブートして修復を試みたのですがこれでも直らず、結局Windowsの再インストールを行うことになりました。
ところがWindowsを再インストールして初期セットアップ画面に入ったところ初期インストールで入るドライバにこのマシンのネットワークアダプターが対応していなかったようで、ネットワーク接続を求める画面でネットワークアダプタードライバのインストールを求められてそこから先に進めなくなってしまいました。
ここからの対処が色々面倒だったので、ここに段取りを記録しておきます。
- PCベンダー (この場合はLenovo) のサポートページを開き、シリアル番号を入力して自分のPCのサポートページを開く
- ドライバーダウンロードページを開き、「イーサネットLAN」や「ワイヤレスLAN」など関連しそうなカテゴリのドライバをダウンロード、USBメディアに保存しておく
- セットアップが止まっていたPCにUSBメディアを刺し、セットアップ画面でドライバのインストールボタンを押してUDBメディアのフォルダを選択、ドライバのインストールを行った……がドライバを自動検出できずインストールに失敗!
Shift-F10キーを押してコマンドプロンプトウィンドウを開き、ドライバのexeファイルを直接実行してインストーラーを起動してドライバをインストール- そのままコマンドプロンプトで
shutdown /r /t 0でマシンを再起動 - Windowsの初期セットアップ画面を進めてネットワーク接続ができることを確認
- ここでつながらない場合、もう一度再起動してBIOS設定を確認し、ネットワーク設定でワイヤレスLANを使うように設定されているかを確認する
この手順で対応できました。Windowsの初期セットアップ画面では Shift-F10 でコマンドプロンプトが起動できることは色んな場面で役に立つので覚えておいた方がいいです。
しかし初期セットアップ時にネットワーク接続&MSアカウント紐付け必須 *1 になったのは面倒ですねえ。まあそのお陰でMSアカウント側に設定が残っていて、そこから復帰することができたのでまあ善し悪しですが。アプリなんかは当然MS Storeからインストールしたものしか復帰できないのでAndroidやiOSと比較するとかなり限定的ですが、それもまた善し悪しですねえ。
*1:Homeバージョンの話でPro版ではローカルアカウントでもセットアップ可能です
Tsurugiは大文字小文字を区別するのか
このエントリは Tsurugi Advent Calendar 2025 の19日目のエントリです。前日は id:hishidama さんによる「 Tsurugi JDBCの使い方 - シャットダウンオプション 」でした。
取り上げる題材はTsurugiのSQLでは大文字小文字の区別はどのようになっているかというものです。結論を先に挙げると次の通りです。
- SQLキーワード (
SELECTやFROMなど) は大文字小文字を区別しない - ユーザーが定義するデータベースオブジェクト名 (テーブル名や列名など) はデフォルト設定では大文字小文字を区別し、小文字に正規化する設定が存在する
- その設定は
tsurugi.iniの[sql]セクションに存在するlowercase_regular_identifiersで、デフォルトではfalseに設定されている - ただし上記設定に関わらず、引用符で囲まれた識別子は大文字小文字を区別する
- その設定は
多くのRDBMSでは引用していないデータベースオブジェクト名は大文字小文字を区別しないため、意外とつまずくかもしれないポイントです。以下で具体的な挙動を見ていきます。
デフォルト設定での動き
Tsurugiをインストール直後の tsurugi.ini の [sql] セクションの記述は次のようになっています。
[sql]
#commit_response=STORED
#default_partitions=5
#lowercase_regular_identifiers=false
#max_result_set_writers=64
#scan_block_size=100
#scan_default_parallel=4
#scan_yield_interval=1
#stealing_enabled=true
#thread_pool_size=
lowercase_regular_identifiers の設定がコメントアウトされていますが、デフォルトの設定値はここに記述されている false です。
この状態で次のDDLを実行してテーブルを作ります。
create table Case_Sample ( ID bigint primary key, Col_1 varchar(*) not null );
tgsqlコンソールでテーブル一覧を確認すると、テーブル名に設定した大文字小文字が反映されていますね。
tgsql> \show table Case_Sample
ここでテーブル名を全て小文字にして \show table コマンドを実行してみるとテーブルが見つかりません。
大文字小文字を正しく記述することでテーブル定義を確認することができます。
tgsql> \show table case_sample 'case_sample' table not found tgsql> \show table Case_Sample databaseName=null schemaName=null tableName='Case_Sample' (0) ID: BIGINT NOT NULL (1) Col_1: VARCHAR(*) NOT NULL primary key=[ID]
SQLの実行についても同様に、テーブル名や列名について大文字小文字を正しく記述する必要があります。
tgsql> insert into case_sample (id, col_1) values (1, 'test'); start transaction implicitly. option=[ type: OCC label: "tgsql-implicit-transaction2025-12-09 00:29:50.856+09:00" ] SYMBOL_ANALYZE_EXCEPTION (SQL-03004: compile failed with error:table_not_found message:"table "case_sample" is not found" location:<input>:1:13+11) transaction rollback finished implicitly. tgsql> insert into Case_Sample (ID, Col_1) values (1, 'test'); start transaction implicitly. option=[ type: OCC label: "tgsql-implicit-transaction2025-12-09 00:30:22.674+09:00" ] (1 row inserted) transaction commit(DEFAULT) finished implicitly. tgsql> select id, col_1 from case_sample; start transaction implicitly. option=[ type: OCC label: "tgsql-implicit-transaction2025-12-09 00:31:00.586+09:00" ] SYMBOL_ANALYZE_EXCEPTION (SQL-03004: compile failed with error:table_not_found message:"table "case_sample" is not found" location:<input>:1:23+11) transaction rollback finished implicitly. tgsql> select ID, Col_1 from Case_Sample; start transaction implicitly. option=[ type: OCC label: "tgsql-implicit-transaction2025-12-09 00:31:28.003+09:00" ] [ID: BIGINT, Col_1: VARCHAR(*)] [1, test] (1 row) transaction commit(DEFAULT) finished implicitly.
lowercase_regular_identifiers に true を設定した場合の動き
先にも述べたように多くのRDBMSでは引用していないデータベースオブジェクトは大文字小文字を区別しないため、このデフォルトの動きは違和感を感じる方も多いかもしれません。
そこで tsurugi.ini の [sql] セクションに存在する lowercase_regular_identifiers の設定を true に変更してみます (先程作成したテーブルを削除した前提で説明しています) 。
[sql]
#commit_response=STORED
#default_partitions=5
lowercase_regular_identifiers=true
#max_result_set_writers=64
#scan_block_size=100
#scan_default_parallel=4
#scan_yield_interval=1
#stealing_enabled=true
#thread_pool_size=
先程と同様に次のDDLでテーブルを作成してみます。
create table Case_Sample ( ID bigint primary key, Col_1 varchar(*) not null );
tgsqlコンソールでテーブル一覧を確認するとテーブル名は小文字になっています。それは先程の設定が「SQLで指定したデータベースオブジェクトの識別子は小文字に正規化する」という設定になっているからです。
tgsql> \show table case_sample
\show table コマンドを実行すると列名も小文字になっていることが確認できます。
tgsql> \show table case_sample databaseName=null schemaName=null tableName='case_sample' (0) id: BIGINT NOT NULL (1) col_1: VARCHAR(*) NOT NULL primary key=[id]
SQLを実行してみると、大文字小文字どちらでも動きます。ただし、識別子を引用する場合はこの設定であっても区別します。 この挙動は概ね PostgreSQLと同じ挙動 になります。
tgsql> insert into case_sample (id, col_1) values (1, 'test'); start transaction implicitly. option=[ type: OCC label: "tgsql-implicit-transaction2025-12-09 00:26:42.940+09:00" ] (1 row inserted) transaction commit(DEFAULT) finished implicitly. tgsql> select id, col_1 from case_sample; start transaction implicitly. option=[ type: OCC label: "tgsql-implicit-transaction2025-12-09 00:27:02.509+09:00" ] [id: BIGINT, col_1: VARCHAR(*)] [1, test] (1 row) transaction commit(DEFAULT) finished implicitly. tgsql> SELECT ID, COL_1 FROM CASE_SAMPLE; start transaction implicitly. option=[ type: OCC label: "tgsql-implicit-transaction2025-12-09 00:28:08.814+09:00" ] [id: BIGINT, col_1: VARCHAR(*)] [1, test] (1 row) transaction commit(DEFAULT) finished implicitly. tgsql> select Id, Col_1 from Case_Sample; start transaction implicitly. option=[ type: OCC label: "tgsql-implicit-transaction2025-12-09 00:29:01.847+09:00" ] [id: BIGINT, col_1: VARCHAR(*)] [1, test] (1 row) transaction commit(DEFAULT) finished implicitly. tgsql> select Id, Col_1 from "Case_Sample"; start transaction implicitly. option=[ type: OCC label: "tgsql-implicit-transaction2025-12-09 00:36:58.053+09:00" ] SYMBOL_ANALYZE_EXCEPTION (SQL-03004: compile failed with error:table_not_found message:"table "Case_Sample" is not found" location:<input>:1:23+13) transaction rollback finished implicitly.
ちなみに \show table コマンドの場合は設定に関わらず大文字小文字を区別するので注意してください。これはSQLではなくtgsqlが備えるコマンドです。
tgsql> \show table Case_Sample 'Case_Sample' table not found
まとめ
まとめると、Tsurugiはデフォルトでデータベースオブジェクト名の大文字小文字をSQL上で区別します。他のRDBMSに慣れていると違和感を感じる方が多いかもしれませんが、Java系のORマッパーを使っている場合などCamelCaseの識別子を使いたい場合にはこの方がいいと感じる方もいるかもですね。
個人的な意見としては、混乱しないように次のどちらかのルールで運用した方がいいと思います。
lowercase_regular_identifiersをtrueに設定して運用する- デフォルト設定で運用する場合、データベースオブジェクト名は小文字で統一するかCamelCaseにする
(参考) 他のRDBMSではどのようになっているの?
先程も述べたように lowercase_regular_identifiers に true を設定した場合の動きは概ねPostgreSQLと同じです。
SQL標準では大文字に正規化することになっており、Oracleなどはそのような挙動になっています。
参考までに他のRDBMSでのこの動きについて説明しているドキュメントのリンクを挙げておきます。MySQLはデータベースオブジェクトをファイルとして保存するため、OSやファイルシステムによって挙動が変わることで有名ですね。
Anthropicの "Code execution with MCP" にモヤモヤする
Anthropicが発表したModel Context Tool (MCP) はAIアプリケーションのツールコールのインターフェースを標準化するプロトコルとして大ブームになり、今や様々なソフトウェアやWebサービスが競ってMCPサーバーを提供するようになっています。 *1
しかし先日、そのAnthropic自らがMCPを利用したAIエージェントアプリケーションの開発に伴う問題点と、それに対応する新たなアプローチを "Code execution with MCP: Building more efficient agents" というタイトルで発表しました。
上記エントリ自体はやや抽象的なところもあり、分かりにくいところもあるのですが、発表後様々な人が内容を検証、実際にサンプルアプリケーションを作ったりしています。概ね次のような内容です。
- MCPを使ったAIエージェントはトークン消費量が莫大になるという問題がある
- 1の対応策としてこれまでのLLMが直接MCPツールをコールするスタイルからコード実行 (Code execution) というスタイルに変えることを提案する
- MCPツール定義は段階的に提示する (Progressive disclosure)
- 上記エントリではファイルツリーの形にして管理することを提案している
- MCPサーバーとやり取りを行うプログラムコードを作成しておき、これをツール定義として提示する
- LLMには 上記ツールを利用するプログラムコードを生成 させ、そのコードをエージェントが実行して結果を取得、LLMに返す
- これによりトークンの消費量が大幅に抑えられる
- MCPツール定義は段階的に提示する (Progressive disclosure)
1の課題はよく分かります。特にサイズの小さいローカルLLMを使ったAIエージェント開発においては結構深刻な問題で、自分が作ったときにはエージェントコード側でLLMに見せるツール定義を絞ったりしたことがありました。
Anthropicはその対応策として新たに「LLMにはMCPを利用するコードを生成させる」というアプローチを提示してきた *2 わけですが、確かに提案としてはいいと思うものの非常にモヤモヤするものがありました。というのも予め準備したコードからMCPサーバーへ接続するのならば、接続先は別にMCPサーバーである必要はなく従来のAPIで何ら問題ないわけです。Anthropicは自分達が送り出したMCPを否定するようなことを言い出したように自分には見えました。
まあAnthropic自身もMCPを考え出した時はこのようになることが見えていなかったんだろうなあと。このコード実行方式についても主流になるかどうかは不明で、今後も色んなアプローチが模索されるでしょう。新しいテクノロジー周辺の技術は非常に入れ替わりが激しいので、何か決定版のようなものが登場したと思っても少し時間が経てばコロッとひっくり返される可能性があると常に心掛けておいた方が良さそうですね。
*2:ちなみにこのアプローチはもう少し前に Cloudflareが似たアプローチを発表 しており、それを受けてまとめたもののようです
Java2Dで縁取り文字列を描画する方法
最近Java2Dでちょっとした画像加工処理を行う機会があったのですが、意外と日本語の情報が見当たらなかったものがあったので備忘録的なメモです。今更こんな古いAPIの話を?とも思いますが、こういう基礎的なAPIはいつになっても使うものですし。
やることは既存の画像に対して文字を重ね合わせて出力するというものです。それも縁取りのある文字列を描画します。
次のような画像に対して...

次のように文字列を重ねます。

見やすくするために文字列は縁取りを付けて描画します。これが今回のポイントです。
Java2Dの java.awt.Graphics2D クラスには drawString() メソッドがありますが、このメソッドでは縁取り文字列を描画することができません。
縁取り文字列を描画するには描画しようとする文字列のグリフ情報を保持する java.awt.font.GlyphVector クラスを利用します。
次のように java.awt.Font インスタンスと文字列から GlyphVector インスタンスを作ります。
// 加工元の画像ファイルに対するGraphics2Dオブジェクトの取得 var image = ImageIO.read(Objects.requireNonNull(Java2DSample.class.getResourceAsStream("/java2dtest.png"))); var graphics = (Graphics2D) image.getGraphics(); // GlyphVectorの取得 var font = new Font(Map.of( TextAttribute.FAMILY, Font.SANS_SERIF, TextAttribute.SIZE, 80, TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD)); var glyphVector = font.createGlyphVector(graphics.getFontRenderContext(), "Outlined Text");
Glyphvector の getOutline() メソッドをコールすることで当該グリフを描画するための java.awt.Shape オブジェクトを取得します。引数には描画座標を指定します (graphics2D#drawString() と同じく座標はベースラインの左端の文字位置) 。
var outlineShape = glyphVector.getOutline(120.0f, 980.0f);
あとはこの Shape を使って輪郭と塗りつぶしをそれぞれ描画することになります。滑らかに描画するためにアンチエイリアスをオンにすることをお勧めします。
// 滑らかに描画するためにアンチエイリアスをオンにし、品質重視のレンダリングヒントを与えるのがお勧め graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); // 輪郭の描画 graphics.setStroke(new BasicStroke(10.0f)); graphics.setColor(Color.BLACK); graphics.draw(outlineShape); // 塗りつぶし graphics.setColor(Color.WHITE); graphics.fill(outlineShape);
これで先に示したように縁取り文字列を描画することができます。
JavaFXだとCSSで指定できるのでこの辺りは楽ですね。でもJavaFXは今回のようにアプリを作らず純粋に画像を操作するだけの目的には使えないんですよね。
今回のサンプルコードの全体は以下のgistにアップしてあります。
ThunderbirdでGmail送信ができなくなったらSMTPの認証設定を確認しよう
自分は長いことメーラーとしてはずっとThunderbirdを使っていて、仕事場でも自宅でもGmailはThunderbird経由で使っています。さらに大昔になると Becky とか使ってたのですが、一時期macユーザーになった時にApple純正のメーラーが余りにも使いにくかったので、Windowsによくあるようなメーラーを探していたところThunderbirdが良かろうということで使うようになり、以来Windowsに戻ってもThunderbirdを使っているという経緯です。
で、家の方で先程Thunderbirdからメールを送信しようとしたら認証で引っ掛かりました。パスワードが正しいのにどうして?そういや大分前からGmailはサードパーティーツールとの連携にはOAuth2になったからパスワード入力する時点でおかしいのでは?と気付きSMTP認証設定を開いてみたところ [認証方式] が 通常のパスワード認証 になっていました…。元々Gmailへの連携設定はThunderbirdのウィザード経由で行っていたのですが、それが大分昔のことだったので古い設定にままになっていたのですねえ。
正しくは次のように OAuth2 に設定する必要があります。

この設定を行って改めてメール送信するとGoogleの認証ダイアログが開き、認証することで送信可能になります。
しかしGmailがサードパーティー連携にOAuth2を要求するようになったのは大分前の話のはずで、次の記事にあるように2022年5月時点ではそうなっていました。
つまり長いことプライベート用途でメールを送信する機会がなく、送られてくるメールを読むだけだったのですね。仕事ですらメールを使うことはぐっと減りましたし、本当にメールを使う機会が減ったんだなあと改めて実感することになりましたよ。