プロが教えるわが家の防犯対策術!

http://mrxray.on.coocan.jp/Halbow/Notes/N001.htmlを基に

//----------

unit Unit1;

interface

uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
function WinExecAndWait32(FileName: string; Visibility: Integer): Longword;
private
{ Private 宣言 }
public
{ Public 宣言 }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}


function TForm1.WinExecAndWait32(FileName: string; Visibility: Integer): Longword;
var
StartupInfo: TStartupInfo;
ProcessInfo: TProcessInformation;
begin
FillChar(StartupInfo, SizeOf(StartupInfo), #0);
StartupInfo.cb := SizeOf(StartupInfo);
StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
StartupInfo.wShowWindow := Visibility;

if not CreateProcess(nil, //<<<<<<<<<<ここで停止します
PChar(FileName), // pointer to command line string
nil, // pointer to process security attributes
nil, // pointer to thread security attributes
False, // handle inheritance flag
CREATE_NEW_CONSOLE or // creation flags
NORMAL_PRIORITY_CLASS,
nil, // pointer to new environment block
nil, // pointer to current directory name
StartupInfo, // pointer to STARTUPINFO
ProcessInfo) // pointer to PROCESS_INF
then Result := WAIT_FAILED
else
begin
WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
GetExitCodeProcess(ProcessInfo.hProcess, Result);
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
end;
end; { WinExecAndWait32 }


procedure TForm1.Button1Click(Sender: TObject);
begin
WinExecAndWait32('Notepad.exe',SW_SHOW);
ShowMessage('メモ帳が終了しました');

end;

end.
//--------------------
というプログラムの動作テストをしているのですが、ボタンを押すと、例外クラス$C0000005(メッセージaccess violation at 0x765affeb:write of adress 0x005b48ee)を送出しました。というエラーメッセージが出て停止します。

if not CreateProcess(nil, のところで止まるようです。
何か足らないところがあるのでしょうか?
Delphi XE5 Starterを使っています。

質問者からの補足コメント

  • ありがとうございます。
    次のようにしたのですが、
    実行すると「CardinalとLongBoolには互換性がありません」と出ます。
    //------------------------------
    function TForm1.WinExecAndWait32(cmd: string): Longword;
    var
    pi: TProcessInformation;
    si: TStartupInfo;
    begin
    UniqueString(cmd);// ** Point **
    result := CreateProcess(nil, PWideChar(cmd), nil, nil, False,
    CREATE_DEFAULT_ERROR_MODE, nil, nil, si, pi);
    end; { WinExecAndWait32 }

      補足日時:2015/06/09 19:12
  • ///続き
    procedure TForm1.Button1Click(Sender: TObject);
    begin
    WinExecAndWait32('Notepad.exe');
    ShowMessage('メモ帳終了');
    end;
    end.

      補足日時:2015/06/09 19:13
  • 回答ありがとうございます。
    返値の型をLongBoolに変え、
    GetExitCodeProcess(ProcessInfo.hProcess, Result);をコメントアウトしたところ、うまく動作しました。
    この行が(私のアプリに)いるのかどうか今のところ不明ですが、おかげさまで一歩前に進めました。
    ありがとうございます。

    No.2の回答に寄せられた補足コメントです。 補足日時:2015/06/10 08:59

A 回答 (2件)

最初の質問「if not CreateProcess(nil, のところで止まるようです。

」については、if文の前に「UniqueString(FileName);」を追加します。

捕捉コメントの質問「CardinalとLongBoolには互換性がありません」は、CreateProcess関数の返値のBOOL型(LongBool型の別名)の値をLongword型の変数resultに代入しているためです。
この回答への補足あり
    • good
    • 1

バージョン間による違いだったりするんじゃないですかねぇ…



http://edn.embarcadero.com/jp/article/38791
より…
>Delphi 2007(またはそれ以前) の PChar型は AnsiChar(バイト) 配列へのポインタですが、Delphi 2009 の PChar型は WideChar(ワード) 配列へのポインタとなっています。
ということで、CreateProcessW()がコールされているとすると…
http://kujirahand.com/blog/index.php?2009%252F04 …

http://stackoverflow.com/questions/6705532/acces …
など。

定数(文字列定数)として渡すとアウト…という部分かも知れません。
    • good
    • 0
この回答へのお礼

解決しました

ありがとうございます。
うまく動作するようになりました。

お礼日時:2015/06/10 09:02

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!