delphi 7, FastMM4 nu poate instala o soluție de lucru (Programare, Delphi, Delphi 7, Fastmm)

PresleyDias a intrebat.
a intrebat.

lucrez la o aplicație care utilizează FastMM4, , din sourceforge.net.așa că am adăugat FastMM4.pas la clauza uses chiar la început. În aplicație trebuie să execut o aplicație batch după FinalizeMemoryManager; în instrucțiunea finalization din unit FastMM4; în felul următor

  initialization
        RunInitializationCode;

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

 end.

apoi codul meu pentru RunTheBatFileAtTheEnd este :

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

Pentru aceasta am nevoie să folosesc SysUtils,shellapi în clauza uses a unității fastmm4. Dar folosind acest mesaj apare acest mesaj

Dar dacă înlătur SysUtils,shellapi din uses funcționează.Am nevoie în continuare de toate caracteristicile fastmm4 instalate, dar cu SysUtils,shellapi, , fastmm4 nu este instalat

Am o unitate proprie dar finalizarea ei este executată înainte de finalizarea fastmm4.

îmi poate spune cineva poate cum să rezolv această problemă?

EDIT- 1

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

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

aplicația mea

 program memCheckTest;
   uses
      FastMM4,

EDIT-2 :

(după răspunsul lui @SertacAkyuz),am eliminat SysUtils și a funcționat , dar încă trebuie să execut fișierul batch pentru a deschide o aplicație externă prin intermediul RunTheBatFileAtTheEnd. Motivul este ..vreau o aplicație externă pentru a rula numai după ce FastMM4 ca a fost din finalization. sExeName este aplicația care va rula fișierul sFilePaTh(.nam) . poate cineva să spună cum se poate face acest lucru? fără uninstalling FastMM4.

Comentarii

  • Ce clauză de utilizare? Dacă în interfață, faceți ca FastMM4 să depindă de ele și acestea vor fi inițializate primele, inclusiv toate unitățile de care depind. Orice alocare de memorie făcută acolo ar provoca acest lucru. Ați încercat să mutați cele două unități în clauza de implementare? Acest lucru ar trebui să schimbe ordinea de dependență. –  > Por Marjan Venema.
  • @MarjanVenema : am adăugat un nou cod pentru clauza uses, SysUtils,shellapi; sunt în implementation –  > Por PresleyDias.
  • Trebuie să vă descurcați fără ‘sysutils’. Codul din secțiunea de inițializare a ‘sysutils’ are nevoie de alocarea memoriei, prin urmare trebuie setat managerul de memorie. –  > Por Sertac Akyuz.
  • @SertacAkyuz ok, deci sysutils este problema, voi încerca ceva –  > Por PresleyDias.
2 răspunsuri
Sertac Akyuz

FastMM verifică dacă managerul de memorie implicit este setat înainte de a-și instala propriul manager de memorie printr-un apel la IsMemoryManagerSet funcție în ‘system.pas’. Dacă este setat managerul de memorie implicit, refuză să își instaleze propriul manager de memorie și afișează mesajul prezentat în întrebare.

Instrucțiunea din acest mesaj despre ‘fastmm4.pas’ ar trebui să fie prima unitate din fișierul .dpr al proiectului. presupune că „fastmm4.pas” nu este modificat.

Atunci când modificați clauza uses din „fastmm4.pas”, dacă una dintre unitățile incluse în clauza uses are un initialization atunci acea secțiune de cod trebuie să fie executată înainte de secțiunea de inițializare din „fastmm4.pas”. În cazul în care codul respectiv necesită alocarea/alocarea de memorie prin RTL, atunci se stabilește managerul de memorie implicit.

Prin urmare, trebuie să aveți grijă ca, în cazul în care modificați „fastmm4.pas”, să nu includeți o astfel de unitate în clauza uses, cum ar fi „sysutils.pas”.


Exemplul de cod de mai jos (fără verificarea erorilor, verificarea fișierelor etc.) arată cum puteți lansa fișierul jurnal al FastMM cu Notepad (cu condiția ca fișierul jurnal să existe) fără a aloca memorie:

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.

Comentarii

  • am nevoie de sFilePaTh:=SysUtils.ExtractFilePath(applicaTname) pe care nu o pot obține fără SysUtils deci există vreo modalitate de a obține calea fișierului de aplicație? (chiar și `application.exe’). –  > Por PresleyDias.
  • ok..Întrebare: Notepad " numele aplicației mele este tracker.exe cum îl scriu în loc de Notepad "? –  > Por PresleyDias.
  • @Presley – Mai bine folosiți calea completă. Numărați caracterele, ca în răspuns. CmdLine:='C:somefoldertracker.exe ", , care a folosit 27 de caractere, atunci Len:=GetModuleFileName(0,PChar(@CmdLine[27]),..). Măriți dimensiunea CmdLine pentru a lua în considerare spațiul pentru utilizarea crescută: var CmdLine:array[0..350] of Char etc.. Folosiți debuggerul pentru a urmări modul în care se acumulează CmdLine… –  > Por Sertac Akyuz.
  • tocmai am încercat funcționează cu calea hardcoded dar cum obțin calea aplicației mele (calea de instalare) deoarece nu pot folosi registrul..cum?????? –  > Por PresleyDias.
  • @Presley – O opțiune este să înregistrați aplicația în cheia ‘App Paths’ sau în calea de mediu (link), astfel încât să nu fie nevoie să o găsiți. O alta poate fi să încerci să folosești direct api-ul funcțiile de registru, , dar cred că nu este posibil să lucrezi mai multe detalii în comentarii. –  > Por Sertac Akyuz.
Jerry Dodge

Sunt de acord cu răspunsul lui Sertac, dar, de asemenea, aș dori să dau o recomandare, dacă insistați să utilizați SysUtils.pas. Răspunsul este să nu-l folosiți, și să extrageți ceea ce aveți nevoie din el și să-l puneți în propria copie. Iată de ce ați avea nevoie mai jos – ExtractFilePath folosit LastDeliminator, , care a folosit StrScan, , și, de asemenea, 2 constante, așa că le-am copiat în această nouă unitate și am numit-o MySysUtils.pas.

Acest lucru este, de asemenea, utilizat pe scară largă pentru persoanele care nu doresc să aibă o grămadă de cod suplimentar compilat pe care nu îl vor folosi niciodată (Ar trebui să fiți absolut sigur că nu este utilizat nicăieri în nicio unitate, totuși).

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.

Comentarii

  • +1, hei, mare truc.!!! dar cum rămâne cu Application.ExeName utilizări forms.pas și voi avea în continuare aceeași problemă cu Fastmm4 care nu se instalează , deci ce să fac în acest caz? pentru a obține Application.ExeName –  > Por PresleyDias.
  • @Presley – Poți folosi ‘GetModuleFileName’, deoarece asta este ceea ce folosește VCL pentru ParamStr(0). Vedeți acest răspuns pentru un exemplu de implementare (puteți utiliza versiunea ansi a funcției). –  > Por Sertac Akyuz.
  • @SertacAkyuz ok, dar cred că ai ratat link-ul –  > Por PresleyDias.
  • Pur și simplu nu văd posibilitatea de a face astfel de apeluri, care necesită utilizarea memoriei, înainte ca FastMM să fie inițializat. Mă scarpin în cap încercând să înțeleg de ce trebuie să pui acest tip de cod în FastMM4.pas. –  > Por Jerry Dodge.
  • @JerryDodge : încerc să fac o aplicație care să deschidă log fișier pe care l-am creat prin fastmm4 care se întâmplă să fie creat după ce în FinalizeMemoryManager (în finalizare)…vreau ca aplicația mea să apară și să arate fișierul log fișier, dar cred că acest lucru este posibil doar după FinalizeMemoryManager a finalizat execuția….mă puteți ajuta cum să execut aplicația mea după ce FinalizeMemoryManager? –  > Por PresleyDias.