WMIで情報取得、showmessageで結果を表示後「OK」を押すとエラーとなります。コメントにするとエラーは出ません。
フォーム不要なのでインターネットのフォームありのサンプルを参考にフォームなしで作ったのですがフォームなしにすることに問題があるのでしょうか。
delphi初心者で対処方法が分からず困っています。
よろしくお願いします。
----
・環境:WindowsXP,Delphi6
・エラーメッセージ
EAccessViolationがモジュールProject2.exeの 00005F98で発生しました。
モジュール'Project2.exe'のアドレス00405F98でアドレス57FB2C08に対する読み込み違反が起きました。
program Project2;
uses
Windows, Messages ,Dialogs, ActiveX, WbemScripting_TLB;
var
Locator: ISWbemLocator;
Service: ISWbemServices;
ObjSet: ISWbemObjectSet;
Enum: IEnumVariant;
Obj: OleVariant;
Value: Cardinal;
msg: string;
{$R *.res}
begin
Locator := CoSWbemLocator.Create;
Service := Locator.ConnectServer('.', 'root\cimv2', '', '', '', '', 0, nil);
ObjSet:= Service.ExecQuery('SELECT * FROM Win32_ComputerSystemProduct',
'WQL', wbemFlagReturnImmediately, nil);
Enum:= (ObjSet._NewEnum) as IEnumVariant;
while (Enum.Next(1, Obj, Value) = S_OK) do
begin
Obj:= IUnknown(Obj) as SWBemObject;
msg := Obj.Vendor + Obj.Name + Obj.IdentifyingNumber;
end;
showmessage(msg); //<--このメッセージ表示後「OK」を押すとエラーとなります。
end.
D6が無いのでなんとも言えませんが
program Project1;
uses
Windows, Messages ,Dialogs;
{$R *.res}
begin
ShowMessage('1');
ShowMessage('2');
ShowMessage('3');
MessageBox(0,'a','b',MB_OK);
end.
これが動けばShowMessageはシロだと思います。
Win32APIで動けばそれはそれでいいかもしれません。
http://msdn.microsoft.com/ja-jp/library/cc410914.aspx
XP D6Proで。
このソースコードだと'CoInitialize は呼び出されていません。'というエラーになります。
で、beginの後にApplication.Initialize;を入れたらエラーは出なくなりました。
D様、monaa様
アドバイスありがとうございます。
Application.Initialize」からヘルプを確認してQFormユニットを追加することでエラーが出なくなりました。残念ながら私には理由は分かりません。
「Application.Initialize;」はなくてもOKでした。
初心者で手探り状態なので今後もよきアドバイスよろしくお願いします。
変更後のソース−−−−−
program Project2;
uses
Windows, Messages ,Dialogs, ActiveX, WbemScripting_TLB,QForms;
var
Locator: ISWbemLocator;
Service: ISWbemServices;
ObjSet: ISWbemObjectSet;
Enum: IEnumVariant;
Obj: OleVariant;
Value: Cardinal;
msg: string;
// Application: TApplication; ←なくてもOKなのでコメント
// {$R *.res} ←使用していないのでコメント
begin
// Application.Initialize; ←なくてもOKなのでコメント
Locator := CoSWbemLocator.Create;
Service := Locator.ConnectServer('.', 'root\cimv2', '', '', '', '', 0, nil);
ObjSet:= Service.ExecQuery('SELECT * FROM Win32_ComputerSystemProduct',
'WQL', wbemFlagReturnImmediately, nil);
Enum:= (ObjSet._NewEnum) as IEnumVariant;
while (Enum.Next(1, Obj, Value) = S_OK) do
begin
Obj:= IUnknown(Obj) as SWBemObject;
msg := Obj.Vendor + #13#10 + Obj.Name + #13#10 + Obj.IdentifyingNumber;
end;
showmessage(msg);
end.
訂正です。
QFormsを組み込むとPG実行時に「qtinitf.dll」が必要になります。
Formsに変更して「Application.Initialize; 」追加でdll不要で動作しました。
program Project2;
uses
Windows, Messages ,Dialogs, ActiveX, WbemScripting_TLB,Forms;
var
Locator: ISWbemLocator;
Service: ISWbemServices;
ObjSet: ISWbemObjectSet;
Enum: IEnumVariant;
Obj: OleVariant;
Value: Cardinal;
msg: string;
Application: TApplication; //<---追加
// {$R *.res}
begin
Application.Initialize; //<---追加
Locator := CoSWbemLocator.Create;
Service := Locator.ConnectServer('.', 'root\cimv2', '', '', '', '', 0, nil);
ObjSet:= Service.ExecQuery('SELECT * FROM Win32_ComputerSystemProduct',
'WQL', wbemFlagReturnImmediately, nil);
Enum:= (ObjSet._NewEnum) as IEnumVariant;
while (Enum.Next(1, Obj, Value) = S_OK) do
begin
Obj:= IUnknown(Obj) as SWBemObject;
msg := Obj.Vendor + #13#10 + Obj.Name + #13#10 + Obj.IdentifyingNumber;
end;
showmessage(msg);
end.
showmessageは、内部でTFormを使用してるので、厳密にフォーム無しにはならない。
monaa さんのレスにある、MessageBox はWindowsAPIなので、これを使い
Dialogsを削除したらいいのでは?
・・・テストしていませんけど。
ツイート | ![]() |