ラベル WIndows の投稿を表示しています。 すべての投稿を表示
ラベル WIndows の投稿を表示しています。 すべての投稿を表示

2015年5月29日金曜日

Variant型引数をもつDLLの呼出(VisualStudio2013)


今回の仕事も古いDLLを使用して相手装置のログを読み出す開発。

DLLの説明書にはVB6.0での使用方法しか書かれていない。
発注元からVisualStudio2013から呼び出せるのか確認してもらうと
実際に確認していないが動作するはずですとの回答。
なんとかなるよなと。。。


正直、私が使ったことがあるのVisualStudio6.0で以降の開発環境って今回が初めて。
ここ数年Javaがメインで開発しているしMicrosoft製品っていうかDLLとかよく判らない。
動的なライブラリってのはわかってますが。



OS     Windows7 Pro 32Bit版
開発環境 Visual Basic 2013

簡単にやりたいことを書き出すとアナログ値を収集する装置から
一定間隔で値を取得しDBへ保存する。
収集装置から値を取り出すのにDLLを使用する。


DLLをどうやって使うのかも微妙な感じで社内のMicrosoft製品での開発に詳しい人に聞いて何とかDLLをソースで呼び出せるようになる。

さて実行して見ると実機を前にDLL側から提供されているInit()、Open()は問題なく呼び出せた。
で、実際に値を読み取るメソッドでエラーとなってしまう。

このメソッドの引数が
Method(String , String, variant)

ソースはこんな感じ

Imports VS6Lib
class test(){
Private vs6Lib As VS6Lib.VS6COMM
sub test() {
Dim ret As Long
Dim ret As Object = new Object
vs6Lib = new VS6Lib.VS6COMM()
'' DLL初期化
ret = vs6Lib.init()
IF ret<>0 THEN
'' エラー処理
ENDIF
'' 装置へ接続
ret = vs6Lib.open()
IF ret<>0 THEN
'' エラー処理
ENDIF
'' アナログ値読み出し
ret = vs6Lib.Method("装置名","ALL_READ", obj)
IF ret<>0 THEN
'' エラー処理
ENDIF
~DB登録等の処理~
}
}

variant型はObject型に置き換えるとの記載を目にしたのでvariantの引数はObjectを
渡しているのだがDLLから帰ってくるエラー内容は、データ配列数が少ないとなっている。

このメソッドを使用するとvariant型に取得したいアナログ値をByte配列にして
戻してくれるらしいのだが…

同じ動作をするメソッドでvariantの箇所をStringでファイル名を指定するとファイルに出力してくれるメソッドがあるのでこちらを試してみると正常終了となりファイルも作成されてて当然値も出力されている。

やっぱりvariant型への引数の渡し方が悪いんだね。

調べてみても有用な情報は見つからず…
既に値が取れる前提で以降の処理は作成されているため変更は手戻りが大きすぎる。

なんとか引数を渡せないのか?
DLLからはByte配列が戻ってくるのでByte配列を引数に指定してみるが型が違うとエラーになる。当然か…

やっぱりファイル経由で値を取らないと駄目なのか?

しばし、考察


variant型の使い方を見ているとユーザ定義型などをvariant型引数に突っ込んだり出来るらしい。
もしかしてObject型にもユーザ定義型って突っ込めるのか?

そう思い試してみることに

'' Byte配列を定義
Dim b(0 To 64) As Byte
obj = b
'' アナログ値読み出し
ret = vs6Lib.method("装置名","ALL_READ", obj)
IF ret<>0 THEN
'' エラー処理
ENDIF

こんな感じで試してみるとエラーは発生しないで値を取れました!

取れたんですがさらに厄介なことに
 byte, byte,       byte, byte, byte, byte
 状態, ステータス, 値(Single 4byte)
ってな状態で返してくれているらしい。浮動小数点byteの中見ても判らんし正しい値が取れているのか?

Singleは浮動小数点なのでbyteを単純に変換出来るのか?
と調べてみると
System.BitConverter.ToSingle(byte配列, 開始位置)
Byte配列からシングルへの変換メソッドが有りました

        Dim sVal as Single = System.BitConverter.ToSingle(b, 2)

こんな便利なメソッドが用意されているなんて素敵です。
これで無事値を取得することが出来ました。


しかしVBって結構沢山の人が使っていると思うのだが情報を見つけるのが大変。
検索の仕方が悪いのか目的の情報になかなかたどり着けない。
情報が多すぎるんだろうなきっと。。。


この装置が出来てから10年近く立ってるんだったらDLL位更新して欲しいよな。後64bit版もね
ハード屋さんなんでソフトを再作成するの面倒なのかな?

2015年5月18日月曜日

外字登録後、Windowsで日本語が正常に表示されなくなってしまった時の対処法


仕事の都合で客先で使用している外字をフォントファイルに組み込んで使用していたのですが、仕事が終了したことも有り外字ファイルを削除したところ、プリンターの設定画面やAdobeReaderでPDFを開くとメニューの日本語が表示されなくなってしまいました。
外字自体はきちんと表示されていたんだが…

日本語部分が表示されない…

日本語部分が全く表示されず、操作が出来ない状態。
せめて英語表示の方がまだ判るんだが。


ネットを調べても同様の現象は見つからない。。。
文字化けの対処方法はあっても日本語が表示されないってのはあまり起きないんだろうな。

たどり着いたのがレジストリ値。
regeditを使用して外字フォントを修正します。


スタート
 プログラムとファイルの検索欄にregeditと入力

  以下のレジストリを編集
  コンピューター
   |-HKEY_CURRENT_USER
    |-EUDC
     |-932
      +SystemDefaultEUDCFont

ここの値が組み込んだ外字ファイル名となっていたので936、949と同じEUDC.TTEに変更。
変更後、再起動を行ったら無事復旧しました。
※regeditで他の値を修正するとwindowsの挙動がおかしくなるので注意!

ダブルクリックすると編集できます

OKで登録されます

この外字ファイルを組み込んだ際に使用したツールで削除したつもりだったんだが上手く解除できていなかったのか?

外字ファイルを変更したらeudc.tteに戻す必要があったんだね。

これなら操作出来ます。



使用しているPCはWindows7 Professional 64bit版です。

同じ現象で苦しんでいる人の助けに慣れれば幸いです。



2014年7月16日水曜日

リモートデスクトップでコンソールセッションに接続


Windows2003Serverへリモートデスクトップでアクセスし起動中のアプリを停止させようとしたら動いているはずのアプリがいない!
タスクマネージャのプロセスではちゃんと動いているのに~なんて事無いですか?


これはリモートデスクトップで接続した時に違うセッションに接続しているためだそうです。
その場合、コマンドプロンプトから以下のコマンドで接続するとコンソール・セッションに接続できます。

c:\>mstsc.exe /console /V:xxx.xxx.xxx.xxx


/Vは接続先のIPアドレスを入れます。
IPアドレスをしてしないとリモートデスクトップ接続画面で接続先を指定する事になります。

接続するときは毎回コンソールセッションに繋ぎたい場合などは上記の一行をメモ帳などに書き込んでmstsc-aaa.batなんてバッチファイルにしておけば便利ですね。



Windows7にてhostsファイルを編集するには


hostsファイルってご存じですか?

ネットワークのIPアドレスとホスト名(マシン名)を紐付けてくれるファイルです。
最近は使うことがあまりないと思うのですが古いシステムなどでは使用していたりするんです。

昔のシステムってアプリケーションとかに直接IPアドレスとか持っていたりするのでこれをホスト名にしておけばhostsファイルの修正だけで済むわけです。

が、今となってはこのファイルを簡単に変更できてしまうと悪意のあるサイトに簡単に誘導できてしまうためセキュリティが強化され編集出来ないんですよね。

ちょっと古いシステムを動かしたいのでhostsファイルを編集したいんですが…

秀丸エディタで開くとアクセス制限がかかっていて開くことは出来ても保存が出来ません。
プロパティとか見ても権限変更出来ないし…
まだ、Windows7を使い始めて半月なので正直どうすりゃいいんじゃ?って感じ



ネットでいろいろ調べて見ると管理者権限で実行すればよいなんて見つかる。
ふむふむ、秀丸エディタのアイコンを右クリックして「管理者として実行」すると編集することが出来ました!こんなメニューがあるなんて知らなかったよ。
※メモ帳でも同じように管理者で実行すれば問題なく編集できるはずです。


注意!
hostsファイルをドラッグ&ドロップで秀丸、メモ帳に渡しても表示すらしないです。
エディタのメニューでファイルを開くから開かないと編集出来ません。
(一体どんな理由なんだろうか?)


今回はhostsファイルを例にしましたが「ファイルが編集できない~!」なんて時はメモ帳やエディタを「管理者として実行」してみましょう!


2014年3月22日土曜日

Windows2008ServerでVC++6.0で作成したプログラムを動かす


Windows2003ServerからWindows2008R2へのサーバリプレース作業がありました。
DBもSQLServer2000からSQLServer2008へアップグレード。

このWindows2003サーバ本来持っている機能は作成しなおしここまでは問題なく作業終了。

ところが現地で問題が発覚。
本来、別サーバで動いているべきアプリがいつの間にかリプレース対象のサーバで動いていたことが発覚!。
当然、仕様落ちだし作業範囲外。とは、言ってもその動いていたアプリをWindows2008で動かさねば。


このアプリVC6.0++ で作成されていてすんなり動くことはなく多々、問題がありそう。

機能
コンソールアプリで通信を行い受信したデータを別サーバのDBへ書き込む。
書き込む先はWindows2000サーバでDB接続はODBC。
実行ファイルの他にdllが2つある。


問題となりそうなところ

1.64bitOSで32bitで作成されたアプリが動くのか?
  
2.DLLが動作するのか?

3.ODBC接続でうまく接続できるのか?


早々に対応しないといけないのでVMにWindows2008R2の試用版を入れて動作確認。

まず、アプリをそのままコピーして起動してみる。
起動した時点で、DLLが見つかりませんとメッセージが表示される。
そのためDLLを”Windows\System32”へコピーしてみるが状況は変わらず。
次に別に作成した”c:\work”へコピーし環境変数のPATHにこのフォルダを追加して実行すると起動は出来る。

PATHを追加しなくても動作出来ないのか調べたところ、WOW64で32Bit 版のアプリを検出すると、CPUを32bitプログラムが動く「Compatibility Mode」に変更するそうで、その際参照するシステムフォルダは”Windows\SysWOW64”になるとのこと。
それならと、DLLをコピーしてみる。(当然System32、PATHは元に戻して)
実行すると何とか起動が出来るようになった。

さすがにマイクロソフトも考えてくれて傷んだね。

これで1,2の問題は解決出来そう。

次が3.のODBC接続。
現地と同じようにODBC接続を設定する。
ODBC設定の動作確認で接続完了まで行っているので設定自体は問題無いと思うが残念ながらアプリはエラーメッセージを吐き出し接続できない。
こちらも調べてみると32Bit版のODBC接続を設定すれば良いそうです。
32bit版のODBC設定画面は”Windows\SysWOW64\odbcad32.exe”を起動して同じ設定にすれば良いらしい。
設定後再起動すると確かにDBへ接続できている様子。
通信用のデータを流してDBへ書き込むところまでひと通り確認できた。
※但しこの時点で接続しているDBはWindowsXP+SQLServer2005で現地とは異なる


ODBCドライバの説明で下位のSQLServerへの互換性は保証しているなんて記載を見つける。
裏切られることの多いマイクロソフトを信じて現地のサーバへセットアップに。

嬉しいことに一発でうまく行きました。


まとめ、Windows7、Windows2008R2など64bitOSで32bit版を動作させるにはSysWOW64を使用すればうまく行きます。