2026年1月17日 (土)

画像生成AIで遊んでいる人の役にたつかもしれません

aiimeta というツールを作りました。画像生成AIで生成した画像ファイルから、「AI生成メタデータ」というものを取り出して表示するアプリです。具体的にはプロンプト (いわゆる「呪文」) や使用したAIモデル、各種設定パラメーター等を表示できます。

このツールは「画像を分析してプロンプトを推測する」というAI的なことをやるわけではなくて、画像ファイル中に埋め込まれている情報を取り出すだけです。AI生成画像の全てにメタデータが埋め込まれているわけではないので、メタデータを含まない画像では表示できません。Stable Diffusion WebUI (通称 A1111) に PNG Info という機能がありますが、あれと同じようなものです。ただし、A1111 の PNG Info は、A1111 自身 (または互換ツール) で生成した画像の情報しか表示できませんが、aiimeta は ComfyUI や SwarmUI にも対応しています。なお、AI生成画像を投稿できるサイトはたくさんありますが、サイトによっては投稿された画像からメタデータを削除するところもあるようです。そういうサイトの画像を aiimeta に入れてもメタデータは表示できません。あしからず。

(pixivの「AI生成」タグのついた画像はAI生成メタデータを含んでいるものが多いような気がします。)

Windows 用の .NET 10 WPF アプリです。Stable Diffusion 等の画像生成 AI で遊んでいるかたなど興味のあるかたは GitHub からダウンロードしてお試しください。なお、.NET Desktop Runtime の 10.0 以降が必要です。(現時点では 10.0 が最新版なので「以降」というのは変ですが。)

この記事で触れた「文字ボケ」対策も入っています。タイムリーだったもので。

2026年1月 2日 (金)

WindowsのDPIの違うマルチモニター環境でWPFアプリの文字がボケないようにする

いくら探してもちゃんとした説明が見つからないし、ChatGPT 5が教えてくれたやり方も機能しなかった。

正解は shibayan/WPF-PerMonitorV2-Sample にあった (芝村さん、ありがとうございます!) が、解説が一切ない。せっかくなので、私が理解した範囲で解説しておく。

何が問題か

最近のWindowsでは、「ディスプレイ」の「拡大/縮小」という機能によってモニターごとに「倍率」を指定できる。開発者ではないユーザー向けの説明には「OSが自動的にアプリの表示を拡大縮小します」と書いてある。起動したアプリのウインドウを倍率が違うモニターに動かすと、アプリが何もしない場合は確かに「OSが自動的に表示を拡大縮小する」のだが、これは画像としての拡大縮小なので文字がボケて読みにくくなってしまう。

でも、Windowsの標準のアプリ (エクスプローラーとかメモ帳とか) はどれも、文字がボケずに表示される。それは、「アプリが何とかするので、OSは倍率の通知だけやってくれ」というモードがあって、それを使っているから。実際には個々のアプリが自分で「何とかするコード」を書くわけではなくてUIフレームワークが何とかしてくれる。今回の私の関心事はWPFなのだが、もちろんWPFもその機能を備えている。

…のだが、(マイクロソフトによると「互換性のために」) デフォルトではこの機能が無効になっている、というか、使い勝手の悪いモードがデフォルトになっているので、そのままだと結局文字がボケてしまう。この設定を変えれば解決する。

設定方法

プロジェクトにapp.manifestを追加して、次のように書く。

<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
</windowsSettings>
</application>
</assembly>

※ プロジェクトにすでにapp.manifestが存在する場合は、それとマージする。新規に追加する場合、asseblyIdentity要素は、もちろんこの例のままじゃなくて適切な値に書き換える必要がある。

文字がボケる件に関係するのはdpiAwareness要素とdpiAware要素で、この内容は丸写しでいいはず。

Windows 10のサポートが終了し、Windows 12もリリースされていない現在では、dpiAwarenessは「PerMonitorV2」固定でいいと思うのだが、実際には5通りの設定が書けるようだ。その説明はここにある。ただし、この説明はWindows Forms用のMSBuildプロジェクトファイルの説明なのでApplicationHighDpiModeなんていう要素名になっている。XMLの書き方はWPFとは違うので参考にしてはいけない。

※ 「だったら、なんでそんなページを参照するのか」と思うだろうが、それはマイクロソフトの公式ドキュメントでPerMonitorV2の説明が他に見つからないからだ。一体、どうなっているのだろう。

.NET Framework 4.8 以降と.NET 6 (というか、Windows Desktop 6 なのか?) 以降で使えるはず。

本題と関係ない追記

大晦日の深夜に、1年ぶりにSecond Lifeにログインして、Arare Cafeにおじゃましたわけですが、ほとんど動かず会話もせずにじっとしていたのは、実は裏で本件の調査をしていたからでした。ちょっと急ぎだったのですが、年が明けた時点ではまだ解決していなかったので、SLはおろそかになってしまいました。久しぶりだったのに失礼しました。

2025年9月27日 (土)

ComfyUIの「Prompt has no outputs」というエラーは「ワークフローに結果を出力するノードが含まれていない」という意味

原因は、ワークフローの編集中にSave Imageノードを削除してしまったり、いろいろ実験していてBypassしてあったり、が多いと思う。

Comfy

私はこのメッセージの意味が分からなくてしばらく悩んでしまったよ。落とし穴は「Prompt」という言葉だ。画像生成AIで「プロンプト」と言ったら、生成する画像を方向付けるテキストデータ、通称「呪文」のことだと思うよね。でも、この「Prompt」はそれとは無関係だったのだ。ComfyUIの「ワークフロー」は、画像生成処理を実行する際にはpythonの内部データ形式 (dict らしい) に変換されているのだが、このデータのことをComfyUIのソース上ではpromptと呼んでいて、それのことだった。エンドユーザー的には、ComfyUIの開発者用語の「Prompt」は「ワークフロー」と同じ意味だと思えばOK。

ということを発見するまでに3時間くらいかかった。そんなこと一般ユーザーには分かりませんよ。Workflow contains no output node くらい言ってくれれば一瞬で分かったのに。

2025年2月 2日 (日)

AngleSharp.js の最新「stable」バージョンは最近の AngleSharp の stable バージョンとは互換がないらしい

AngleSharp (.core) の比較的最近のバージョンはどれも、AngleSharp.js の最新 stable バージョン (0.15) とは互換がないらしい。AngleSharp.js の 1.0.0-beta シリーズを使用する必要がある。

具体的に、AngleSharp 1.2.0 stable と AngleSharp 0.15 stable の組み合わせでは動作しなかった (エラーにもならず、警告メッセージようなものも出ず、単に JavaScript を実行しない)。AngleSharp 1.2.0 stable と AngleSharp 1.0.0-beta.41 との組み合わせは動作した。

このことに気づくまでに3日かかってしまった。(1日あたり2時間くらいずつしか費やしてないけど。) 同じプロジェクトのライブラリーで、最新の stable 同士で組み合わせられないなんて、普通考えないでしょ? しかも、nuget のメタデータでも組み合わせ可能なバージョンだって書いてあるし。解決には、ウェブでいろいろ調べまくっていてたまたま見つけた、Zennの「AngleSharp で ASP.NET Core ウェブアプリケーションの統合テストをする」という記事がヒントになった。この記事では、AngleSharp.js の stable 版はリリースが古く、最新の JavaScript に対応していないので 1.0.0-beta を勧める、みたいに書いてあるのだが、実際は、そういう問題ではなくて、stable 版は全く使い物にならないのだった。

※ ちなみに、困っているときに、BrowsingContext を作るコードを Microsoft Copilot に見せて「JavaScriptを実行できないんだけど何が悪いのか?」と聞いたら、「.WithJS() ではなく .WithJavaScript() を使用してJavaScriptを有効にします。」とか「using AngleSharp.Scripting; と宣言してあることを確認します。」とか言われて調査が迷走したのも時間がかかった一因。「.WithJS() とは別に .WithJavaScript() っていうのがあるのか?」って思ってググると、確かにそういうメソッドで config 作っているコードがたくさん見つかる。でも、実際に書くとそんなメソッドはないと言われ、コンパイラが「package reference が不足していませんか?」という。それで探したら、nuget に AngleSharp.Scripting.JavaScript」なんていうパッケージもあるんだもの。実際はこれは大昔のAngleSharpの話で、今は .WithJavaScript() なんていうメソッドは存在しないのだった…。

「人生に無駄なことなどない」と言うが、この経験もいつか役に立つことがあるのだろうか…。こんな経験が役に立つ場面には、二度と遭遇したくないものだが。

追記

nuget で単に AngleSharp.Js の 1.0.0-beta.41 をインストールすると、dependency として Jint のかなり古いバージョンが自動インストールされるが、それでは動作しない。Jint のもっと新しいバージョン (例えば 4.2.0) をインストールする必要がある。そうすると、nuget が「NU1608 Detected package version outside of dependency constraint: AngleSharp.Js 1.0.0-beta.41 requires Jint (>= 3.0.0 && < 4.0.0) but version Jint 4.2.0 was resolved.」などと文句を言うが、このメッセージは無視する。

なんなんだ。

2024年10月12日 (土)

Google の Cloud Translation API Advanced Service (v3) って昨日は不調でしたか?

このブログに書くのは初めてだと思うのだが、数年前から Google の Cloud Translation API というものを使っている。主に Advanced Service、通称「v3」。

それで、昨日、この API を使うあるツールを修正していたら、そのツールが動かなくなってしまった。

ちょっと大掛かりな修正 (機能追加) をやっていて、しばらくビルドできない状況が続いていたが、やっとビルドできるようになったので試したところ動かなかった。それだけなら至極よくあることだし、特に驚くようなことではないが、今回触ったのはコンテンツの部分だけなのに Cloud Translation API を呼び出す部分で例外が出ていた。ちょっとしたラッパークラスを自分で作っていて、そこは一切触っていなかったのだが、そのクラスの中で。Google.Cloud.Translate.V3.TranslationServiceClient.DeleteGlossary というメソッドの呼び出しが失敗して Grpc.Core.RpcException になる。

例外の StatusCodeInvalidArgument だった。Status.Details を見ても単に "Invalid argument." と書いてあるだけ。当惑したのは、このメッソドには引数が一つしかなく (実際は二つあるのだが、もう一つは省略していた)、文字列型で、そこには毎回固定の文字列を渡しているだけだったからだ。(その文字列は削除する glossary の識別子のようなもので、そのツールでは固定の glossary を一つだけ使うので。) もちろん、その文字列も今まで動いていたものから変更していない。もうちょっとエラーの詳細が知りたいところだが、「InvalidArgument」という以上の追加情報は得られないようだった。

最初に考えたのは、例外が発生するのはこのメソッドだが、実際に間違っているのはこれ以前の Cloud Translation API の呼び出しで、たまたまこのメソッドで間違いが発覚するのではないか、というもの。それで、ほとんど何もせずにこのメソッドに来るようにパッチしたコードを作り、少しずつ呼び出しを増やして原因を探ろうと考えた。ところが、何もしなくてもこのメソッドはエラーになる。クライアントオブジェクトを作って、クレデンシャルを設定して、それですぐ削除しても例外。クレデンシャルの設定に間違いがあるならその部分でエラーになるはずだし、そもそも削除の前の手順はさっきまで問題なく動いていたし。(ちなみに、削除するべき glossary は存在していたし (それはすぐに調べた)、もしも存在しない glossary を削除しようとすると StatusCode.InvalidArgument ではなく StatusCode.NotFound になることは分かっていた。)

いろいろと小さなテストコードを書いて状況を調べたりしたのだが、原因どころか、何が起きているのかもさっぱり分からず。もう深夜になっていたので、あきらめて寝た。

それで、今朝だ。朝起きてすぐに調査の続きをやろうと思ったら … 例外が発生しません。問題なく動きます。

いや、その。動いたからいいとも言えるが、昨日のアレは何だったんだ、と。Google さん、勘弁してよ、と。

とりあえず、不満の掃け口として、ブログに書いてみました。

ということで、たった一つの事象を一般化して導き出した法則:

Google の Cloud Translation API は、勝手に不調になって謎の例外が起きることがある。
その場合、放っておけば翌日には回復する。

(うーむ、本当だろうか?)


ちなみに、Cloud Transationi API を使い始めたころに作ったサンプルがここにあります。GCPのアカウントがあれば API を使った翻訳を試してみることができます。 (トラブったツールはこれじゃありませんがもしも機能これを動かしたら、一部機能は動作しなかったはず。DeleteGlossary 呼ぶ場所があるので。)

2024年10月 1日 (火)

git の「ワークツリー」という用語

日本語で git のことを解説している記事を読むと、初心者向けのものも、かなり高度な内容のものも、だいたいどれも「ワークツリー」という用語を使っているようだ。記事によっては「作業ツリー」になっている場合もあり、また work tree とアルファベットで書いている場合もあるが、アルファベット表記の場合は worktree と一語で書いている記事と work tree と二語で書いている記事が両方あるようだ。

それで、本来英語ではどういうのかと思って git の公式の (英語の) ドキュメントを調べた。そうしたら、なんと、work tree でも worktree でもなくて working tree と呼ぶのが正しいようだった。

びっくりだ。

git のコマンドには、git worktree というものがあって、これは一語の worktree が正しいサブコマンド名。また、git が受け付ける共通オプションの中に --work-tree= というものがあって、これは work tree と二語で書く (ものを、単一のオプション名にするために間にハイフンを入れる) のが正しい。コマンドとしてはそれが正しいのだが、ドキュメントの説明の文章が、それを指す言葉としては、worktree とか work tree とかは使われてなくて、一貫して working tree という言葉を使っているのだ。少なくとも、git の公式ドキュメントは。(The Git Reference Manuals も、Pro Git も。どちらも英語版。) 

それで、Reference Manual はだいたいどれも公式の日本語訳があったなと思って調べたところ、どうやら公式訳は「作業ツリー」と訳しているようだった。ただ、一か所だけ、用語集が「作業ツリー (working tree)」と英ママ (というか、対訳?) で書いている。

ということで、git のこの用語は、英語は「working tree」で、日本語は「ワークツリー」または「作業ツリー」ということらしい。


なぜ、英語の working tree をカタカナで書くと「ワーキングツリー」ではなくて「ワークツリー」になるのか。

すぐに思いつくのは、コマンドに出てくるのが worktree と work-tree なので、それが正しい用語だと思い込んでしまった、というもの。また、英文の公式ドキュメントを読まずに、日本語の解説記事ばかり読んでいるとどれも「ワークツリー」と書いてあるので、それを覚えてしまう人が続出して広まった、というもの。ストーリーとしてはもっともらしい。

でも、意図的にそうしている可能性もあるかもしれない。それは、世の中には英語からカタカナ表記を作る際の「ルール」みたいなものがあって、その中に「~ing は省く」みたいなのがあった気がするからだ。(「あるからだ。」と書こうとしてウェブで調べたが、そのルールを発見できなかった。なので「気がするからだ。」と書いた。私の思い込みかもしれない…。)

実際はどういう理由なのだろうか?

 

2024年9月 7日 (土)

AngleSharpでHTMLファイルを更新する

AngleSharpというと、皆さんウェブサイトのスクレイピングを目的に、専らHTMLの解析と情報の取り出しに使っているようだが、実はHTMLの書き換えや新規作成にも使える。そして、そういう使い方でも、かなり便利だ。

ということで、AngleSharpを、ローカルファイルのHTMLの更新に使う話。(AngleSharpでスクレイピングするやり方は、ウェブに説明が多数あるので、それと重複することには触れない。)

SgmlReaderとの比較

AngleSharpを紹介する記事 (のうち、比較的初期のもの) はたいてい「C#でスクレイピングをしようと思ったら、昔はSgmlReaderが定番だった」みたいに書いている。SgmlReaderはDTDを読んでそれに基づいてSGML文書を解析する機能を持っているので、HTML以外にも「XMLじゃないSGML」を何でも解析できるのが売りだったのだが、実際にはHTMLの解析にばかり使われていたようだ。

そのSgmlReaderとAngleSharp (のHtmlParser) を、HTMLファイルを読み込んで修正して (一部を書き換えて) 保存する、という使い方に関して比較すると、こんな感じだと思う。

  SgmlReader AngleSharp
入力 TextReader、string Stream、string、char[]、ReadOnlyMemory<char>
出力 Stream、TextWriter、ファイル、string TextWriter、string
オブジェクトモデル・要素 全ての要素はXElement型という同じ型になっている。個々の要素の区別はNameプロパティを文字列として参照。(Linq to XMLの仕様) それぞれの要素が専用の型になっている。IHtmlElementという共通のインターフェースもあり、要素を区別しないで扱うことも可能。
オブジェクトモデル・属性 属性を表すXattribute型があり、全ての属性は同じ型。個々の属性の区別はNameプロパティを文字列として参照。属性値は全てstring型 (整数などへの変換は容易)。(Linq to XMLの仕様) 各要素の型に、要素の属性に対応したプロパティがある。各プロパティの型は許される属性値を意識していて、stringの他にintだったりboolだったりする。ITokenList型なんてのもある。
他方、IElementには、属性名も属性値も文字列として操作するメソッドもあり、Linq to XMLのようなダックタイピング的な操作も可能。
要素ごとの型のプロパティで属性値を操作する場合と、IElementとして名前で属性を操作する場合とは連動していて、「両者を混ぜて使っていたら値がずれてしまった」みたいなことにはならない。
ドキュメント Readmeがあるだけだが、機能が小さい上に、基本的にはXmlReaderと同じAPIを提供するだけなので、これで十分使える。 書きかけの(?)ドキュメントが10ページほどあるが、AngleSharpは巨大なライブラリー (30個以上のパッケージに分かれていて、パブリックな型だけで400以上ある) なので全然足りない。ソースにはdocumentation commentが書いてあるが、当たり前のことを機械的に書いた印象が強く、Intellisensも構文以上のことはほとんど教えてくれない。なので、使おうと思ったら、ソースを調べるか、ウェブを検索しまくるしかない。
開発チームの誰かが本を書いて売る、みたいな話もあるようだが、今のところ実現していないようだ。

AngleSharpの方がずっといいよね、一見して明らか、みたいな表になる予定だったのに、そうなってない。おかしいな…。

入力のエンコーディング

これはスクレイピングにも関係するので分かっている人が多いと思うが、SgmlReaderの入力はTextReaderか文字列かの二択。ファイルやネットワークから入手したバイト列であるStreamを直接扱うことはできない。つまり、エンコーディングは、SgmlReaderを使う以前に、アプリ側で判定してStreamReaderなりを呼び出す際に指定する必要がある。これは、一般的なSGMLを処理するのであれば、こうならざるを得ない。

ところが、実際のHTMLでは、エンコーディングはHTML文書中にmetaタグを使って書いてある。HTMLをパースした後でなければエンコーデイングが分からない。スクレイピングであれば、HTTP応答を見ることも可能だが、ローカルファイルを読むときにはContent-Typeとかcharsetとかを教えてもらうことはできない。また、特定サイトをスクレイピングするのであれば、あらかじめ使われているエンコーディングを調べてハードコードしてもいいし、2024年時点ではHTMLはUTF-8で作るのが常識だからUTF-8決め打ちで問題ないという考え方もあるだろう。でも、HTMLを扱うローカルツールとしては、UTF-8専用は気持ちが悪い。

SgmlReaderとは違い、AngleSharpは、入力をStreamで渡せば、metaに書いてあるエンコーデイングに従ってよろしく処理してくれる。素晴らしい。

ただし、AngleSharpでも出力はTextWriterなので、アプリ側でエンコーディングを指定してStreamWriterなどを用意しておく必要がある。書き出すときには解析済みのHTMLがあるので、metaを参照するのは簡単だが手間ではある。この手間をはぶくと、.NETのStreamWriterはデフォルトでUTF-8なので、元のHTMLがUTF-8以外のcharsetを使っているとおかしなことになってしまうので注意が必要。

出力のシリアライズ

SgmlReaderを使う場合、更新したHTMLを書き出すのは難しい。(SgmlReaderという名前なので、この点を責めるのはどうかとも思うが。)

SgmlReaderには対になるSgmlWriterのようなものは存在しない。なので、SgmlReaderで読んだHTMLを普通に書き出そうと思うと、XElement.Saveを使ったり、XElement.ToStringしてからFile.WriteAllTextを使ったりすることになると思うが、これは内部的に、XmlWriterというXMLをシリアライズする機能が使われるので、正しいHTMLにならない (*1)。

<img src="...">」が「<img src="..." />」になるのはxhtmlでもそうなので許してもらえることが多いと思うが、空のscript要素、つまり「<script src="..."></script>」が「<script src="..." />」になってしまうのは非常に困る。

というわけで、書き出したい場合は、SgmlReaderは適さない。

AngleSharpは、もともとHTML用で、自分自身の出力機能を備えているので、問題なく書き出せる。

更新方法と書き出し方

  • ドキュメントの更新は、要素に関しては、いわゆる普通のDOMのAPIがそろっており、clone、add、append、remove、replaceといったメソッドで操作できる。拡張メソッドだがInsertAfterとかInsertBeforeなどもある。
  • 新しい要素の作成は、IDocumentのCreateElementを使う。(IDocumentは、IHtmlDocumentの親インターフェースの一つ。)
  • ただし、要素をいくつも作って組み立てるのは面倒なので、パターンが決まっているなら、IElementのInnerHtmlプロパティを書き換えるのが簡単。これはstring型で、JavaScriptのInnerHTMLと同じように機能する。
  • 既存の要素の属性値を書き換えるのは、対応するプロパティに値をセットするだけでいい。
  • 属性自体を削除したい場合は、名前を指定してIElement.RemoveAttribute(string)を呼ぶ。

更新が終わって書き出すときは、

  • IHtmlDocument html のときに、html.ToHtml() とするとHTML文書全体が一つの文字列になる。
  • また、TextWriter writer のときに、html.ToHtml(writer) とすると、ファイル等に書き出せる。

*1 実は、XmlWriterのインスタンスを作るときに使うXmlReaderSettingsというクラスにはXmlOutputMethodというプロパティがあり、値としてXmlOutputMethod.Htmlを取ることができる。マイクロソフトによる、このプロパティの説明には、こう書いてある:

出力は、HTMLの規則やXML 1.0の規則などによってシリアライズできます。
この設定は、XSLTプロセッサが設定したり、Visual Studioが内部的に使用したりします。

なるほど、これはXSLTの <xsl:output method="html" ... /> を実現するためのものなのね、これでいいじゃん、と思って、プロパティを設定しようとすると、このプロパティは読み取り専用 (getのみでsetがない) ということに気づいて驚く。実際には、セッターが存在しないのではなくて、internal なだけなので、リフレクションを使えば好きな値を設定できる。そうやってXmlWriter.Createで取得したインスタンスは、正しいHTMLを作ることができる。

できるのだが、これはかなり「ウラワザ」的なので、お勧めできない。どうしてもやりたければ、リフレクションに頼るのではなく、XslTransformを使った方がいいように思う。大げさになってしまうが、正式な公開APIだけでHTML出力を実現できる。(XSLTプロセッサが作ったHTML出力のXmlWriterが動くわけだ。たぶん。)

2024年8月13日 (火)

エクセルの「区切り位置」という機能

マイクロソフトのエクセルには「区切り位置」という機能がある。いわゆるCSVのように、項目をコンマとかタブとかで区切って並べたテキストファイルの各行がまとめて一つのセルに入ってしまっているものを、項目ごとにバラして複数の列に入れ直す機能だ。(この機能についてちゃんと知りたい人はネットで検索すれば、解説記事が大量に見つかる。) 

Text_to_columns-ja

これはかなり昔からある機能で、便利なので私もときどき使うのだが、「区切り位置」という名前が直観的でなくて覚えられず、使うたびにメニュー (リボン) のどれだったか分からなくて毎回苦労する。この機能を使うときには「区切り位置指定ウィザード」というダイアログが開いて、どうやって各項目を切り分けるのかを選ぶようになっている。おそらく、それが「区切り位置」という名前の理由なのだろうと思ってはいた。この命名センスはどうなのかともずっと思っていた。(そんなことを考えているのに「区切り位置」という名前が覚えられないのもちょっとアレだが。)

ところで、Google Spreadsheetにも同じ機能があるのだが、そちらは「テキストを列に分割」という名前になっている。こっちの方がずっと分かりやすいし、機能の存在を知らない人がたまたまメニューで見かけても、何をやる機能か予想がつくんじゃないかと思う。(「区切り位置」の機能は、名前か想像するのは難しいだろう。)

それで、私は「マイクロソフトの (またはエクセルの) 開発チームの命名センスは変わっているのだろうな」と思っていた。ずっと。でも、そうじゃなかった

今朝気づいたのだが、エクセルの英語版では、この機能は「Text to Columns」という名前だったのだ。つまり「テキストを列に」だ。分かりやすい。

Text_to_columns-en

つまり、命名センスがおかしいのは、エクセルの開発チームじゃなくて、エクセルのUIを日本語に訳した人だったのだ。ってゆーか。英語の「Text to Columns」という言葉を見て、それをそのまま翻訳したら、「区切り位置」にはならないよね。絶対に。だからこれは「単純に『テキストを列に』なんて訳しても、日本語圏の人には意味が分からないだろう。言葉を訳すんじゃなくて、内容が伝わるように分かりやすく言い直そう。」と考えた上での訳としか思えない。思えないのだが… これって分かりやすくなっているどころか、意味不明になってますよねえ。

いったいどうしてこういうことに…。

2024年7月22日 (月)

日本語Windowsのdotnetコマンドの出力を英語にする方法

.NET SDKの「dotnet」コマンドをWindowsにインストールすると、メッセージは「OSの言語」で表示される。つまり日本語Windowsだと日本語メッセージになってしまう。日本語話者なのでちゃんとした日本語メッセージならうれしいが、誤訳ばかりで意味不明なメッセージはいやだ。

そういう場合は DOTNET_CLI_UI_LANGUAGE という環境変数を en に設定すれば英語メッセージになる。fr ならフランス語、de ならドイツ語。好きな言葉を選べばOK。どれも日本語よりは大分まともらしい。(英語以外は私には評価できませんが。)

ただの環境変数なので、どうやって設定してもいいのだが、お勧めはアカウントに設定してしまうこと。こうすればcmd.exeでもPowerShellでも、あるいはvscodeが直接スポーンするような場合も効く。

[設定] > [システム] > [バージョン情報] > [システムの詳細設定] > [環境変数] から設定できる。

Dotnet_cli_ui_language
実行例はこんな感じ。
Dotnet

2024年7月19日 (金)

Snapdragon Dev Kit for Windows を購入してしまった

勤務先をクビになったこともあり、Snapdragon Dev Kit for Windows というものをポチってしまった。Snapdragon X Elite を搭載したミニPCで、Windows+PCをターゲットとした開発作業に最適ということになっている。Windows Dev Kit 2023の「AI対応版」という説明を見かけるが、Windows Dev Kit 2023はマイクロソフト製だったのに対して、こちらはQualcom製だ。(どちらの会社もPCの組み立て工場を持っているわけではないと思うので「XX製」というのは責任の所在という程度の意味だと思うが。)

送料込みで通常価格$899のところ、10%OFFクーポンをもらったので$809.10だった。クレカの請求額は¥127,045になるらしい。割高感があるが、円安なのでこんなものかな。

アメリカから発送し5日程度で届くとのこと。ちゃんと来るだろうか。


7月23日追記

いよいよ届くかなと思ってOrder Historyを確認したら、Est. Delivery (お届け予定日) が8月16日に書き換わっていました。なんだ、それ。悲しい。


8月1日追記

住所に使用できない文字が含まれているので修正せよ、みたいなメールが来た。それでウェブサイトにアクセスしたら、またもお届け予定日が変わっていて、今度は9月5日になっていた。どんどん遅くなっているが、それどころか、確認した日からお届け予定日までの日数も増え続けている。5日後 → 23日後 → 35日後。予定日変更に関する連絡や説明などは一切なし。不愉快だなあ。

とりあえず住所は修正したが、もうキャンセルしちゃうかなあ…。


8月10日追記

先週「もうキャンセルしちゃうかなあ」と書いたが、実際はそのまま放置してあった。しかし、ハローワークで面白くないことがあったので、半ば八つ当たりで発注をキャンセルする気になってArrow Electronicsにアクセスした。

すると、なんと、またまたいつの間にかお届け予定日が変わっていたのだが、今回は初の前倒しで、8月16日予定になっていた。つまり1週間後だ。7月23日の状況に戻ったとも言える。

1週間なら待ってもいいなあ、などと、また気が変わり、オーダーはキープ。さて、今度こそ無事に届くのでしょうか。


8月16日追記

届きませんでした。本日のお届け予定日は8月20日とのこと。

しかし、いったい何なんでしょうね、この予定日が頻繁に変わる販売システムって? 何らかの理由で計画通り生産できていない? 生産は計画通りなのだが、お得意様や大口注文が入るとそっち優先で出荷してしまい私のような重要でない顧客の分は後回しになる? そもそも生産計画と無関係に適当にお届け予定日を決めている?

8月16日追記2

ebayに出品している人がいる。https://www.ebay.com/itm/305712232803
新品未使用で2個あるとのこと。(まとめ売りじゃなくて1個ずつの販売。)

価格は、なんと$2,499.00。標準価格の約3倍。いわゆる転売ヤーさんなんですかね。そうだとしても、どうやって入手したのかは気になる。「これは絶対品薄になる」と予測して、販売開始から秒で何台も発注した感じですかね?

※ 関係ないけど、ebayは同じものを複数販売する場合「×個あります」という形で出品できる。上の出品もその仕組みを使って2個販売している。逆に、同じ人が全く同じ商品を多数出品することは禁止されているらしい。メルカリもそうすればいいのに。


8月18日追記

今見たら、上に書いたebayの出品は残り1台になっていました。つまり、1台売れたってことですかね。そういう意味では、元々もっとたくさんあったのが、16日には残り2台になっていたという可能性もあるわけで。

PS5のような一般消費者向けの商品でなくても、転売ビジネスは成立するということなのでしょうか。

まあでも、検索してもSnapdragon Dev Kit for Windowsを売りに出しているのはこのebayの出品者しか見つからないので、「転売ヤーたちが買い占めてるから一般人が購入できない」わけではなさそう。


8月20日追記

お届け予定日は8月20日から変わっていないが、order statusも「pending」のまま変わっていない。これは1か月以上前に注文した直後からずっと同じ。pendingは解釈が難しいが、まだ出荷されていないのは間違いないのだろう。


8月23日追記

実は20日の追記を書いた後で、カスタマーサポートに問い合わせた。

ウェブでContact Supportというページを見ると、アメリカとイギリスと中国の電話番号が記載されているが、これはパス。よくあるウェブ問い合わせフォームもあったので、そこから「estimated delivery dateを過ぎていますがどうなっているのですか?」みたいなことを書いて送信。その後24時間待ったが返事がない。

それで、あまり気が進まなかったが「テキストチャットサポート」を試してみた。最近のチャットサポートはたいていAIが返事をするのだが、Arrowもそうで、意味のある回答が得られない。たいてい、しばらくチャットを続けているとAIがあきらめて人間を出してくれるので、それまで付き合う必要がある (これがイヤなのだ、私は)。で、ついに「それでは人間のオペレーターに交代します」みたいになって人間 (と思われる) サポート要員が出てきた。「予定日を過ぎても出荷されていないようなのだがオーダーが今どういう状況なのか知りたい」みたいなことを言うと「状況を確認しますのでしばらくお待ちください」みたいなことを言われた。これは普通だ。しかし、そのまま無言。しばらく (1分くらい?) 待っても無言のままなので「Hello?」とか「Are you still there?」とか何度か入力してみるが全く返事がない。その後5分ほど無言が続いたので「じゃあ、返事はメールで送ってください」みたいなことを書いてセッション終了。それが21日。

で、翌22日も音沙汰無だったが、今日23日にメールが来た。「Your order is currently processing, and we're doing everything we can to get it delivered to you right on time.」だと。「注文は現在処理中です。予定通りに届けることができるよう全力を尽くしています。」みたいな感じか? まあ定型文なのだろうが。「いや、だから、もう予定を過ぎてるから問い合わせたんだけど。そもそも発注したときの予定から1か月過ぎてるんだけど。」と思ってウェブのOrder Statusを確認したところ、予想通りというか何というか、またお届け予定日が書き換わっていて、今度は9月20日になっていた。


9月2日追記

もう待てないという気持ちになったことと、他に欲しいものができてしまったことから、今度こそ (8月10日の追記参照) Snapdragon Dev Kit for Windowsはキャンセルすることにした。

Arrow Electronicsの通販サイトでキャンセルボタンを探すが見つからない。FAQを探したら「商品によってキャンセル方法が違うので、チャットで問い合わせろ」みたいに書いてある。そこでAIチャットから問い合わせる。が、一向にキャンセル方法を教えてくれない。最初はいろいろと長く書いていたのだが「何を言っているのか分からりません。別の言い方を試してください。」みたいなことを言われる。ひょっとしてキャンセル要求が来ると分からないフリをするように訓練されたAIなのかとも思ったが、何回か表現を変えて繰り返すが変わらず。最後に「I want to cancel my order!」と入れたら (最後のビックリマークが効いたのか?) ついに「人間のオペレーターに交代します」になったが、十数秒後に「現在対応できるオペレーターがいません。後ほどメールで連絡します。」となって終わった。

で、また待たされるかと思ったら、今度は数時間でメールが来て「注文をキャンセルしたいのですね。喜んでお手伝いします。」みたいに書いて来た。それで「すでにこの注文はキャンセルできました。」(the order has been successfully canceled) と書いてあったので、キャンセルは対応が早いなと思ってウエブサイトを確認したところ、キャンセルされておらず、相変わらずstatusがPendingで、お届け予定日も9月20日と表示されるままになっていた。

むむむ。


9月5日追記

キャンセルできたかどうか不安だと思っていたところ、昨夜 (4日) 「Delivery update (配送状況のお知らせ)」というメールが来た。「お客様のご注文は9月後半に必ずお届けします」みたいに書いてある。キャンセルできていないのかと驚きウェブサイトを確認したところ、statusがCancelled (キャンセル済み) になり、金額も$0.00になっていた。なぜメールが来たのか分からないが、注文は無事にキャンセルできているように見える。

メールには「仕様変更のお知らせ」も含まれていて「Your device will now ship with a USB-C to HDMI dongle, in lieu of an embedded HDMI port.」と書いてある。「内蔵HDMIポートの代わりに、USB-CからHDMIへの変換器を添付します」という感じか。つまり、「HDMIポートは削除になった。代わりに変換器を付けるから許してね」ということだろう。確かに製品仕様も書き換わっている。

Changes_20240905092401
今の製品仕様: Snapdragon-Dev-Kit-for-Windows-Product-Brief-original.pdf
注文したときの製品仕様: Wayback Machine (archive.org)

よく見ると価格も変わっていて (値下げ)、私が注文したときには$899.00を10%オフのクーポンで$809.10になったのだが、今はだれでも (クーポンなしでも) $809.10のようだ。ちなみに販売サイトの在庫状況は「在庫なし、入荷予定: 13週間後」のようだ。

なんか、もう、いろいろグダグダですね。

より以前の記事一覧

フォト
無料ブログはココログ