So-net無料ブログ作成
検索選択
ソフト開発 ブログトップ
前の10件 | -

zlibの研究結果 [ソフト開発]

zip圧縮・解凍のフリーソフトであるzlibについていろいろと調べた結果。最新版の1.2.11を使ってzlibwapi.dllを作ることはできたが、それを実際に使ってみるとまともに動かなかった。圧縮はRelease版でzipができず、解凍はバッファーサイズを256にすることでうまくいったがデフォルトの8196だとエラーになった。

WinImage社が公開していた1.2.5のzlibwapi.dllを使っていて何の問題もなかったのだが、現時点でWinImage社には1.2.5がアップされておらず1.2.3になっている。それがなぜなのかはわからない。だったら、zlib公式サイトの提供物をもとにして、最新版の1.2.11用zlibwapi.dllを作ってみたくなったのだ。

だれか1.2.11ベースでWindowsでちゃんと動くzlibwapi.dllの作り方を教えてくれないかなぁ。ネット上の日本語サイトは一通り見て試してダメだったのであきらめた。またいつか思い出したときにトライすることにして、いったんこの件は忘れよう。WinImage社の1.2.5ベースのzlibwapi.dllを使い続ければ済むことだから。

TEMPフォルダ書き込みエラーが頻発したのはなぜだろう [ソフト開発]

「環境変数TEMPトラブルについて振り返る」という記事に書いた出来事は1か月ほど前に起きたことでありWindows Serverでもあったから、レアな事象としてとらえていたが、一昨日の金曜日に起きたことはそんな局所的な問題とは違う広い範囲の問題ではないかと思っているのだけれども。。

アプリで保存しようとしたら、エラーでC:\Users\[User Name]\AppData\Local\Tempへの書き込みに失敗って出たんだけどどうしたらいいかって問い合わせが、合計4件来たのだ。たまにある問い合わせではあるものの、それが4件同じ日に来るのはおかしい。エクスプローラで%TEMP%と打ち込んで、中のファイルを全部消せばよい。安全側で考えるなら、Cドライブのプロパティでディスククリーンアップして一時ファイルを消せばよい。最近1週間に作ったフォルダ・ファイル以外を全部削除してくれる。

GetTempFileNameで0バイトのファイルを大量に作って消さないアプリがいるのだろうか。OS自体、IE、Office、ウイルス対策送付となんかの誰もが使っているやつだったりしたら、多くのユーザーに影響が出る。GetTempFileNameは最大65535個の名前が作れるので、その数近くになってくるとエラーになる。まさか自分ところのアプリがそんなアホなことをしているのだろうかと怪しんだが、けっこう昔のバージョンでも発生していたから他要因だと思う。フォルダ内のファイルの制限ってのもあるようだが、それはFATの話であって今時のNTFSフォーマットなら上限はないらしい。

ネットで類似の問題が出ていないか調査しても、たまにある話としての記事がある程度。うーむ、何かどこかに元凶となるものがあるんじゃないかと思っているのだが。例えば、ウイルスとか。。ともあれ、情報がないんだからしょうがない。静観しているしかない。

環境変数TEMPトラブルについて振り返る [ソフト開発]

プログラムから環境変数TEMPで指定されたフォルダにファイルが作れないことがわかった時点で、この問題は解決したも同じだった。TEMPの値を「%USERPROFILE%\AppData\Local\Temp」から「C:\Temp」に変更して万事解決としたが。。変更前で指定していたTempフォルダに対してなぜファイルが作れなかったか?そこを深掘りして原因追及すべし!と言い出す人間が出てこないかと今ひやひやしているところだ。

この問題長引いたのは、関わる組織が多かったことだ。アプリAがあり、そこに組み込む部品Bをおいらが作っている。部品Bには、アメリカ製のライブラリCを使っており、ライブラリCはライブラリDを使っている。Tempフォルダに作業ファイルを作っていたはライブラリDだった。別にDが悪いってわけではなくて、その事実を突き止められたのが重要なこと。初期調査の段階で、ライブラリの関数の戻り値は正常値だったので原因がさっぱりわからなかったところ、ふとしたことでコマンドプロンプトにメッセージが出ていることが判明。Error Creating Imageだったかな。標準出力にメッセージを出すprintf的な処理がライブラリCに入っていたので。おいらがCの人に報告してCの人がDの人に聞いて、その原因がTEMPフォルダにファイルが書き込めないがことが判明。Cの人はアメリカ人なので、やりとりは英語。幸いなことにAの担当者が英語が得意な人間だったので、アドバイスもらいながら、なんとかコミュニケーションがとれた。解決したぜっておいらがCの人に連絡して戻ってきた「I am Happy !」が印象に残っている。

問題の発生した状況について。エクスプローラからの操作でフォルダ参照はできるし、新規でテキストファイルを作れて編集だってできた。フォルダのプロパティからセキュリティタブを見ると、administratorsやadministrator(ログインユーザー)にフルコントロールの権限が付与されていて、拒否設定は存在せず、別になんの問題もないように見えた。ところが、プログラムからファイルを作ろうとすると失敗する。GetTempPathで取得したフォルダにCFileでファイルを書き込むシンプルなプログラムで現象が発生した。
新しいユーザーを作ったところこの問題は発生しなかった。環境変数TEMPはユーザーごとに異なるからだ。不思議なのは、その後元のユーザーであるadministratorでログインしたら一部の問題が解決したこと。普通にソフトを起動したらTempフォルダへの書き込みができて、Windowsサービス経由でソフトを動かしたら書き込めないなんて変な状況が発生。よくわからんけれども、administratorのTempフォルダが壊れたってことにして、新たにフォルダ作ってTEMPを変えることにした。

なぜTempフォルダが壊れたのかはわからない。壊れたフォルダはそのまま残してあるので、それを分析すればわかるかもしれないが、そこまでしなくてもいいだろう。今冷静になって振り返ってみると、アクセス権回りが壊れたのではないかと予想できる。アドビさんが「フォルダのアクセス権を初期化する」で触れている方法で解決したかもしれない。ようするに所有者を変更するという方法だ。今度同様のトラブルがあったときにはこれを試してみよーっと。

近頃、社内で原因分析という言葉がよく使われている。原因⇒対策⇒類似問題のつぶしこみって。なぜTempフォルダが壊れたかってことだ。そんなことは知らん。。それよりも、問題を解消するために考えて、行動して、実際に問題解消することに意味がある。何が腹立つかって、口を出すだけで行動しない人間が多いことだ。口を出すだけの人間が評価されていることだ。まぁそれもよい。口を出し続けることの苦しさだってあるのだろう。おいらはそこに魅力を感じないので、口を出さず、手を出して満足感を得たい側の人間なのだから。ともかく、Tempフォルダがなぜ壊れたかなんて知らんということだ。

複数ファイルの名前やパスを取得するのに便利なフリーソフト [ソフト開発]

ファイル名の一覧を作りたいときに使えるものはこれだ。
NameToClipboard64
インストーラは付いていないが、以下の簡単な操作でセットアップができる。
1.zipをダウンロード後解凍して適当なフォルダに入れる。
2.Program Filesに1のフォルダを移動
3.フォルダ内のInstall64.cmdを右クリックして管理者として実行

エクスプローラの右クリックメニューに「名前をコピー」が増えているので、ファイルを複数選択して、フルパスまたはファイル名またはカレントファイル名を指定すれば、クリップボードに情報が格納されるってもの。単一ファイルだったとしてもフルパスを使えば、エクスプローラのフォルダ表示部とファイル名で2回コピペしなきゃいけないところを一発操作で可能になる。

会社で長く使っているもので、家でも使いたいと思ってもなかなかその名前を思い出せなくて、検索しても類似なんだけど面倒な操作が必要なものばかりがヒットしていて、今ようやく見つけ出せたのでここに記録して、今後の備忘録としておく。

WinMergeのフィルタ [ソフト開発]

プログラマにとってファイル比較は必須な作業だ。昔DFっていうとてもシンプルなファイル比較を使っていて重宝したもんだが、64bitOSで使えなくて更新もされないものだから世界的に使われているWinMergeを使いだした。ところがこいつがいろいろとよくわからないことがあって、そのうち調べようと思いつつなかなか使いこなせないでいた。直感的にわかるところだけでは幅が広がらないので、少し時間を使って調べてみたのだ。

特定の拡張子を除いて比較するにはどうしたらよいか?
初期状態ではWinMergeのフィルタの入力欄は「*.*」となっていて、あらゆるファイルを比較することになっている。「*.cpp;*.h」と入力すれば、限定した拡張子での比較ができることはわかった。逆に除くにはどうしたらよいかってこと。ファイルフィルタを使うしかなさそう。「選択...」ボタンを押して、既存のフィルタまたは自分で作ったフィルタを選ぶ。そうすると、フィルタ欄に[F]で始まるものがセットされる 。

特定の拡張子というのがVisual Source Safeの管理ファイルならば、既存フィルタの「Exlude Source Control」を選べばよい。そのフィルタ内には以下の記述がある。
f: \.(vs[sp])?scc$ ## Visual SourceSafe files
sccまたはvsssccまたはvspsccで終わるファイルという意味で、正規表現のなかなか難解な表現だ。

また、プログラム言語固有の余計なファイルも除外したい場合がある。C++だったら、Visual C++ looseを選べばよい。VSSのファイルも除きたければフィルタの編集で、Visual C++ looseに対して上記の1行を追加すればよい。フィルタファイルの詳細は以下のサイトが参考になった。
WinMerge のファイルフィルタ

プログラムっておもしろいなぁとつくづく思うなり [ソフト開発]

ここんところぜんぜんプログラムを書いてなくて仕事がつまんなくなってきたところに、トラブル対応があってプログラムをじっくりと書いてみた。いやはやおもしろい。余計な仕事が飛び込んでこない環境で、スピッツ聞きながらプログラムを書きつづったのだ。

一定の成果が出たので今日のところは終了。そうそう、この成果が出るって感じがいいのだ。時間を費やして、あれこれ悩んで、一定の成果が出る。最近そんな仕事をしていない。一定の時間を費やして、前に進まないか後退しているか。。うむ、我ながらひどい話だ。

ということで今日はよく働いたので、この後は酒でも飲んでグタグタしましょうかね!
nice!(4)  コメント(0)  トラックバック(0) 
共通テーマ:日記・雑感

通常使うプリンタを取得する [ソフト開発]

通常使うプリンターを取得する方法をいくつか挙げる。
①GetDefaultPrinter
TCHAR printerName[1024];
DWORD dwBufferSize = 1024;
BOOL bRet = GetDefaultPrinter(printerName, &dwBufferSize);

②CPrintDialog::GetDefaults
CPrintDialog pd(TRUE);
pd.GetDefaults();
DEVNAMES* pDevNames;
if( pDevNames = (DEVNAMES*)GlobalLock( pd.m_pd.hDevNames ) )
{
TCHAR* pbuff = (TCHAR*)pDevNames;
TCHAR* pPrinterName = pbuff+pDevNames->wDeviceOffset
GlobalUnlock( pd.m_pd.hDevNames );
GlobalFree( pd.m_pd.hDevNames );
}

③CWinApp::GetPrinterDeviceDefaults
PRINTDLG prn;
pApp->GetPrinterDeviceDefaults( &prn );
DEVNAMES* pDevNames = (DEVNAMES*)GlobalLock( prn.hDevNames );
{
TCHAR* pbuff = (TCHAR*)pDevNames;
TCHAR* pPrinterName = pbuff+pDevNames->wDeviceOffset
GlobalUnlock( pd.m_pd.hDevNames );
GlobalFree( pd.m_pd.hDevNames );
}

④GetProfileString
TCHAR buffer[1024];
::GetProfileString(_T("windows"), _T("device"), _T(",,,"), buffer, sizeof(buffer));
TCHAR* printerName = wcstok(buffer, L",");

①~③は今現在通用するちゃんとした方法だ。
④はかなりあやしい方法。
win.iniのwindowsセクションのdeviceから情報を取得するなんて書いてあったけれども、win.iniなんてWindows 10環境においては、ほとんど何にも書いていなかった。それでも実際に動かしたら、以下のような情報が取得できたのだった。
EPSON LP-S300,winspool,Ne04:
ドキュメントを読む限り、Win9x時代の遺物感があるが、互換性のために残された使える方法なのかもしれない。①から③の方法が使えない場合には使ってみよう。しかし、いつか使えなくなるかもしれないというリスクを負わなければならないだろう。

デバイスコンテキスト [ソフト開発]

デバイスコンテキストとは何かを調べてみた。
Device Context=装置の状況。直訳すると意味わからん。状況という言葉があいまいで、背景・場面・状況・文脈という意味があるが、やっぱわからないことに変わらない。
絵を描くためのキャンパスと筆というのが正解で、そのキャンパスに図形・文字・画像を書くってわけだ。デバイスコンテキストって長ったらしいので以下dcと呼ぶ。C++のプログラミングにおいて、画面描画に関わる要素である。

VCのダイアログベースアプリを作ったならば、OnPaint()でこうすればdcが取得できる。
CClientDC cdc(this);
他に以下のような関数でdcを取得することができるのだが、この先はよくわからんので、話を変えることにしよう。
CreateCompatibleDC、CreateDC、GetDC

dcって略す言葉がたくさんあるので、いろいろと書いてみよう。
【ドメイン・コントローラー】
アクティブディレクトリというネットワーク環境において、ユーザー情報などを管理するためのコンピュータ(サーバー)。クライアントから見たなら、ワークグループじゃなくてドメイン参加する場合のこと。大企業でWindowsのネットワークを組むなら必要。いろいろと面倒なことが多いという印象があるので、アプリ側からみると、いやーな存在だ。
【ドキュメント・クラウド】
Adobe Readerの現バージョンの名前でDCと呼ばれている。それまで10とか11とかバージョンを付けていたところ、2015年4月にDCというバージョンを出した。きっとバージョン管理するのが面倒になったのだろう。DCのバージョン2015.020.20039みたいな管理をしているから、逆に面倒になっているのかもしれない。Windows 8以降ではPDFを参照するためのリーダーという名前のストアアプリが出ていて、PDFはISO標準となったこともあり、Adobe社だけのものではなくなっているか。
【ダイヤモンド・クレジット】
クレジットカードの名前でDCカードのこと。持ったことないからあまり身近なものではない。中井貴一、カッパ、たぬきが躍るCMをやっていたのはずいぶん昔のことだから、今時の若い人間にはわからないか。ちなみに、おいらは長いことJCBのJALカードを使っていたところ、最近ダイナースのANAカードに切り替えた。年会費高いけど、それを上回るメリットがあり、何よりもマイルの期限がないことがうれしい。さらに余談で、クレジットとは「信用・信頼」という意味。なんかお金的な言葉の意味だと思っていた。
【デザイナーズ&キャラクターズ】
DCブランド。バブルの頃にもてはやされたブランドの服。おいらが高校生の頃にはやっていて、ジャケット1着5万とか10万とかで買って喜んでいた人間がいて、丸井は大賑わいだった。丸井カードの分割払いで買って、ローンに苦しんだろうに。おいらはカジュアル派だったので、そんな苦労はしなかったけれども。バブルと言えば、うちの近所にジュリアナ東京跡地があって、営業していた90年代前半はさぞかしにぎわっていたんだろうな。今はとってもゆったりとした穏やかな街になっている。その近くには月9でやってたラブジェネレーションのキムタクが住む家があったのだが、最近取り壊されて駐車場になってしまった。

CArrayで配列の配列(ネスト)を実現する方法 [ソフト開発]

CArrayで配列の配列(ネスト)を実現したいことがよくある。
シンプルにこんなことやると、ビルドエラーになる。
typedef struct {  // 構造体
	CStringArray m_ary;
}S_TEST;

CArray<S_TEST,S_TEST> ary;
S_TEST test1;
test1.m_ary.Add(_T("a"));
test1.m_ary.Add(_T("b"));
ary2.Add(test1);
S_TEST test2;
test2.m_ary.Add(_T("c"));
test2.m_ary.Add(_T("d"));
ary2.Add(test2);
一方、こんなふうにするとうまくいく。
CArray<S_TEST*,S_TEST*> ary;
S_TEST* pTest1 = new S_TEST;
pTest1->m_ary.Add(_T("a"));
pTest1->m_ary.Add(_T("b"));
ary.Add(pTest1);
S_TEST* pTest2 = new S_TEST;
pTest2->m_ary.Add(_T("c"));
pTest2->m_ary.Add(_T("d"));
ary.Add(pTest2);
構造体定義をnewにしているだけのことだ。
以下のように、値を参照しても問題なかった。
CString msg;
for( int i=0; i<ary.GetSize(); i++ )
{
	S_TEST* pTest = ary.GetAt(i);
	for( int j=0; j<pTest->m_ary.GetSize(); j++ )
		msg += pTest->m_ary.GetAt(j);
	delete pTest;
}
AfxMessageBox( msg );  // abcdと出る


テキストファイルの最大行数 [ソフト開発]

バカでかいテキストファイルを作る必要があって、結果約2GBにもなった。
CADから出力するんだけど、7.5時間もかかってしまった。
中身を見ようと思って、おなじみ秀丸くんで開こうとしたら開けなかった。
上限の行数1000万行を超えているとのこと。

軽く調べたら、秀丸エディター64bit版は1億行までに対応していた。
おいらは64bitOSを使っているが、秀丸は32bitを使っていたのだ。
64bitを入れなおしたら、なんとか読み込めた。
4845万行だから、限界の半分までいってない感じ。
秀丸くんサスガですな。

この巨大なテキストファイルにもう一つ特徴があった。
最後のほうに、1行にとてつもなく大量のテキストが書かれていたのだ。
その行だけ抜き出してファイルサイズを見たら62MB。
1バイトで半角1文字だから、62,000,000文字もあるのだ。
6200万文字ってすげぇぞ。
よくぞ、これだけの文字を1行として扱えたものだ。
たぶんこんな構造になっているから、ファイル書き出しに7.5時間も
かかってしまうのだろう。。

前の10件 | - ソフト開発 ブログトップ