J'ai écrit un utilitaire qui recherche les fichiers journaux pour les exceptions et il a bien fonctionné avec Vista 64 bits. Maintenant, j'ai mis à niveau vers Windows 7 64 bits et il pourrait parfois être suspendu à jamais lors de la lecture d'un flux de fichiers. Je pense que cela ne se bloque que si le fichier journal est actif et que l'utilisateur y écrit. Mais cela fonctionne bien avant que j'utilise le drapeau fmShareDenyNone. J'utilise Delphi 2007. Avez-vous une idée de ce que je pourrais changer pour que cela fonctionne?Comportement modifié pour filestream avec Windows 7?
Voici toute la méthode qui recherche dans les répertoires pour les fichiers journaux:
procedure TfrmMain.Refresh;
var
FileData : TSearchRec; // Used for the file searching. Contains data of the file
vPos, i, PathIndex : Integer;
vCurrentFile: TStringList;
vDate: TDateTime;
vFileStream: TFileStream;
begin
tvMain.DataController.RecordCount := 0;
vCurrentFile := TStringList.Create;
memCallStack.Clear;
try
for PathIndex := 0 to fPathList.Count - 1 do // Loop 0. This loops until all directories are searched through
begin
if (FindFirst (fPathList[PathIndex] + '\*.log', faAnyFile, FileData) = 0) then
repeat // Loop 1. This loops while there are .log files in Folder (CurrentPath)
vDate := FileDateToDateTime(FileData.Time);
if chkLogNames.Items[PathIndex].Checked and FileDateInInterval(vDate) then
begin
tvMain.BeginUpdate; // To speed up the grid - delays the guichange until EndUpdate
fPathPlusFile := fPathList[PathIndex] + '\' + FileData.Name;
vFileStream := TFileStream.Create(fPathPlusFile, fmShareDenyNone);
vCurrentFile.LoadFromStream(vFileStream);
fUser := FindDataInRow(vCurrentFile[0], 'User'); // FindData Returns the string after 'User' until ' '
fComputer := FindDataInRow(vCurrentFile[0], 'Computer'); // FindData Returns the string after 'Computer' until ' '
Application.ProcessMessages; // Give some priority to the User Interface
if not CancelForm.IsCanceled then
begin
CancelForm.lblLogFile.Caption := fPathPlusFile;
if rdException.Checked then
for i := 0 to vCurrentFile.Count - 1 do
begin
vPos := AnsiPos(MainExceptionToFind, vCurrentFile[i]);
if vPos > 0 then
UpdateView(vCurrentFile[i], i, MainException);
vPos := AnsiPos(ExceptionHintToFind, vCurrentFile[i]);
if vPos > 0 then
UpdateView(vCurrentFile[i], i, HintException);
end
else if rdOtherText.Checked then
for i := 0 to vCurrentFile.Count - 1 do
begin
vPos := AnsiPos(txtTextToSearch.Text, vCurrentFile[i]);
if vPos > 0 then
UpdateView(vCurrentFile[i], i, TextSearch)
end
end;
vFileStream.Destroy;
tvMain.EndUpdate; // Now the Gui can be updated
end;
until(FindNext(FileData) <> 0) or (CancelForm.IsCanceled); // End Loop 1
end; // End Loop 0
finally
FreeAndNil(vCurrentFile);
end;
end;
La première chose que vous devriez faire ici est de refactoriser le code de l'interface utilisateur de la logique actuelle. Débarrassez-vous de tvMain, UpdateView, memCallStack, Application.ProcessMessages, CancelForm, FindDataInRow. Le code résultant devrait être beaucoup plus court et plus facile à reproduire. –
Oui, je suis d'accord là-dessus. Cela a commencé comme un outil rapide et sale au lieu de chercher des logdirs manuellement. Mais il a évolué pour être utile à la fois pour les développeurs et le support. –
Lorsque votre application semble se bloquer, appuyez sur le bouton "pause" dans le débogueur pour savoir exactement où il est accroché. Vous avez dit qu'il se bloque pendant la lecture d'un flux de fichiers, mais vous parlez du mode de partage. Si le partage était plus pertinent, alors votre programme se bloquerait en * ouvrant * le fichier, pas en le lisant. La pile d'appel de votre programme en pause vous dira où cela se produit. –