Làm thế nào để đóng tất cả các thẻ điều khiển trong một thư mục nhất định theo chương trình?


18

Tôi đã tự hỏi nếu có một công cụ dòng lệnh cho phép tôi đóng tất cả các thẻ xử lý đang mở trong một thư mục cụ thể.

Tôi đã thử ProcessExplorer , Unlocker và các công cụ tương tự, nhưng chúng cung cấp giao diện GUI và không hữu ích trong môi trường lập trình

Một giải pháp trên Python, cmd hoặc PowerShell sẽ là lý tưởng.


Hãy nhớ rằng việc đóng một tập tin xử lý có thể khiến chương trình sử dụng xử lý đó bị sập.
Harry Johnston

1
@HarryJohnston Tệ hơn nữa, cuối cùng bạn có thể gây ra tất cả các loại tham nhũng tệp miễn là chương trình được mở: technet.microsoft.com/en-us/magazine/ Lỗi
Bob

Câu trả lời:


7

Unlocker không yêu cầu nó cung cấp cho bạn khả năng này:

  1. Chỉ cần nhấp chuột phải vào thư mục hoặc tệp và chọn Unlocker

    Bước 1

  2. Nếu thư mục hoặc tập tin bị khóa, một danh sách cửa sổ của tủ khóa sẽ xuất hiện

    Bước 2

  3. Đơn giản chỉ cần nhấp Unlock Allvà bạn đã hoàn tất!

Tôi không chắc nếu nó hỗ trợ sử dụng dòng lệnh.

FileAssassin của MalwareByte thực hiện các hành động tương tự và không hỗ trợ sử dụng dòng lệnh, do đó bạn có thể viết kịch bản khá dễ dàng.

Chuyển mạch FileAssassinin


Cảm ơn techie007, tôi đoán tôi đã bỏ lỡ điều đó. Tôi nhận thấy rằng Unlocker đôi khi bỏ lỡ các tệp của tôi (ProcessExplorer không) .. Vấn đề thứ hai là nếu tôi muốn mở khóa hoặc phát hành tệp theo chương trình (ví dụ: công cụ dòng lệnh sẽ giúp theo hướng này).
Amelio Vazquez-Reina

@intrpc Có ya đi, tôi đã thêm một đề xuất (thân thiện với dòng lệnh). :)
cʜιᴇ007

1
Cẩn thận, Unlocker đi kèm với phần mềm độc hại những ngày này.
Joshua Hanley

10

Cảm ơn vì điều đó. Chúng tôi đã gặp một số vấn đề với việc xử lý tệp mở khiến việc kiểm tra git không thành công trong các công việc Jenkins dựa trên Windows của chúng tôi và điều này đã giúp khắc phục vấn đề một cách cẩn thận. Tôi sẽ đưa ra những điều cơ bản của kỹ thuật:

  1. Cài đặt Handle.exe trên nút xây dựng. Tôi đã tải xuống từ đây http://technet.microsoft.com/en-us/sysiternals/bb896655 , giải nén nó và bỏ Hand.exe trong C: \ Windows \ System32 để đảm bảo nó sẽ có sẵn trên% PATH% mặc định

  2. Cài đặt plugin pre-scm-buildstep của Jenkins: https://wiki.jenkins-ci.org/display/JENKINS/pre-scm-buildstep . Điều này cho phép chúng tôi xác định các hoạt động trước khi plugin git bắt đầu tiếp cận với các tệp có khả năng bị khóa.

  3. Đã triển khai lệnh batch sau đây như một bước xây dựng trước scm:

    @echo off
    echo Cleaning up open file handles from %NODE_NAME%:%WORKSPACE%...
    for /f "tokens=3,6,8 delims=: " %%i in ('Handle /accepteula %WORKSPACE% ^| grep workspace') do echo Releasing file lock on E:%%k & handle -c %%j -y -p %%i
    

Nó dường như hoạt động độc đáo và chắc chắn cắt giảm các thất bại giả. Tôi cũng sẽ lưu ý một vài vấn đề tôi đã làm qua:

  • Handler.exe có EULA phải được chấp nhận lần đầu tiên chạy. Nếu bạn đang điều hành đại lý Jenkins của mình dưới dạng dịch vụ trong bối cảnh Hệ thống cục bộ, thì đây là vấn đề vì bạn không thể đăng nhập với tư cách người dùng đó và chấp nhận bằng tay. Khi chúng tôi thử chạy nó từ công việc Jenkins, quá trình chỉ chờ đợi đầu vào của người dùng và phải mất vài phút để tìm hiểu lý do tại sao. Tôi đã giải quyết điều này bằng cách chạy nó từ công việc Jenkins bằng cách sử dụng cờ / accepteula và tôi khuyên mọi người thực hiện điều này như một quy trình tự động cũng làm như vậy. Đây có thể là cài đặt đăng ký trong HKEY_CURRENT_USER \ Software \ Sysiternals \ Xử lý và bạn cũng có thể đặt và hủy cài đặt thông qua regedit.exe nếu bạn cần thao tác với người dùng cụ thể, nhưng tùy chọn dòng lệnh có vẻ dễ nhất.

  • Plugin bước Jenkins Batch thực thi mã hàng loạt như thể nó nằm trong một tập lệnh chứ không phải là một lệnh dòng lệnh. Lưu ý các lối thoát (ví dụ: %% i, ^ |).

Cảm ơn!


Đấu tranh để có được cú pháp của điều này, ai đó có thể cung cấp chi tiết hơn về những gì %% i, j vv không?
c4sh

Điều này có thể giúp hiểu cú pháp của lệnh batch: robvanderwoude.com/ntfortokens.php
c4sh

Làm thế nào các bạn giải quyết được thực tế là handle.exe cần phải chạy với tư cách quản trị viên, trong khi chúng tôi chạy nó từ một người dùng Jenkins không phải là quản trị viên?
c4sh

8

Chúng tôi sử dụng đoạn mã sau để đóng xử lý tệp từ người dùng đến máy chủ của chúng tôi. Bạn có thể sửa đổi nó để sử dụng.

rem close all network files that are locked
for /f "skip=4 tokens=1" %%a in ('net files') do net files %%a /close

Cảm ơn @Brendan. Tôi nghĩ rằng mã của bạn không được định dạng đúng. Câu trả lời của bạn có vẻ thú vị, vì vậy nếu bạn không phiền khi chỉnh sửa nó, tôi sẽ đề nghị bạn chọn các dòng mã của mình, sau đó nhấp vào nút có hai vòng đeo tay xoăn. Điều đó sẽ biến đoạn mã của bạn thành mã có thể đọc được.
Amelio Vazquez-Reina

5

Tôi tạo tệp bó nhỏ này để tự động giải phóng tất cả các khóa vào tệp xml bằng nhật thực của tôi

@echo off
for /f "tokens=3,6,8 delims=: " %%i in ('handle -p eclipse e:\git\ ^| grep .xml') do echo Releasing %%k & handle -c %%j -y -p %%i

Bạn cần tải xuống tiện ích xử lý từ trang web Microsoft và tiện ích grep từ GnuWin32

Nếu bạn không cần bộ lọc theo loại tệp, bạn có thể bỏ qua phần grep như thế này:

@echo off
for /f "tokens=3,6,8 delims=: " %%i in ('handle -p eclipse e:\git\') do echo Releasing %%k & handle -c %%j -y -p %%i

Hoặc nếu bạn không cần lọc các khóa theo một chương trình cụ thể, chỉ cần xóa bộ lọc quy trình nhật thực:

@echo off
for /f "tokens=3,6,8 delims=: " %%i in ('handle e:\git\') do echo Releasing %%k & handle -c %%j -y -p %%i

Hãy nhớ thay thế e:\git\bằng đường dẫn thư mục của bạn.


4

Nếu bạn đang sử dụng PSTools , điều này sẽ buộc đóng tất cả các tệp đang mở theo cách đệ quy:

psfile \\serverName c:\path\toDatabase\ -c

Lưu ý rằng đó c:\path\toDatabase\là ổ C: \\serverNamekhông phải máy cục bộ của bạn. Điều này ban đầu không rõ ràng với tôi nên tôi nghĩ tôi đã chỉ ra điều đó.

Đây là một cách tiếp cận bạo lực gần như được đảm bảo để mất dữ liệu, vì vậy hãy thận trọng khi sử dụng nó.

Chúng tôi có một cơ sở dữ liệu Access cùng nhau bị xáo trộn, điều đó thực sự khiến công ty của chúng tôi phải quỳ gối một cách thường xuyên (tôi đã phải sửa nó ba lần chỉ trong ngày hôm qua).

Anh chàng thường xử lý việc này trong một vài tuần và hướng dẫn của anh ta sử dụng phương pháp dựa trên giao diện người dùng (Bắt đầu> Máy tính> Quản lý> Quản lý máy tính (Cục bộ)> Kết nối với máy tính khác> Công cụ hệ thống> Thư mục được chia sẻ> Mở tệp> Đóng Mở tập tin). CÁCH quá nhiều lần nhấp khi tôi chỉ có thể chạy lệnh trên và loại bỏ toàn bộ công ty khỏi tất cả các tệp cơ sở dữ liệu và bắt đầu quy trình Compact & Repair (tôi cũng đang làm việc theo cách tiếp cận theo kịch bản).

Bí quyết là đi trước những người ngay lập tức bắt đầu kết nối lại với cơ sở dữ liệu ngay khi nó đi xuống. Họ đã quá quen với việc họ không phát hiện ra lỗi để chống lại nó, họ cứ đập vào cơ sở dữ liệu cho đến khi họ quay trở lại. Tôi chỉ cần khởi động chúng cho đến khi tôi nén và sửa chữa ba tá các tập tin tạo nên cơ sở dữ liệu.


4

Nếu bạn đang nói về các tệp xử lý mở thông qua chia sẻ SMB trên máy chủ tệp Windows (Máy chủ 2012 trở lên), thì đây là câu trả lời của PowerShell:

Get-SmbOpenFile | Where-Object { $_.Path -like "D:\Folder\*" } | Close-SmbOpenFile -Force

Trên một máy chủ Windows cũ hơn, nó openfiles.exe /disconnect.

Đối với việc xử lý tệp hệ thống cục bộ, cách tốt nhất tôi tìm thấy là sử dụng Sysiternals handle.exe



2

Unlocker cũng có thể chạy ở chế độ im lặng.

Ví dụ: để mở khóa tất cả các tệp trong không gian làm việc của Jenkins:

"C:\Program Files\Unlocker\unlocker.exe" "%WORKSPACE%" /S

Sau đó, bạn có thể xóa các tệp không gian làm việc một cách an toàn:

del "%WORKSPACE%\*.*" /s /q

0

Bạn có thể sử dụng Powershell để làm công cụ này:

function KillProcessesWithHandles
{
    param([string]$path)

    $allProcesses = Get-Process

    # Start by closing all notepad processes. Someone may have left a logor config file open
    $allProcesses | Where-Object {$_.Name -eq "notepad"} | Stop-Process -Force -ErrorAction SilentlyContinue

    # Then close all processes running inside the folder we are trying to delete
    $allProcesses | Where-Object {$_.Path -like ($path + "*")} | Stop-Process -Force -ErrorAction SilentlyContinue

    # Finally close all processes with modules loaded from folder we are trying to delete
    foreach($lockedFile in Get-ChildItem -Path $path -Include * -Recurse) {
        foreach ($process in $allProcesses) {
            $process.Modules | Where-Object {$_.FileName -eq $lockedFile} | Stop-Process -Force -ErrorAction SilentlyContinue
        }
    }
}

Để biết thêm chi tiết, hãy tham khảo Thomas Ardal tại đây: https://thomasardal.com/deleting-contents-of-a-folder-contained-files-with-open-file-handles-USE-powershell/

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.