UWSCでタスクトレイアイコンを表示する (COM版)

お仕事で使ってるツールで常駐型のがあるんですけどね
タスクトレイアイコンが出せるといろいろ便利だろうなーてことで

UWSCでタスクトレイ常駐する – じゅんじゅんのきまぐれ

を使ってアイコン出してたんですね
不自由なく使えててゴキゲンだったんですけどある日事件が起こる
F-SecureのアンチウイルスソフトにUWSCから呼んだPowerShellが…

ブロックされてしまった!

例外登録とかもできずどうしようもなかったのだ…
ぼくは悲しみに暮れた

のでCOMで使えるやつをつくった
createoleobj() できるやつだ!
C#で書きました

サンプルコードは一番下にあるよ

どういうのか

任意のアイコンを表示させられます
oleevent() でアイコンをクリックしたときのイベントを処理できます
アイコンは途中で変更できます

大変だったこと

C#ほとんど書かないのでまず書き方を忘れていたよね
COM用のDLLはむかーしちょっとしたの書いたことがあったので
それを掘り起こしつつ地味に書き進めました…が

動かない!想定どおりに動かない!
とくにイベント周り!

公開するインタフェースの各メンバに DispId 書いてなかったんですよね最初
その状態でもプロパティにアクセスしたりメソッド叩いたりはできたので油断したよね
イベント発火するとイベントハンドラが未定義だ!って怒られるわけよ
oleevent() は成功してるのに!
(ちなみにこの状態でもPowerShellから呼ぶと成功するので混乱した)

んで、そこを乗り越えたら簡単なイベントはちゃんと扱えるようになりました
ヨカッタネ☆ …て思うじゃん?
今度はもっと深みにはまった…
アイコンをクリックした時のイベントハンドラからデリゲートを呼ぶようにしてたのさ
(そのデリゲートが公開してるイベントなわけね)
するとどうだ、イベント発火時にUWSCがクラッシュするではないか
つらい

これが全然原因わからなくって…
いやなんかうすうすSTAとかそういうのじゃないかなとか考えてはいたんですけど
そうだとしても実装方法がさっぱりわかんなかったのだ…
ぐぐっても出てこないというかどうやってぐぐればいいかもわかんなかった系でね
RegAsmすると ThreadingModelBoth になってるし…
なにこれ Apartment に書き換えればいいの…?
関係ねぇよ!! (関係なかった

つらい

まぁでも解決しました
結論を言うとイベントハンドラを追加してたメソッドに
[STAThread]
付けただけなんですけどね

いやだってさーこれさーexe書くときにエントリポイントにつけるもんです!
って解説されてるわけでさー…じゃあDLLのときはどうすんのとかわかんないわけよ!
ダメ元で書いたけど当初他の理由でうまくいかなかったりしててね…
しばらくこれが正解だって気付かなかったんだよね

まぁなんかそういうことしながらなんとかやりました
ほめて

使う時の心得

RegAsmしなきゃなので管理者特権が必要です
スクリプトから登録もしたいという場合は注意してね

RegAsmしなくて使う方法もあるんだけどそれはそれでいろいろめんどくさい
reg free com とかでぐぐると出てくるよ

サンプルコード

エラーハンドリング全くしてないのでなんかしくじると落ちます

広告
カテゴリー: UWSC

PowerShellのPackageManagementでChocolateyGetを使う

Linuxユーザの方には馴染み深いであろうパッケージ管理ですが、Windowsにも結構前からChocolateyというのがあってまぁこれが便利なわけですよ
ただしPowerShellユーザにとっては choco コマンドを叩くとかわりと苦痛でしかないわけで
でも大丈夫、PackageManagementがChocolateyを内包してくれるんだ

続きを読む

UWSC5.3.0出てましたね

変更点
http://www3.rocketbbs.com/13/bbs.cgi?id=umiumi&mode=pickup&no=3740

今回はSublime Text用のUWSCパッケージに手を入れる必要がなくてヨカッタネ

いやー、正直やりたくねーめんどくせーとか思ったのでありがたい
…やりたくねーめんどくせーと思ってしまった

Visual Studio Code向けUWSC拡張も結局完成させずに放置してたら完全にやる気を失ってしまった
(ちなみにそれはVSCode正式版が出る前に着手したものなんで当時と仕様変わっててちゃんとうごかねーんじゃねーかなってことでなかったことにしました、今)

あんなに好きだったUWSCに対してでもモチベートできない
UWSCに限らないんだが、まぁ

カテゴリー: UWSC

#一ヶ月COMPだけ生活 を終えて

こういうのをやりました

一ヶ月間COMPだけ食べるというのをやります(やりました) | たっぷす庵

なんだかんだでやりきってしまいました

そもそもなんでこんなこと始めたか

これ がね、ずっと気になってたわけですよ
COMPを知る前はずっとソイレントが気になってたのでいろんな記事見てて、その中の一つだったわけですがまぁインパクトあるよね
このおっさんの様子がどんどんおかしくなっていくんですもの

で、ソイレントは入手が難しかったけどCOMPが出てきた
常用するようになって、ふと思いたったわけです

僕もあれやろう、一ヶ月のやつ!


あのオッサンみたいになるのかなー、ワクワクだなーとそれを思いついた10月半ばくらいにぽわぽわしてました

実際どうだったか

精神に異常どころかとくになにもありませんでした
件のおっさんと違って僕の場合はすでにCOMPを半年近く常食しており、COMPの摂取に抵抗がなかった、というかCOMPのない生活が考えられないという程度にはCOMPを受け入れていたのが大きいんじゃないかという気がします
初めてCOMP買っていきなり今後はCOMPしか食わないぜふっふー!とかやると危険なのかもしれんね

身体への影響は?

あんまないと言えば、ない

体調面

もともと悪いんですが悪いのがそのまま維持されてました
COMPの影響は特になかった

便

💩ね
これは変化ありましたよ、ええ
一週間経過したくらいで便がなんだかだいぶ硬くなってまいりましてね
おかげで腸が耐えきれなかったのか出血しました
出血は10日くらい続いた、最長記録だ

その後は寒い日が続いたりしておなかの調子がわるくなったので緩めだったけど
うん、おなかの丈夫な人ならずっとカッチカチなんじゃなかろうか

それと、その硬かった期間は排便もスムーズでした
COMPだけ食べてれば便秘しないんじゃないかな
そんであれです、量はとても減ります、あんまり出ない

あとあれだ、色はCOMP色になる

あご

弱ってた!
めっちゃ弱ってた!
久しぶりに噛んで食べたら痛いし疲れるんですよ!
びっくりしたね
痛いのは2日くらい続きました

COMPだけで生活するならいざという時のために日々エアガム噛むなどなにか対策が必要

ふつーの食事の代替となりえるのかしら?

うん、なってたんじゃないかな

普段から活動というほど活動してないからというのはあるんですけど、生活するのに必要なものはちゃんと補充されてた感じ

その後のあれ

#一ヶ月COMPだけ生活 に #その後 というのを加えてつぶやいたのを拾っておく

あごがつれぇ

ある意味主食だったもの

ちょっとこの日味覚変だったんだよね
今はあれです、味のする食べ物おいしいです!

なにか食べる度にダメージ

油いいよね…

意外と平気で、その後も平気なままでした

二日目はまだダメージがある

肉食いに行こうぜ!と誘われたので奢らせってもらった
ちょっとお高いステーキおいちい!

このあたりであまり痛みが気にならなくなる

緊急来日しためんたろ社長によりCOMP祭り?が開かれると見せかけてHoloLens体験会が始まったのであった
COMPも試飲させたので一応祭りの体裁は守られたかに見えた
しかし

UWSCのFormでX-UA-CompatibleがIE=9以上だとoleevent()が使えないのをどうにかする

UWSCのFormでこう、ちょっとしたUIを作りたいときに

<meta http-equiv="X-UA-Compatible" content="IE=edge">

などと書きたいわけですよ、つらいから
だけどそうすると oleevent が使えなくなっちゃうんですね
そんなイベントはねー!みたいなエラーになってしまう
こまる、つらい

じゃあもう自分でやるしかないな!

f = createform("about:blank", "test", TRUE)
f.document.write(html)

while f.visible
    select f.document.parentWindow.value
        case 1,2,3,4
            print f.document.parentWindow.value + " が押されました"
            f.document.parentWindow.value = 0
    selend
    sleep(0.01)
wend

textblock html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<script>
value = 0;
var hoge = function(n)
{
    value = n;
}
</script>
</head>
<body>
    <input type="button" name="1" value="1" onclick="hoge(this.value);">
    <input type="button" name="2" value="2" onclick="hoge(this.value);">
    <input type="button" name="3" value="3" onclick="hoge(this.value);">
    <input type="button" name="4" value="4" onclick="hoge(this.value);">
</body>
</html>
endtextblock

はい

script タグ内で宣言してる

value = 0;

の値をForm内でjs使って書き換えるようにして、それをUWSC側から監視してしまおうというわけです
これは要するに window.value なのでUWSC側からは f.document.parentWindow.value で見える

あとはおなじみFormの visible 監視ループの中でその変数の値を見てそれに応じて処理を行う、というすんぽーよ
毎回その変数を初期化するのを忘れずにね
取りこぼしがあるかもしれないからあんまり激しいのはNGよ!

とまぁこんな感じでごまかしながらやってんだけど oleevent() こうするとできるよーみたいな情報ある人は教えてください…

カテゴリー: UWSC

UWSCで配列リテラルっぽいなにか

UWSCって配列リテラルないじゃないですか
なので配列リテラルっぽい気持ちになれる関数を作る

function Array(arg0 = NoValue, arg1 = NoValue, arg2 = NoValue, arg3 = NoValue, arg4 = NoValue, arg5 = NoValue, arg6 = NoValue, arg7 = NoValue, arg8 = NoValue, arg9 = NoValue, arg10 = NoValue, arg11 = NoValue, arg12 = NoValue, arg13 = NoValue, arg14 = NoValue, arg15 = NoValue, arg16 = NoValue, arg17 = NoValue, arg18 = NoValue, arg19 = NoValue, arg20 = NoValue, arg21 = NoValue, arg22 = NoValue, arg23 = NoValue, arg24 = NoValue, arg25 = NoValue, arg26 = NoValue, arg27 = NoValue, arg28 = NoValue, arg29 = NoValue, arg30 = NoValue, arg31 = NoValue)
    const NoValue = null + null + null
    tmp = safearray(0, 31)
    i = 0
    while TRUE
        value = eval("arg" + i)
        if value = NoValue then
            break
        else
            tmp[i] = value
            i = i + 1
        endif
    wend
    result = slice(tmp, 0, i - 1)
fend

function @(arg0 = NoValue, arg1 = NoValue, arg2 = NoValue, arg3 = NoValue, arg4 = NoValue, arg5 = NoValue, arg6 = NoValue, arg7 = NoValue, arg8 = NoValue, arg9 = NoValue, arg10 = NoValue, arg11 = NoValue, arg12 = NoValue, arg13 = NoValue, arg14 = NoValue, arg15 = NoValue, arg16 = NoValue, arg17 = NoValue, arg18 = NoValue, arg19 = NoValue, arg20 = NoValue, arg21 = NoValue, arg22 = NoValue, arg23 = NoValue, arg24 = NoValue, arg25 = NoValue, arg26 = NoValue, arg27 = NoValue, arg28 = NoValue, arg29 = NoValue, arg30 = NoValue, arg31 = NoValue)
    result = Array(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19, arg20, arg21, arg22, arg23, arg24, arg25, arg26, arg27, arg28, arg29, arg30, arg31)
fend

はい

for item in Array("foo", "bar", "baz")
    print item
next

for item in @(1,3,5,7,9)
    print item
next

こんな感じで使えます
Array() 関数に適当に引数渡せばSafeArrayの要素として返ってくるってすんぽーよ
Array() だと書くのめんどくさいから@() という別名も用意、PowerShell使いだからすごく配列に見える

最大32個の要素を持つ配列が作れます
32なのは slctbox に倣ってるからです、とりあえず使う分には十分でしょう
(可変長引数があればね…こんなことしなくてもいいんだけど…)

const NoValue はそれぞれの引数の初期値として定義しています
おそらく絶対に渡されないであろう値ならなんでも良いんですがとりあえず null を3つ足しました
えるしってるか null は足せる(というか文字列結合してる、lengthは3になるぞ)
関数内で宣言してても const のスコープはグローバルです
なぜそんなことしてるのかと言うと、引数の初期値に変数を渡す場合はその変数がグローバルスコープじゃないとだめだからなんですね
関数内に書いてるのは外に書くと邪魔かなって気がしたからですが特に深い意味はないです

カテゴリー: UWSC