こんにちは。
ファイルを新規で作成し、
そこに文字(Str)を書き出そうとしています。
procedure TForm1.Button1Click(Sender: TObject);
var
FileName,Str: String;
FileHandle,Size: Integer;
begin
Str := 'abcdefg';
FileHandle := FileCreate('C:\test.txt');
FileName := '???'; //←何を入れる?
//FileHandle := FileOpen(FileName,fmOpenReadWrite);
Size := GetFileSize(FileHandle, nil);
FileWrite(FileHandle,FileName,Size);
~~~??~~~
end;
ヘルプなどを見たのですが、書き込むことができません。
Str の"abcdefg"という文字を書き込むにはどのようにすればよいのでしょうか?
お分かりの方がいましたら、宜しくお願いします。
FileCloseを忘れてますよ?
でも、それでもうまくは書き込めないはずですね、
FileWriteの第二引数のBufferの使い方が間違っています。
FileWriteなどは使わないのではっきりとはいえませんけど、
Bufferには、ファイルに書き込む内容、第三引数にはそのサイズを指定しないといけません。
GetFileSizeを使った時点では、ファイルは空っぽですね?
ところで、TStringListのSaveToFileを使ったほうが早いような気がします。
この方法を覚えておいても損はないと思いますけど。
FileCreateするとファイルハンドルが返されます。
この時点では、ファイルは「閉じていません」
再度開く必要はありません(閉じるまで開けません)。
サイズは、書き込みたい文字列のサイズです。
Bufferは、
PChar(Str)^
と指定すればよいです。
array of charやarray of byteならば、その配列の最初の要素を指定します。
# 指定は、ポインタではありません
たかみちえさん、にしのさん、ありがとうございます。
procedure TForm1.Button1Click(Sender: TObject);
var
FileHandle: Integer;
Str: String;
begin
FileHandle := 0;
try
FileHandle := FileCreate('C:\test.bat'); //ファイル作成
Str := 'ipconfig/all > C:\test.txt';
FileWrite(FileHandle,PChar(Str)^,(Length(Str)));
//Sleep(100);
ShellExecute(FileHandle, 'open', 'C:\test.bat', nil, nil, SW_SHOW); //起動
finally
FileClose(FileHandle); //ファイル閉じる
//DeleteFile('C:\test.bat'); //ファイル削除
end;
end;
test.batを作成して起動させ、'test.txt'を作り、
test.batを削除しようとしているのですが、'test.txt'が作成されません。
test.batは作成され、手動で起動させるとちゃんと'test.txt'を作成します。
test.batが作成される前に起動させているとかなのでしょうか?
どうぞよろしくお願いします。
コードの実行速度が速すぎて、バッチファイルがまだ動作中なのでは?
バッチファイルの実行終了を待つようにタイミングを合わせないといけなさそうです。
バッチファイルに使えるかどうかは試したことないですけど、
うちの"おんぷ村倉庫"にある、"stdFiles"ユニットの"RunAs"関数を試してみてください。
バッチファイルならば、第四引数のWaitFlagに、wfWaitFullを指定すれば、起動したプロセスが終了するまで待ってから処理を続けることができます。
いちおうこれでコンソールアプリケーションの実行待ちには成功しています。
あ、そうだ…。
バッチファイルは自己消滅させることもできるそうです。
バッチファイル入門(http://www25.cds.ne.jp/~kamiken/bach/bach.html)
まあ、その後の動作に支障をきたすと思うので、どちらにしても終了待ちをしたほうがいいとは思いますけど…。
.batは、openするものではありませんよ。
cmd(もしくはcommand)が、.batを起動します。
openの対象はcmd(もしくはcommand)となります。
cmd(もしくはcommand)のヘルプや引数の説明を見てください。
たかみちえさん、にしのさん、ありがとうございます。
ShellExecute(FileHandle, 'open', 'C:\test.bat', nil, nil, SW_SHOW); //起動
の部分を
RunAs('C:\test.bat','ipconfig/all > C:\test.txt',SW_SHOW,wfWaitFull);
ShellExecute(FileHandle, 'open', 'C:\WINNT\system32\CMD.exe ipconfig/all > C:\test.txt', nil, nil, SW_SHOW);
としてみたのですが、'test.txt'が作成されません。
ShellExecute(FileHandle, 'open', 'C:\WINNT\system32\CMD.exe', nil, nil, SW_SHOW);
とした場合、test.batは作成され、Command Prompt が起動したままになります。
Command Prompt に'ipconfig/all > C:\test.txt'を渡せばよいのでしょうか?
(そうならば、それはどのようにやるのでしょうか?)
宜しくお願いします。
cmdの引数について調べましたか?
そう書いたつもりなのですが。
コマンドプロンプト上で、
cmd /?
と実行すると引数の使い方が出ます。
これを見ると、/Cオプションが必要だということが解ると思います。
もう一つ、もしかしたら、DOSのリダイレクション機能は使えないのかもしれません。
前に同じようなことで悩んだような気がします。
# あやふやですみません
CreateProcessで起動し、その標準出力ハンドルから読みとれば可能です。
リダイレクション使えますね。
ShellExecute(0, 'open', 'C:\Windows\system32\cmd.exe', '/C ipconfig/all > test.txt', nil, SW_SHOW);
ですね。
ただし、ipconfigがどのくらいで終わるかはわかりませんよ。
ShellExecuteは、起動できたら(終了を待たずに)次の処理に移ります。
ご注意を。
にしのさん、ありがとうございます。
出来ました!
.batを作る処理も省けました。
DOSコマンドだったのですね (^-^;;
DOSはあまり触ったことがなかったのですが
これを機に勉強してみようと思います。
> ただし、ipconfigがどのくらいで終わるかはわかりませんよ。
> ShellExecuteは、起動できたら(終了を待たずに)次の処理に移ります。
> ご注意を。
実行したところ影響はなさそうなのですがもう少し検証してみます。
大変勉強になりました!
たかみちえさん、にしのさん、ありがとうございました。
ツイート | ![]() |