また、お世話になります。
今更ですが古い Windows OS(95/98/Meなど) でも正しく動く
ソフト作りの方法を知りたいです。
開発環境は Windows XP SP3+VC2003 です。
自作ソフトを作っていて MSDN サイトで API 関数のOSバージョンを
調べながら作っています。それでちょっと疑問を持ちました。
例えば GlobalMemoryStatus と GlobalMemoryStatusEx の場合。
GlobalMemoryStatus……Windows95、NT3.1以降
GlobalMemoryStatusEx…Windows2000以降
となっている。
このとき GlobalMemoryStatusEx 関数をインポートライブラリで
ソフトを作ったとします。そしてサポートされていない Windows95、
Windows NT3.1 で実行するとどうなるのですか?
僕の考えでは起動時にOSバージョンをチェックして
Windows2000以降なら GlobalMemoryStatusEx で
それ以前なら GlobalMemoryStatus でメモリ容量を
取得するようにしたいです。
この場合サポートされていない OS 上でエラーとか
でないできりわけって出来ますか?
ここが知りたいところです。
サポートされていない API を利用していると
エラーダイアログが出そうな気がしますが
どう回避すれば良いですか?
お時間があるときでよいので教えて下さい。
お待ちしています。
確かめていないので推測です。
俺は95持ってないので。
サポートしていないというのが
存在しないという意味ならばあなたの方法ではできません。
存在するけど動作しないというのならば
あなたの方法でできます。
サポートされていないOSで実行しようとすると、
「欠落エクスポートがうんたら」といったダイアログが出て起動できません。
(ただし、サポートしていなくてもエントリポイントだけは
用意されている場合もありますが)
LoadLibraryで動的にロードしてGetProcAddressで関数へのポインタを取得して呼び出か、
DLLを遅延ロードするように設定すれば良いと思います。
wclrp ( 'o')さんへ。
>存在するけど動作しないというのならば
>あなたの方法でできます。
DLLに実装されていない API 関数をどうチェックするかを
知りたかったのです。
>俺は95持ってないので。
こちらも持っていないので試しようがないです。
例えとして GlobalMemoryStatusEx を出しましたが
他にも Windows NT系しか動かないソフトのとき、
Windows 9x系では実行時にエラーを出して起動しない方法も
知りたかったのです。
krさんへ。
>「欠落エクスポートがうんたら」といったダイアログが出て起動できません。
やっぱり。
>LoadLibraryで動的にロードしてGetProcAddressで関数へのポインタを取得して…
古い OS の DLL に実装されていない API 関数は全部 LoadLibrary、
GetProcAddress で API 関数を呼び出せば「欠落エクスポート」の
ダイアログが出ずにバージョンチェックで切り分け出来ますか?
>DLLを遅延ロードするように設定すれば良いと思います。
これはどのような機能でしょうか?
ちょっと調べてみました。
http://blogs.sqlpassj.org/yas/archive/2004/03/21/1279.aspx
例外処理を必要とするようですね。
でも起動時にOSバージョンで起動を禁止する場合は
「欠落エクスポート」ダイアログが出なくなるから
便利かなこの方法?
いろいろと考えて LoadLibrary で動的にロードすれば
古い OS の DLL に実装されていない API 関数もチェックできそうですね。
とりあえずこの方法でソースを書き直して見ます。
後、もう一つ質問です。
VC2005 では Windows98以降で動くプログラムしか作れないと
次のサイトに書かれていました。
http://www.usefullcode.net/2006/12/visual_studio_2005windows_95.html
この場合は LoadLibrary で動的ロードしても
起動時にエラーになってしまうのですよね。
VC2003で作ったソフトはどうなりますか?
Windows95でも起動しますかね。
ちょっと訂正。
kernel32.dllは遅延ロードできないので、GlobalMemoryStatus(Ex)を使う場合は駄目ですね。
>この場合は LoadLibrary で動的ロードしても
>起動時にエラーになってしまうのですよね。
そうです。
確か「システムに装着されているデバイスは動作していません」とか、
「新しいバージョンのWindowsが必要です」みたいなメッセージが表示されたはずです。
スタートアップルーチンを自前で書けばどうにかなるかも知れませんが、
制限が多すぎて現実的でないと思います。
>VC2003で作ったソフトはどうなりますか?
VC2003であれば大丈夫です。バージョンごとの動作OSは以下のようになっています。
VC2003 95以降、NT4.0以降
VC2005 98/Me、2000以降
VC2008 2000以降
もっとも、今から作るプログラムでWindows95に対応する必要があるかは疑問です。
Windows95を持っていないのであれば、何かトラブルの報告があっても対処が難しいですし。
krさん。
レスありがとうございます。
>VC2003であれば大丈夫です。バージョンごとの動作OSは以下のようになっています。
この情報ありがとうございます。
ヘルプを調べても見つからなかったので。
>もっとも、今から作るプログラムでWindows95に対応する必要があるかは疑問です。
そうですね。
自作ソフトの一部は Vector さんに登録していて説明書とかに
Windows NT/2000/XP と書いても Windows95/98/Me で使って
動作しないという方がたまにいるようです。
説明書を読めといいたいけどね。
OSバージョンをチェックできるなら先にチェックして
起動時に警告ダイアログを出そうかと思っていたのです。
いろいろと調べたら次のサイトに質問の回答が載っていました。
http://www.usefullcode.net/2006/12/apios.html
やはり LoadLibrary、GetProcAddress で呼び出すようですね。
でも LoadLibrary、GetProcAddress で渡す文字列は
どうすれば良いでしょうか?
今のところマルチバイト文字でソフトを作っています。
今後、文字コードを Unicode で統一しようとした場合は
9x系では基本的に Unicode が利用できませんよね。
TCHAR 型はコンパイル時に決定されるため
9X系でも動作するようにする場合は文字コードを
マルチバイト文字で合わせるしかないのでしょうか?
(9x系とNT系と分けた方がいいのかな?)
> OSバージョンをチェックできるなら先にチェックして
> 起動時に警告ダイアログを出そうかと思っていたのです。
フツーはこういう要望にはインストーラで対応するもんだ。
んで 9X 系用のバイナリと NT 系のバイナリを分けるのであれば、これもまた
やはりインストーラでインストールし分けるのが良いと思うぞ。
あと文字コードについていうなら GetProcAddressA を直接使えばいい
GetProcAddressにはAもWも無いです。
GetProcAddressから取得したい関数にAとWとがある場合は
どちらなのかを明示指定する必要がありますけど。
>フツーはこういう要望にはインストーラで対応するもんだ。
なるほど。
気づきませんでした。
>んで 9X 系用のバイナリと NT 系のバイナリを分けるのであれば、これもまた
>やはりインストーラでインストールし分けるのが良いと思うぞ。
この考えがなかったです。
ありがとうございました。
>GetProcAddressにはAもWも無いです。
TCHAR型を使った場合ですよね。
DLLのときはAやWを直接呼ぶ必要がありそうですね。
皆様ありがとうございました。
インストール方式ですべて解決する方向で行きます。
LPCSTRとLPCTSTRの違いも分からないアホがここにも