Delphi中是否可以將項目的.DSK文件中的斷點保存並且沒有其他桌面設置?Delphi 2007:只保存DSK文件中的斷點選項?
大多數.DSK阻礙,但不能保存調試斷點是一個真正的痛苦(特別是當它們有條件或附加操作時)。
Delphi中是否可以將項目的.DSK文件中的斷點保存並且沒有其他桌面設置?Delphi 2007:只保存DSK文件中的斷點選項?
大多數.DSK阻礙,但不能保存調試斷點是一個真正的痛苦(特別是當它們有條件或附加操作時)。
我從來沒有遇到IDE設施,只保存.Dsk文件中的斷點相關設置。
對於娛樂,我想我會試着通過使用OTA通知的IDE加載項來實現某些內容。下面的代碼可以很好地安裝到D7中安裝的軟件包中,IDE似乎很樂意重新打開一個項目,該文件的.Dsk文件已經被它處理(並且斷點已經設置!)。
正如您所看到的,當使用ofnProjectDesktopSave的NotifyCode調用OTA通知程序的FileNotification事件時,它會捕獲OTA通知程序的FileNotification事件,該事件恰好在IDE保存了.Dsk文件(最初帶有擴展名'。$$$',I在第一次寫這篇文章時沒有注意到)。然後它讀取保存的文件文件,並準備除去指定的部分列表之外的所有部分都被刪除的更新版本。用戶然後可以選擇將稀疏文件保存回磁盤。我使用了TMemIniFile來完成大多數處理,只是爲了儘量減少所需的代碼量。
當我讀到你的q時,我沒有寫過OTA通知器的經驗,但下面引用的GE專家常見問題非常有幫助,尤其是示例通告程序代碼。
正常情況下,刪除項目的.Dsk文件是無害的,但請謹慎使用此代碼,因爲它未經過壓力測試。
更新:我注意到TIdeNotifier.FileNotification事件接收到的文件名實際上有一個'。$$$'的擴展名。我不太清楚爲什麼會這樣,但看起來事件在文件重命名爲xxx.Dsk之前被調用。我認爲這需要更改 以保存稀疏版本,但顯然不是。
更新#2:已經使用的文件夾監測工具,看看到底發生了什麼,事實證明,該代碼接收桌面保存通知僅僅是最早的一批的操作有關的.dsk文件。這些包括將任何現有版本的.Dsk文件重命名爲。〜Dsk文件,並最終將。$$$文件保存爲新的.Dsk文件。
unit DskFilesu;
interface
{$define ForDPK} // undefine to test in regular app
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Buttons, StdCtrls, IniFiles, TypInfo
{$ifdef ForDPK}
, ToolsApi
{$endif}
;
{$ifdef ForDPK}
{
Code for OTA TIdeNotifier adapted from, and courtesy of, the link on http://www.gexperts.org/open-tools-api-faq/#idenotifier
}
type
TIdeNotifier = class(TNotifierObject, IOTANotifier, IOTAIDENotifier)
protected
procedure AfterCompile(Succeeded: Boolean);
procedure BeforeCompile(const Project: IOTAProject; var Cancel: Boolean);
procedure FileNotification(NotifyCode: TOTAFileNotification;
const FileName: string; var Cancel: Boolean);
end;
{$endif}
type
TDskForm = class(TForm)
edDskFileName: TEdit;
SpeedButton1: TSpeedButton;
OpenDialog1: TOpenDialog;
lbSectionsToKeep: TListBox;
lbDskSections: TListBox;
moDskFile: TMemo;
btnSave: TButton;
procedure btnSaveClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure SpeedButton1Click(Sender: TObject);
private
procedure GetSectionsToKeep;
function GetDskFileName: String;
procedure SetDskFileName(const Value: String);
function GetDskFile: Boolean;
protected
public
DskIni : TMemIniFile;
property DskFileName : String read GetDskFileName write SetDskFileName;
end;
var
NotifierIndex: Integer;
DskForm: TDskForm;
{$ifdef ForDPK}
procedure Register;
{$endif}
implementation
{$R *.DFM}
{$ifdef ForDPK}
procedure Register;
var
Services: IOTAServices;
begin
Services := BorlandIDEServices as IOTAServices;
Assert(Assigned(Services), 'IOTAServices not available');
NotifierIndex := Services.AddNotifier(TIdeNotifier.Create);
end;
{$endif}
procedure DskPopUp(FileName : String);
var
F : TDskForm;
begin
F := TDskForm.Create(Application);
try
F.DskFileName := FileName;
F.ShowModal;
finally
F.Free;
end;
end;
function TDskForm.GetDskFileName: String;
begin
Result := edDskFileName.Text;
end;
procedure TDskForm.SetDskFileName(const Value: String);
begin
edDskFileName.Text := Value;
if Assigned(DskIni) then
FreeAndNil(DskIni);
btnSave.Enabled := False;
DskIni := TMemIniFile.Create(DskFileName);
DskIni.ReadSections(lbDskSections.Items);
GetSectionsToKeep;
end;
procedure TDskForm.btnSaveClick(Sender: TObject);
begin
DskIni.UpdateFile;
end;
procedure TDskForm.FormCreate(Sender: TObject);
begin
lbSectionsToKeep.Items.Add('watches');
lbSectionsToKeep.Items.Add('breakpoints');
lbSectionsToKeep.Items.Add('addressbreakpoints');
if not IsLibrary then
DskFileName := ChangeFileExt(Application.ExeName, '.Dsk');
end;
procedure TDskForm.GetSectionsToKeep;
var
i,
Index : Integer;
SectionName : String;
begin
moDskFile.Lines.Clear;
for i := lbDskSections.Items.Count - 1 downto 0 do begin
SectionName := lbDskSections.Items[i];
Index := lbSectionsToKeep.Items.IndexOf(SectionName);
if Index < 0 then
DskIni.EraseSection(SectionName);
end;
DskIni.GetStrings(moDskFile.Lines);
btnSave.Enabled := True;
end;
function TDskForm.GetDskFile: Boolean;
begin
OpenDialog1.FileName := DskFileName;
Result := OpenDialog1.Execute;
if Result then
DskFileName := OpenDialog1.FileName;
end;
procedure TDskForm.SpeedButton1Click(Sender: TObject);
begin
GetDskFile;
end;
{$ifdef ForDPK}
procedure RemoveNotifier;
var
Services: IOTAServices;
begin
if NotifierIndex <> -1 then
begin
Services := BorlandIDEServices as IOTAServices;
Assert(Assigned(Services), 'IOTAServices not available');
Services.RemoveNotifier(NotifierIndex);
end;
end;
function MsgServices: IOTAMessageServices;
begin
Result := (BorlandIDEServices as IOTAMessageServices);
Assert(Result <> nil, 'IOTAMessageServices not available');
end;
procedure TIdeNotifier.AfterCompile(Succeeded: Boolean);
begin
end;
procedure TIdeNotifier.BeforeCompile(const Project: IOTAProject; var Cancel: Boolean);
begin
Cancel := False;
end;
procedure TIdeNotifier.FileNotification(NotifyCode: TOTAFileNotification;
const FileName: string; var Cancel: Boolean);
begin
Cancel := False;
// Note: The FileName passed below has an extension of '.$$$'
if NotifyCode = ofnProjectDesktopSave then
DskPopup(FileName);
end;
initialization
finalization
RemoveNotifier;
{$endif}
end.
哇。謝謝是一個非常聰明的解決方案我稍後會試一試。我喜歡簡單:比我預想的要容易得多。 – 2014-12-04 15:17:40
感謝您的編輯。按照討論,我在編輯後刪除了我的答案。 +1 – 2014-12-04 18:17:50
@ JeroenPluimers-Binck:我的歉意:似乎有關文件擴展名的文件傳回通知者 - 請參閱我的答案的更新部分。 – MartynA 2014-12-04 22:57:02
因爲現在的我,他們做中間人對HTTPS流量:http://stackoverflow.com/users/3990592/jeroen-pluimers-binck – 2014-12-04 09:14:01
OK,這是有道理的! – 2014-12-04 09:16:45