我正在使用 Delphi 11.1 和 WebBroker 开发我的第一个 ISAPI Web 模块,并且想要将日志写入文件系统。为了测试目的,我做了以下过程
TryWriteFile
,测试是否可以在WebApplicationDirectory
中创建文件:
procedure WriteMyFile;
var
fname: string;
fs: TFileStream;
begin
fname := TPath.Combine(WebApplicationDirectory, 'myfile.log');
fs := TFileStream.Create(fname, fmCreate or fmOpenWrite or fmShareDenyNone);
fs.Write([$54,$65,$73,$74,$0D,$0A], 6); { T e s t CR LF }
fs.Free;
end;
现在,我尝试在 DefaultHandler 操作中调用
WriteMyFile
,但收到“访问被拒绝”异常:
procedure TWebModule1.WebModule1DefaultHandlerAction(Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
begin
WriteMyFile; //==> exception: access denied!
Response.Content := 'no error!';
end;
当我从单独的线程调用
WriteMyFile
时,它可以工作。文件已正确创建:
procedure TWebModule1.WebModule1DefaultHandlerAction(Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
var
thr: TThread;
begin
//WriteMyFile; //==> exception: access denied!
thr := TThread.CreateAnonymousThread(WriteMyFile); //works!
thr.FreeOnTerminate := False;
thr.Start;
thr.WaitFor;
thr.Free;
Response.Content := 'no error!';
end;
所以我的问题是:为什么?和Windows文件夹权限有关系吗?如果是这样,那么在不同的线程中它们怎么会不同呢?
IIS配置:
MYPOOL
C:\inetpub\wwwroot\MYPOOL\
添加了“修改”权限 IIS AppPool\MYPOOL
IIS 和 Delphi 11.1 Alexandria 都在我的 Windows 10 计算机上运行。
无论您是从主线程还是从后台线程调用它,您的
WriteMyFile
过程的工作方式都没有区别。如果无法创建或写入现有文件,则会引发异常。
区别在于,当您从线程调用它时,引发的异常包含在线程内,并且不会传播到该线程外部的代码。
如果您想知道是否引发了异常,您可以检查线程的
FatalException
属性,如果已分配它,则它包含您可以检查的异常对象。
您可以在等待线程完成之后、释放线程之前或在线程
OnTerminate
事件处理程序中执行此操作。
procedure TWebModule1.WebModule1DefaultHandlerAction(Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
var
thr: TThread;
begin
thr := TThread.CreateAnonymousThread(WriteMyFile);
thr.FreeOnTerminate := False;
thr.Start;
thr.WaitFor;
if thr.FatalException is Exception then
Response.Content := Exception(thr.FatalException).Message
else
Response.Content := 'no error!';
thr.Free;
end;