mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-21 09:58:13 +00:00
ADD: Feature [0001762] Show the processes, which lock the file from deletion #2
This commit is contained in:
parent
0d6cb0ceb1
commit
3516f8d117
6 changed files with 251 additions and 5 deletions
|
|
@ -284,7 +284,7 @@ end;"/>
|
|||
<MinVersion Minor="3" Valid="True"/>
|
||||
</Item12>
|
||||
</RequiredPackages>
|
||||
<Units Count="238">
|
||||
<Units Count="239">
|
||||
<Unit0>
|
||||
<Filename Value="doublecmd.lpr"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
|
|
@ -1716,6 +1716,12 @@ end;"/>
|
|||
<ResourceBaseClass Value="Form"/>
|
||||
<UnitName Value="fViewOperations"/>
|
||||
</Unit237>
|
||||
<Unit238>
|
||||
<Filename Value="ffileunlock.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<HasResources Value="True"/>
|
||||
<UnitName Value="fFileUnlock"/>
|
||||
</Unit238>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
|
|
|
|||
97
src/ffileunlock.lfm
Normal file
97
src/ffileunlock.lfm
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
object frmFileUnlock: TfrmFileUnlock
|
||||
Left = 326
|
||||
Height = 342
|
||||
Top = 203
|
||||
Width = 638
|
||||
BorderIcons = [biSystemMenu, biMaximize]
|
||||
Caption = 'Unlock'
|
||||
ChildSizing.LeftRightSpacing = 12
|
||||
ChildSizing.TopBottomSpacing = 12
|
||||
ClientHeight = 342
|
||||
ClientWidth = 638
|
||||
Position = poOwnerFormCenter
|
||||
LCLVersion = '1.8.4.0'
|
||||
object stgFileHandles: TStringGrid
|
||||
AnchorSideLeft.Control = Owner
|
||||
AnchorSideTop.Control = Owner
|
||||
AnchorSideRight.Control = Owner
|
||||
AnchorSideRight.Side = asrBottom
|
||||
AnchorSideBottom.Control = btnClose
|
||||
Left = 12
|
||||
Height = 281
|
||||
Top = 12
|
||||
Width = 614
|
||||
Anchors = [akTop, akLeft, akRight, akBottom]
|
||||
AutoFillColumns = True
|
||||
BorderSpacing.Top = 12
|
||||
BorderSpacing.Bottom = 12
|
||||
ColCount = 3
|
||||
Columns = <
|
||||
item
|
||||
SizePriority = 0
|
||||
Title.Caption = 'File Handle'
|
||||
Width = 100
|
||||
end
|
||||
item
|
||||
SizePriority = 0
|
||||
Title.Caption = 'Process ID'
|
||||
Width = 100
|
||||
end
|
||||
item
|
||||
Title.Caption = 'Executable Path'
|
||||
Width = 413
|
||||
end>
|
||||
FixedCols = 0
|
||||
Flat = True
|
||||
Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goRowSelect, goSmoothScroll]
|
||||
TabOrder = 0
|
||||
OnSelection = stgFileHandlesSelection
|
||||
ColWidths = (
|
||||
100
|
||||
100
|
||||
413
|
||||
)
|
||||
end
|
||||
object btnUnlockAll: TButton
|
||||
AnchorSideTop.Side = asrBottom
|
||||
AnchorSideRight.Control = btnClose
|
||||
AnchorSideBottom.Control = btnClose
|
||||
AnchorSideBottom.Side = asrBottom
|
||||
Left = 464
|
||||
Height = 25
|
||||
Top = 305
|
||||
Width = 75
|
||||
Anchors = [akRight, akBottom]
|
||||
BorderSpacing.Right = 12
|
||||
Caption = 'Unlock All'
|
||||
OnClick = btnUnlockAllClick
|
||||
TabOrder = 1
|
||||
end
|
||||
object btnUnlock: TButton
|
||||
AnchorSideTop.Control = btnUnlockAll
|
||||
AnchorSideRight.Control = btnUnlockAll
|
||||
Left = 377
|
||||
Height = 25
|
||||
Top = 305
|
||||
Width = 75
|
||||
Anchors = [akTop, akRight]
|
||||
BorderSpacing.Right = 12
|
||||
Caption = 'Unlock'
|
||||
OnClick = btnUnlockClick
|
||||
TabOrder = 2
|
||||
end
|
||||
object btnClose: TButton
|
||||
AnchorSideRight.Control = Owner
|
||||
AnchorSideRight.Side = asrBottom
|
||||
AnchorSideBottom.Control = Owner
|
||||
AnchorSideBottom.Side = asrBottom
|
||||
Left = 551
|
||||
Height = 25
|
||||
Top = 305
|
||||
Width = 75
|
||||
Anchors = [akRight, akBottom]
|
||||
Caption = 'Close'
|
||||
ModalResult = 11
|
||||
TabOrder = 3
|
||||
end
|
||||
end
|
||||
9
src/ffileunlock.lrj
Normal file
9
src/ffileunlock.lrj
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
{"version":1,"strings":[
|
||||
{"hash":96810395,"name":"tfrmfileunlock.caption","sourcebytes":[85,110,108,111,99,107],"value":"Unlock"},
|
||||
{"hash":78334293,"name":"tfrmfileunlock.stgfilehandles.columns[0].title.caption","sourcebytes":[70,105,108,101,32,72,97,110,100,108,101],"value":"File Handle"},
|
||||
{"hash":164572548,"name":"tfrmfileunlock.stgfilehandles.columns[1].title.caption","sourcebytes":[80,114,111,99,101,115,115,32,73,68],"value":"Process ID"},
|
||||
{"hash":165250008,"name":"tfrmfileunlock.stgfilehandles.columns[2].title.caption","sourcebytes":[69,120,101,99,117,116,97,98,108,101,32,80,97,116,104],"value":"Executable Path"},
|
||||
{"hash":93881116,"name":"tfrmfileunlock.btnunlockall.caption","sourcebytes":[85,110,108,111,99,107,32,65,108,108],"value":"Unlock All"},
|
||||
{"hash":96810395,"name":"tfrmfileunlock.btnunlock.caption","sourcebytes":[85,110,108,111,99,107],"value":"Unlock"},
|
||||
{"hash":4863637,"name":"tfrmfileunlock.btnclose.caption","sourcebytes":[67,108,111,115,101],"value":"Close"}
|
||||
]}
|
||||
116
src/ffileunlock.pas
Normal file
116
src/ffileunlock.pas
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
unit fFileUnlock;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
|
||||
Grids, uFileUnlock;
|
||||
|
||||
type
|
||||
|
||||
{ TfrmFileUnlock }
|
||||
|
||||
TfrmFileUnlock = class(TForm)
|
||||
btnUnlockAll: TButton;
|
||||
btnUnlock: TButton;
|
||||
btnClose: TButton;
|
||||
stgFileHandles: TStringGrid;
|
||||
procedure btnUnlockAllClick(Sender: TObject);
|
||||
procedure btnUnlockClick(Sender: TObject);
|
||||
procedure stgFileHandlesSelection(Sender: TObject; aCol, aRow: Integer);
|
||||
private
|
||||
procedure ShowThread;
|
||||
procedure UnlockRow(Index: Integer);
|
||||
public
|
||||
|
||||
end;
|
||||
|
||||
function ShowUnlockForm(ProcessInfo: TProcessInfoArray): Boolean;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
Windows, Math, fMain;
|
||||
|
||||
function ShowUnlockForm(ProcessInfo: TProcessInfoArray): Boolean;
|
||||
var
|
||||
Index: Integer;
|
||||
UnlockEnabled: Boolean = False;
|
||||
begin
|
||||
with TfrmFileUnlock.Create(frmMain) do
|
||||
try
|
||||
stgFileHandles.RowCount:= Length(ProcessInfo) + 1;
|
||||
|
||||
for Index:= 1 to stgFileHandles.RowCount - 1 do
|
||||
begin
|
||||
if (ProcessInfo[Index - 1].FileHandle <> 0) then begin
|
||||
UnlockEnabled:= True;
|
||||
stgFileHandles.Cells[0, Index]:= IntToStr(ProcessInfo[Index - 1].FileHandle);
|
||||
end;
|
||||
stgFileHandles.Cells[1, Index]:= IntToStr(ProcessInfo[Index - 1].ProcessId);
|
||||
stgFileHandles.Cells[2, Index]:= ProcessInfo[Index - 1].ExecutablePath;
|
||||
end;
|
||||
btnUnlockAll.Enabled:= UnlockEnabled;
|
||||
stgFileHandles.Row:= IfThen(UnlockEnabled, 1, 0);
|
||||
|
||||
TThread.Synchronize(nil, @ShowThread);
|
||||
|
||||
Result:= (ModalResult = mrOK);
|
||||
finally
|
||||
Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
{$R *.lfm}
|
||||
|
||||
{ TfrmFileUnlock }
|
||||
|
||||
procedure TfrmFileUnlock.stgFileHandlesSelection(Sender: TObject; aCol, aRow: Integer);
|
||||
begin
|
||||
btnUnlock.Enabled:= Length(stgFileHandles.Cells[0, aRow]) > 0;
|
||||
end;
|
||||
|
||||
procedure TfrmFileUnlock.btnUnlockClick(Sender: TObject);
|
||||
begin
|
||||
UnlockRow(stgFileHandles.Row);
|
||||
if (stgFileHandles.RowCount = 1) then
|
||||
begin
|
||||
Close;
|
||||
ModalResult:= mrOK;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TfrmFileUnlock.btnUnlockAllClick(Sender: TObject);
|
||||
var
|
||||
Index: Integer;
|
||||
begin
|
||||
for Index:= stgFileHandles.RowCount - 1 downto 1 do
|
||||
begin
|
||||
UnlockRow(Index);
|
||||
end;
|
||||
if (stgFileHandles.RowCount = 1) then
|
||||
begin
|
||||
Close;
|
||||
ModalResult:= mrOK;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TfrmFileUnlock.ShowThread;
|
||||
begin
|
||||
ShowModal;
|
||||
end;
|
||||
|
||||
procedure TfrmFileUnlock.UnlockRow(Index: Integer);
|
||||
var
|
||||
ProcessId: DWORD;
|
||||
FileHandle: HANDLE;
|
||||
begin
|
||||
ProcessId:= StrToDWord(stgFileHandles.Cells[1, Index]);
|
||||
FileHandle:= StrToQWord(stgFileHandles.Cells[0, Index]);
|
||||
if FileUnlock(ProcessId, FileHandle) then stgFileHandles.DeleteRow(Index);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
|
@ -61,7 +61,7 @@ implementation
|
|||
uses
|
||||
DCOSUtils, uLng, uFileSystemUtil, uTrash, uAdministrator, uOSUtils
|
||||
{$IF DEFINED(MSWINDOWS)}
|
||||
, uFileUnlock
|
||||
, Windows, uFileUnlock, fFileUnlock
|
||||
{$ENDIF}
|
||||
;
|
||||
|
||||
|
|
@ -343,12 +343,22 @@ begin
|
|||
end;
|
||||
|
||||
if AdministratorPrivileges then
|
||||
PossibleResponses:= ResponsesError
|
||||
begin
|
||||
SetLength(PossibleResponses, Length(ResponsesError));
|
||||
Move(ResponsesError[0], PossibleResponses[0], SizeOf(ResponsesError));
|
||||
end
|
||||
else begin
|
||||
SetLength(PossibleResponses, Length(ResponsesError) + 1);
|
||||
Move(ResponsesError[0], PossibleResponses[0], SizeOf(ResponsesError));
|
||||
PossibleResponses[High(PossibleResponses)]:= fsourRetryAdmin;
|
||||
end;
|
||||
{$IF DEFINED(MSWINDOWS)}
|
||||
if (Length(ProcessInfo) > 0) or (LastError = ERROR_ACCESS_DENIED) or (LastError = ERROR_SHARING_VIOLATION) then
|
||||
begin
|
||||
SetLength(PossibleResponses, Length(PossibleResponses) + 1);
|
||||
PossibleResponses[High(PossibleResponses)]:= fsourUnlock;
|
||||
end;
|
||||
{$ENDIF}
|
||||
case AskQuestion(sQuestion, '',
|
||||
PossibleResponses,
|
||||
fsourRetry, fsourAbort) of
|
||||
|
|
@ -360,9 +370,17 @@ begin
|
|||
RaiseAbortOperation;
|
||||
fsourRetryAdmin:
|
||||
Exit(False);
|
||||
{$IF DEFINED(MSWINDOWS)}
|
||||
fsourUnlock:
|
||||
begin
|
||||
bRetry:= True;
|
||||
GetFileInUseProcessSlow(FileName, LastError, ProcessInfo);
|
||||
ShowUnlockForm(ProcessInfo);
|
||||
end;
|
||||
{$ENDIF}
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
until bRetry = False;
|
||||
end;
|
||||
|
||||
|
|
|
|||
|
|
@ -316,8 +316,8 @@ resourcestring
|
|||
rsNoEquivalentInternalCommand = 'No internal equivalent command';
|
||||
|
||||
// Locked by another process
|
||||
rsMsgProcessId = 'Process: %d';
|
||||
rsMsgApplicationName = 'Application: %s';
|
||||
rsMsgProcessId = 'PID: %d';
|
||||
rsMsgApplicationName = 'Description: %s';
|
||||
rsMsgExecutablePath = 'Executable: %s';
|
||||
rsMsgOpenInAnotherProgram = 'The action cannot be completed because the file is open in another program:';
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue