簡體   English   中英

delphi 7,FastMM4無法安裝解決方法

[英]delphi 7, FastMM4 cannot install work around

我正在使用來自sourceforge.net的使用FastMM4的應用程序。 因此,我在一開始FastMM4.pas添加到了uses子句中。 在應用程序中,我需要在FinalizeMemoryManager;之后運行batch文件FinalizeMemoryManager; unit FastMM4;finalizationunit FastMM4; 像這樣

  initialization
        RunInitializationCode;

  finalization
        {$ifndef PatchBCBTerminate}
        FinalizeMemoryManager;
        RunTheBatFileAtTheEnd; //my code here..calling a procedure
       {$endif}

 end.

那么我的RunTheBatFileAtTheEnd代碼是:

 procedure RunTheBatFileAtTheEnd;
 begin
 //some code here....
  sFilePaTh:=SysUtils.ExtractFilePath(applicaTname)+sFileNameNoextension+'_log.nam';
 ShellExecute(applcatiOnHAndle,'open', pchar(sExeName),pchar(sFilePaTh), nil, SW_SHOWNORMAL) ;
 end;

為此,我需要使用SysUtils,shellapi fastmm4單元的uses子句。 但是使用這些消息 在此處輸入圖片說明

但是,如果我從使用中刪除SysUtils,shellapi ,它就會起作用。 我仍然需要安裝fastmm4的所有功能,但是使用SysUtils,shellapi ,shellapi時,不會安裝fastmm4

我有一個自己的單元,但是它的完成是在fastmm4結束之前執行的。

誰能告訴我如何解決這個問題?

編輯-1

unit FastMM4;
//...
...
implementation

 uses
   {$ifndef Linux}Windows,{$ifdef FullDebugMode}{$ifdef Delphi4or5}ShlObj,{$else}
  SHFolder,{$endif}{$endif}{$else}Libc,{$endif}FastMM4Messages,SysUtils,shellapi;

我的應用程序

 program memCheckTest;
   uses
      FastMM4,

編輯2:

(在@SertacAkyuz回答之后),我刪除了SysUtils並起作用,但是我仍然需要運行批處理文件以通過RunTheBatFileAtTheEnd打開外部應用程序。 原因是..i我希望外部應用程序僅在FastMM4之后才能運行,因為finalization尚未finalization sExeName是將運行文件sFilePaTh (.nam)的應用程序。 誰能告訴我該怎么做? 無需uninstalling FastMM4

FastMM在調用“ system.pas”中的IsMemoryManagerSet函數進行安裝之前,檢查默認內存管理器是否已設置。 如果設置了默認的內存管理器,它將拒絕設置自己的內存管理器,並顯示問題中顯示的消息。

該消息中有關“ fastmm4.pas”的指令應該是項目的.dpr文件中的第一單元,並假設“ fastmm4.pas”本身未修改。

當您修改“ fastmm4.pas”的uses子句時,如果uses子句中包含的任何單元都有一個initialization部分,則該代碼部分必須在“ fastmm4.pas”的初始化部分之前運行。 如果該代碼需要通過RTL分配/接收內存,則會設置默認的內存管理器。

因此,您必須小心更改“ fastmm4.pas”,以使其在uses子句中不包含任何此類單元,例如“ sysutils.pas”。


下面的示例代碼(無錯誤檢查,文件檢查等)顯示了如何在不分配任何內存的情況下使用記事本啟動FastMM的日志文件(前提是該日志文件存在):

var
  CmdLine: array [0..300] of Char; // increase as needed
  Len: Integer;
  SInfo: TStartupInfo;
  PInfo: TProcessInformation;

initialization
  ...  // fastmm code

finalization
{$ifndef PatchBCBTerminate}
  FinalizeMemoryManager;       // belongs to fastmm

  // Our application is named 'Notepad' and the path is defined in AppPaths
  CmdLine := 'Notepad "';  // 9 Chars (note the opening quote)
  Len := windows.GetModuleFileName(0, PChar(@CmdLine[9]), 260) + 8;

  // assumes the executable has an extension.
  while CmdLine[Len] <> '.' do
    Dec(Len);

  CmdLine[Len] := #0;
  lstrcat(CmdLine, '_MemoryManager_EventLog.txt"'#0); // note the closing quote

  ZeroMemory(@SInfo, SizeOf(SInfo));
  SInfo.cb := SizeOf(SInfo);
  CreateProcess(nil, CmdLine, nil, nil, False,
                NORMAL_PRIORITY_CLASS, nil, nil, sInfo, pInfo);

{$endif}

end.

我同意Sertac的答案,但也想給一個建議,如果你堅持要用SysUtils.pas 答案是不要使用它,然后從中提取所需的內容並將其放入自己的副本中。 下面是你會在下面所需要的- ExtractFilePath使用LastDeliminator ,它使用StrScan ,而且2常數,所以我復制他們到這個新單元,並將其命名MySysUtils.pas

對於不想編譯一堆他們永遠不會使用的額外代碼的人,它也得到了廣泛的使用(不過,您必須絕對確保它不會在任何單元中的任何地方使用)。

unit MySysUtils;

interface

const
  PathDelim = '\';
  DriveDelim = ':';

implementation

function StrScan(const Str: PWideChar; Chr: WideChar): PWideChar;
begin
  Result := Str;
  while Result^ <> #0 do begin
    if Result^ = Chr then
      Exit;
    Inc(Result);
  end;
  if Chr <> #0 then
    Result := nil;
end;

function LastDelimiter(const Delimiters, S: string): Integer;
var
  P: PChar;
begin
  Result := Length(S);
  P := PChar(Delimiters);
  while Result > 0 do begin
    if (S[Result] <> #0) and (StrScan(P, S[Result]) <> nil) then
      Exit;
    Dec(Result);
  end;
end;

function ExtractFilePath(const FileName: string): string;
var
  I: Integer;
begin
  I := LastDelimiter(PathDelim + DriveDelim, FileName);
  Result := Copy(FileName, 1, I);
end;

end.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM