hid.libをリンクしようとしたときにLNK2001エラーになる問題

MUDFでドライバ開発中なのですが、hid.libを使いたくて、sourcesにhid.lib追加、internal.hにHidsdi.hのインクルード記述をしてみたところ、ビルド時にLNK2001エラーが発生。

結局はHidsdi.hがCソースなのでextern "C"{}で囲ってやればOKというお話です。

extern "C"{
#include <Hidsdi.h>
}


Windows 7でファイル所有者と書き込み権限をコマンドプロンプトから操作する

多分Vistaも同じだと思うのだけど、HDDを別のマシンに移した際、アクセスできない・消せないファイルが大量にあったので、それらをまとめてコマンドプロンプトからコマンドで再帰的に処理すべくやったことと注意点のメモ。

Program Files以下のフォルダ・ファイルの所有権を自分のPCの管理者に変更する
takeown /F "Program Files" /R /A

Everyoneに対してフルコントロール権限を与えて、誰でも編集できるようにする
icacls "Program Files" /grant Everyone:(F) /T

注意しないといけないのは、フォルダを辿るときに、NTFSのJUNCTIONも辿ってしまうので、ジャンクションは先に消しておいた方がいいかも。
そうしないとうっかり現行のシステムファイルを消しかねない。
というか実際、現行システムのACL書き換えをやらかした。
まさに「FドライブのUsersフォルダの権限を書き換えていたら、いつのまにかCドライブの権限を書き換えていた…!」という状態。
怖い怖い。

ジャンクションかどうかの確認は、コマンドプロンプトからdir /aとかで。

シンボリックリンクも同じかな。どっちも使われているみたいなので注意。


py2exe+wxPythonでmyole4axが見つからないと言われる問題

新規にPython環境セットアップして、何はともあれ既存のファイルに対してpy2exeをやろうとしてはまったメモ

py2exeでexe化したファイルを実行すると、下記のようなエラーが発生する。Pythonのバージョンは2.5と2.6のどちらでも再現。

  File "zipextimporter.pyo", line 82, in load_module
  File "wx\lib\flashwin.pyo", line 15, in <module>
  File "zipextimporter.pyo", line 82, in load_module
  File "wx\lib\activex.pyo", line 44, in <module>
ImportError: cannot import name myole4ax

myole4axって何ぞ?

ファイル名  C:\Python25\Lib\site-packages\wx-2.8-msw-unicode\wx\lib\activex.py
44行目

from comtypes.gen import myole4ax

C:\Python25\Lib\site-packages\comtypes\comtypesフォルダはあるけど、C:\Python25\Lib\site-packages\comtypes\comtypes\genフォルダがありませんよ…

wx\lib\activex.pyの該当部分の周りを見てみると、

import wx

import ctypes as ct
import ctypes.wintypes as wt
import comtypes
import comtypes.client as cc
import comtypes.hresult as hr

import sys, os
if not hasattr(sys, 'frozen'):
    f = os.path.join(os.path.dirname(__file__), 'myole4ax.tlb')
    cc.GetModule(f)
from comtypes.gen import myole4ax

ということで、cc.GetModule(f)が実行されると、comtypes.genが生成されるってことなんですね。つまりpy2exeでexeにする前に一回実行しておく必要あり。

py2exeでは実行はせずにファイルをパッケージ化しているだけだから、生成されないままパッケージ化されてしまうというわけ。

もしくはこんな風に手で実行してもOK。

>>> import wx
>>>
>>> import ctypes as ct
>>> import ctypes.wintypes as wt
>>> import comtypes
>>> import comtypes.client as cc
>>> import comtypes.hresult as hr
>>>
>>> import sys, os
>>> f = os.path.join(r"C:\Python25\Lib\site-packages\wx-2.8-msw-unicode\wx\lib", 'myole4ax.tlb')
>>> cc.GetModule(f)
# Generating comtypes.gen._99AB80C4_5E19_4FD5_B3CA_5EF62FC3F765_0_1_0
# Generating comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0
# Generating comtypes.gen.stdole
# Generating comtypes.gen.myole4ax
<module 'comtypes.gen.myole4ax' from 'c:\Python25\lib\site-packages\comtypes\gen
\_99AB80C4_5E19_4FD5_B3CA_5EF62FC3F765_0_1_0.py'>
>>> 

comtypes.gen.ShockwaveFlashObjectsも同じようにエラーが出る場合があるので、同じ手段で対処できます。


Chromeでキャッシュ先を変更してパフォーマンスを上げる

最近ハードディスクがアクセスされっぱなしになって、PC全体のパフォーマンスが著しく落ちると言う現象に悩まされていたのですが、どうやらGoogle Chromeが問題だった模様。

起動しっぱなしにしておくと、キャッシュの整理を始めるのか、一回アクセスが始まると数時間止まらないなんてことも。

で、とにかくディスクアクセスがボトルネックなので、メモリ上か、さもなくば別ドライブに展開してほしい。

ということで調べたら、キャッシュ先を別のフォルダに指定する起動オプションがあるようです。

–disk-cache-dir="Z:\cache"

これでRAMディスク上にキャッシュ展開すれば速くなりますね。

詳しい設定方法は "続"Google chromeのキャッシュをRAMディスクに移動させる – consbiol のエコ日記 を参照のこと。

今使ってる通常版のChrome 3.0.195.38でも使えました。

NTFSのジャンクションを使って実現する方法が結構検索に引っ掛かってくるけど、今はこっちの方が圧倒的に楽なのでオススメ。


devcon.exeのログ

Windows 7でのユーザーモードドライバ開発、inxファイルを作ってdevcon.exeでドライバをインストールしようとして、

devcon.exe failed.

と表示された場合は

C:\Windows\inf\setupapi.dev.log

をチェックする。

行頭に!!!が付いている行がエラー。


SafariのkCFErrorDomainCFNetwork error 303.

iPhone用のWebサイトを作っていてSafariで発生した
Operation could not be completed. (kCFErrorDomainCFNetwork error 303.)
というエラー。

ページを読み込む途中で上記のエラーで止まってしまうので悩んでいたのですが、Proxyが問題でした。

というか、サーバがTransfer-Encoding: chunkedで送信してきた場合に、Proxyの挙動が仕様と異なる場合に起こるようです。TCPコネクションの問題かな…?

Transfer-Encoding: chunkedになるのは主にサーバからPHPとかで動的にページ書き出す場合ですね。

サーバ側でContent-Lengthを返すようにするか、Proxyを外すかってところですかね。

Fiddler使う際には注意。


リバースProxy環境でのmixiアプリのOAuth

CakePHPでmixiアプリのOAuthを処理させる方法は以下のサイト参照。ホントにシンプルでわかりやすい解説。

[cakephp] mixiアプリのOAuthのリクエストを受け取る – 「のーぶるじゃすぱー」略して「のぶじゃす」のBLOG

通常の環境ではこのまま実装すればOK。

で、このあとロードバランサーの入ったサーバに持ってきたらOAuthが正しく認証されない。

OAuthRequestのhttp_urlを見てみると、

http://192.168.0.2:8001:80//api/hoge/hoge/…

という悲しいことになっていて、これがどうも問題のようだと。というか、ホスト:ポート:ポートってどういうことだ…

本来ならもちろん、

http://mixiapp.sample.com:80/api/hoge/hoge/…

みたいなアドレスになっていないといけない。

ちなみに送信側はmixiアプリのサンプルそのまんまな感じのJavaScript

var params = {};
params[gadgets.io.RequestParameters.REFRESH_INTERVAL] = 0;
params[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.SIGNED;
params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.TEXT;
var url = "http://mixiapp.sample.com/api/hoge/hoge/";
gadgets.io.makeRequest(url, func, params);

解決策は

function validateOAuth () {

    $get = $_GET;
    unset($get['url']);
    $http_url = 'http://mixiapp.sample.com:80/' . ltrim($_SERVER['REQUEST_URI'],'/');
    $request = OAuthRequest::from_request(null, $http_url, array_merge($get, $_POST));
    if ($_GET['oauth_consumer_key'] == 'mixi.jp') {
        @$signature_valid = $this->MixiAppliOauth->check_signature($request, null, null, $get["oauth_signature"]);
    }

    if ($signature_valid == true || Configure::read('debug')) {

        $this->oauth_valid = true;
        $this->viewer_id   = $get['opensocial_viewer_id'];
        $this->owner_id    = $get['opensocial_owner_id'];

        return $get;

    }

    return false;

}

というように、from_requestの第二引数にURLを指定してやればOK。なぜかスラッシュが2つ付いていたので削って付けなおしてます。


iPhoneのSafariでtouchendイベントを使うときの注意

iPhone用のドラッグアンドドロップで操作できるWebアプリを作っていて、うっかりはまったtouchendの挙動についてのメモ。

最初に書いたコードはこんな感じでした。

function touchhandler(e) {
    var x = e.touches[0].pageX;
    switch (e.type) {
        case 'touchstart':
            break;
        case 'touchmove':
            break;
        case 'touchend':
            break;
    }
}

document.getElementById('sample').addEventListener("touchend", touchhandler, false);

このプログラムではtouchendの処理が実行されません。

というのもまぁ、気づけば簡単なことなんですが、最後の指をスクリーンから離してtouchendのイベントが発生するときは、もうスクリーンに触ってないのでe.touches[0]がundefinedになるんですね…

なので、touchendのときは、引数で受け取ったe.touchesは注意しましょうという話。

今回参考にさせていただいたのは以下のサイト。

flashcast:フリーで働くITエンジニア集団のブログ: ipod touch用のWeb Applicationを作成してみる(canvasでお絵かき編)

SitePen

Web開発参考サイト – iPhone 3G DevWiki


Windows 7でSynergyを使おう


※2012年4月20日追記

Macを含めないなら、Microsoft The Garageで公開されているMouse without Bordersがかなり便利です。
Microsoft download from The Garage: Mouse without Borders – Next at Microsoft – Site Home – TechNet Blogs

一番下にあるDownload Nowからダウンロードできます。

特に設定らしい設定も不要で、双方向にマウス・キーボード操作ができ(Synergyは片方向)、UAC上でも問題なく操作できます。Synergyのようにホストとクライアントの区別もありません。

あと、そんなに使う用事があるのかはわかりませんが、すべてのマシンで同時に同じ操作をさせることもできます。

おすすめです。

ライセンス版で数週間早く入手したものの、結局パッケージ版が発売されてからインストールしました。Windows 7。

XPの入っていたノートPC(Panasonic Let’snote R5)にWindows 7 Professionalをインストールしたので、とりあえずメインPCから操作できるようにしようと、Synergyをインストールするも…手動で起動すれば動作するものの、自動起動すると動作せず。管理権限で実行してサービスに登録しても動作せず。というか、繋がってはいるみたいなんですけどね。サーバ側のマウスがどこかに行ってしまうので。

で、synergyは2006年に更新が止まって、Vistaも対応していないし、何か後継があるハズ…と思って英語のWikipediaを見たら、synergy-plusというフォークプロジェクトがあったんですね。

Google先生も、「synergy」で検索したら、「もしかして synergy-plus」くらい出してほしいところですが…

32bit版、64bit版もあるので、7から64bitに乗り換えた人も安心ですね。

plusを入れる前に、一度synergyを入れていたので、設定情報を引き継いでくれているようです。といっても必要な設定項目はHost Nameの設定だけですけど。

とりあえずsynergy-plus-1.3.4-Windows-x86-r1.exeをダウンロードしてインストール。今回はクライアント側(操作される側)として使います。

やっぱり色々問題ありました…

  • ログイン画面では入力ができない
  • UACになると操作はできない

あぁ、微妙…というか、大して改善されてないですね…

自動ログインにしてWindows7のUACも無効にしてしまえばいいのかなぁ…複数ユーザ使いたい場合はどうしようもないしなぁ…

Vistaでの対策は以下のページ参照。

Fixing Problems with Synergy on Windows Vista :: the How-To Geek

Windows 7でUACを無効にするには以下のサイト参考。

Disable User Account Control(UAC) For Administrators Only :: the How-To Geek

ざっくり日本語版での対応を説明すると、

スタートメニューの検索からsecpol.mscと入力して実行。ローカルポリシーのセキュリティオプションから、「ユーザー アカウント制御: 管理者承認モードでの管理者に対する昇格時のプロンプトの動作」をダブルクリックして、「確認を要求しないで昇格する」を選択。

らしいですよ?試してないですが。

結論としては、今後に期待…

2011年3月20日追記

すっかり追ってなかったのですが、synergy-plusは本家synergyとマージして開発がバリバリ進んでいるようですね。

http://synergy-foss.org/

今は安定版の1.3系列と、ベータ版の1.4系列、ゼロから(from scratch)書きなおす2.0系列があるようです。それぞれの機能やサポート状況は別の機会に調べてエントリーします。

ロードマップ – Synergy


Pythonのwin32comからSilverlightを使おうと試みる

最終的にはPythonで書かれたWindowsアプリケーションで、Silverlightのコンテンツをロードしたいという目的なのですが、とりあえずSilverlightのActiveXコントロールを読み込んで動作を確認してみたいので色々実験。

まず、インストールされているSilverlightのバージョンを調べてみる。

Javascriptで書かれたコードがいくつか見つかったのでそれを書き直す。

以下はJS版。

var control = new ActiveXObject('AgControl.AgControl');
alert(control.IsVersionSupported('3.0'));

これをPythonで書いてみる。

import win32com.client
control = win32com.client.Dispatch("AgControl.AgControl")
print control.IsVersionSupported('3.0')

Silverlight 3がインストールされていればTrueが表示されます。

他にどんなメソッドが定義されているのかを調べるために、Visual StudioからAgControlを参照して、オブジェクトブラウザで調査。

というか、Silverlightのプラグインのリファレンスがあった。

Silverlight プラグインのオブジェクト リファレンス

が…Sourceを指定してもIsLoadedプロパティがTrueにならない…うーん…もう少し調べてみる。