2009-12-24 12:30
jAmEs_
[建议]TCnDebugger
我处对TCnDebugger.InternalOutputMsg做以下调整,这样可以在没有安装查看器的情况下,输入到文件,这样可以在普通用户使用时,作为跟踪器使用,强烈希望管理员能调整。:)或者有更好方法也行。。。
procedure TCnDebugger.InternalOutputMsg(const AMsg: AnsiString; Size: Integer;
const ATag: AnsiString; ALevel, AIndent: Integer; AType: TCnMsgType;
ThreadID: DWORD; CPUPeriod: Int64);
var
TagLen, MsgLen: Integer;
MsgDesc: TCnMsgDesc;
FChannelReady: Boolean;
procedure GenerateMsgDesc;
begin
// 进行具体的组装工作
MsgLen := Size;
if MsgLen > CnMaxMsgLength then
MsgLen := CnMaxMsgLength;
TagLen := Length(ATag);
if TagLen > CnMaxTagLength then
TagLen := CnMaxTagLength;
FillChar(MsgDesc, SizeOf(MsgDesc), 0);
MsgDesc.Annex.Level := ALevel;
MsgDesc.Annex.Indent := AIndent;
MsgDesc.Annex.ProcessId := GetCurrentProcessId;
MsgDesc.Annex.ThreadId := ThreadID;
MsgDesc.Annex.MsgType := Ord(AType);
MsgDesc.Annex.TimeStampType := Ord(TimeStampType);
case TimeStampType of
ttDateTime: MsgDesc.Annex.MsgDateTime := Date + Time;
ttTickCount: MsgDesc.Annex.MsgTickCount := GetTickCount;
ttCPUPeriod: MsgDesc.Annex.MsgCPUPeriod := GetCPUPeriod;
else
MsgDesc.Annex.MsgCPUPeriod := 0; // 设为全 0
end;
// TimeMarkStop 时所耗 CPU 时钟周期数
MsgDesc.Annex.MsgCPInterval := CPUPeriod;
CopyMemory(@(MsgDesc.Annex.Tag), Pointer(ATag), TagLen);
CopyMemory(@(MsgDesc.Msg), Pointer(AMsg), MsgLen);
MsgLen := MsgLen + SizeOf(MsgDesc.Annex) + SizeOf(DWORD);
MsgDesc.Length := MsgLen;
end;
begin
if FAutoStart and not FIgnoreViewer and not FViewerAutoStartCalled then
begin
StartDebugViewer;
FViewerAutoStartCalled := True;
end;
Inc(FMessageCount);
if not CheckEnabled then Exit;
FChannelReady := FChannel.CheckReady;
if (not FChannelReady) and (not FDumpToFile) then Exit;
GenerateMsgDesc;
if FChannelReady then
begin
if FChannel.CheckFilterChanged then
FChannel.RefreshFilter(FFilter);
if CheckFiltered(string(ATag), ALevel, AType) then
InternalOutput(MsgDesc, MsgLen);
end;
// 同时 DumpToFile
if FDumpToFile and not FIgnoreViewer and (FDumpFile <> nil) then
begin
if not FAfterFirstWrite then // 第一回写时需要判断是否重写
begin
if FUseAppend then
FDumpFile.Seek(0, soFromEnd)
else
begin
FDumpFile.Size := 0;
FDumpFile.Seek(0, soFromBeginning);
end;
FAfterFirstWrite := True; // 后续写就无需判断了
end;
FDumpFile.Write(MsgDesc, MsgLen);
end;
end;
[[i] 本帖最后由 jAmEs_ 于 2009-12-24 16:30 编辑 [/i]]
2009-12-24 15:31
Passion
本来就有输出到文件的功能哇。
2009-12-24 16:29
jAmEs_
怎么搞?我意思是直接由这个类输出哦,没有查看器的情况下~~麻烦告诉一下,呵呵
2009-12-24 16:52
jAmEs_
我回去看了一下,好像必须打开查看器,才会输出文件吧?
2009-12-24 18:02
Passion
打开查看器是输出到查看器,然后查看器可以另存文件。
我记得定义DUMP_TO_FILE的编译条件就行了,可以看看CnDebugger.pas头上的编译指令。
2009-12-24 23:25
jAmEs_
:lol 我感觉你忘记了,能否再去看看?DUMP_TO_FILE是启动输出文件,但是如果查看器没有启动,输出时,检查到就会跳出来。
因为输出时,用到MapFile,而MapFile是查看器创建的,没有创建就不会输出了。
2009-12-25 11:13
Passion
你的意思是不要启动查看器而直接输出到文件?
2009-12-26 11:15
jAmEs_
对啊。。
2009-12-26 19:39
Passion
明白你的需求了。我改了一下,晚上回去提交。
2009-12-27 13:36
jAmEs_
:lol :victory: :handshake
2009-12-28 13:27
Passion
先试一试我改的内容?在附件里。
2009-12-28 18:57
jAmEs_
好像跟我的差不多吧,我加FChannelReady(最好改为ChannelReady...)是为了不多次执行FChannel.CheckReady,因为里面好像有一些代码,避免效能问题,不过有需要我迟点看看。
2009-12-28 20:19
Passion
好的。命名上局部变量似乎是不太合适用F,F都是表示Field,一般是类的成员变量。
2009-12-30 10:31
jAmEs_
FChannelReady当时是从FChannel.CheckReady变来的,当时忘了删除F:lol
测试OK,你处看看是否需要按我说的用变量来保存FChannel.CheckReady结果,这样可以避免好几次判断。。。:D
2009-12-30 17:05
Passion
好的,接受。
2010-2-11 11:38
jAmEs_
procedure TCnDebugger.InternalOutputMsg(const AMsg: AnsiString; Size: Integer;
const ATag: AnsiString; ALevel, AIndent: Integer; AType: TCnMsgType;
ThreadID: DWORD; CPUPeriod: Int64);
var
TagLen, MsgLen: Integer;
MsgDesc: TCnMsgDesc;
LeftMsg: AnsiString;
LeftSize: Integer;
procedure GenerateMsgDesc;
begin
// 进行具体的组装工作
MsgLen := LeftSize;
if MsgLen > CnMaxMsgLength then
MsgLen := CnMaxMsgLength;
TagLen := Length(ATag);
if TagLen > CnMaxTagLength then
TagLen := CnMaxTagLength;
FillChar(MsgDesc, SizeOf(MsgDesc), 0);
MsgDesc.Annex.Level := ALevel;
MsgDesc.Annex.Indent := AIndent;
MsgDesc.Annex.ProcessId := GetCurrentProcessId;
MsgDesc.Annex.ThreadId := ThreadID;
MsgDesc.Annex.MsgType := Ord(AType);
MsgDesc.Annex.TimeStampType := Ord(TimeStampType);
case TimeStampType of
ttDateTime: MsgDesc.Annex.MsgDateTime := Date + Time;
ttTickCount: MsgDesc.Annex.MsgTickCount := GetTickCount;
ttCPUPeriod: MsgDesc.Annex.MsgCPUPeriod := GetCPUPeriod;
else
MsgDesc.Annex.MsgCPUPeriod := 0; // 设为全 0
end;
// TimeMarkStop 时所耗 CPU 时钟周期数
MsgDesc.Annex.MsgCPInterval := CPUPeriod;
CopyMemory(@(MsgDesc.Annex.Tag), Pointer(ATag), TagLen);
CopyMemory(@(MsgDesc.Msg), Pointer(LeftMsg), MsgLen);
if LeftSize > CnMaxMsgLength then
begin
LeftMsg := Copy(LeftMsg, CnMaxMsgLength + 1, LeftSize);
LeftSize := LeftSize - CnMaxMsgLength;
end
else
LeftSize := 0;
MsgLen := MsgLen + SizeOf(MsgDesc.Annex) + SizeOf(DWORD);
MsgDesc.Length := MsgLen;
end;
procedure DoInternalOutputMsg;
begin
if FAutoStart and not FIgnoreViewer and not FViewerAutoStartCalled then
begin
StartDebugViewer;
FViewerAutoStartCalled := True;
end;
Inc(FMessageCount);
if not CheckEnabled then
Exit;
if not FChannel.CheckReady and not FDumpToFile then
Exit;
while LeftSize > 0 do
begin
GenerateMsgDesc;
if FChannel.CheckReady then
begin
if FChannel.CheckFilterChanged then
FChannel.RefreshFilter(FFilter);
if CheckFiltered(string(ATag), ALevel, AType) then
InternalOutput(MsgDesc, MsgLen);
end;
// 同时 DumpToFile
if FDumpToFile and not FIgnoreViewer and (FDumpFile <> nil) then
begin
if not FAfterFirstWrite then // 第一回写时需要判断是否重写
begin
if FUseAppend then
FDumpFile.Seek(0, soFromEnd)
else
begin
FDumpFile.Size := 0;
FDumpFile.Seek(0, soFromBeginning);
end;
FAfterFirstWrite := True; // 后续写就无需判断了
end;
FDumpFile.Write(MsgDesc, MsgLen);
end;
end;
end;
begin
LeftMsg := AMsg;
LeftSize := Size;
DoInternalOutputMsg;
end;
2010-2-11 11:40
jAmEs_
我处对CnDebug做再次改动,当信息长度大于4096时,自动分割信息,希望接纳。或可考虑增加选项控制。
代码可适当调整。
2010-2-26 10:32
jAmEs_
没有人回应一下?:L
2010-7-11 11:32
艳漫虹
新人报到,怎么好像很冷清的。。。。。。
页:
[1]
Powered by Discuz! Archiver 5.0.0
© 2001-2006 Comsenz Inc.