Cách đây rất lâu, không thể có được danh sách các tệp đang khóa quy trình một cách đáng tin cậy vì đơn giản là Windows không theo dõi thông tin đó. ủng hộKhởi động lại API trình quản lý , thông tin đó hiện đã được theo dõi.
Tôi sẽ lấy đường dẫn tập tin và quay lại Danh sách
Mã được đặt cùng nhau để khóa tệp cho tất cả các quy trình.
sử dụng System.Runtime.InteropServices;
sử dụng System.Diagnostics;
using System;
using System.Collections.Generic;
lớp công khai tĩnh FileUtil
{
[StructLayout(LayoutKind.Sequential)]
cấu trúc RM_UNIQUE_PROCESS
{
int công khai dwProcessId;
public System.Runtime.InteropServices.ComTypes.FILETIME ProcessStartTime;
}
const int RmRebootReasonNone = 0;
const int CCH_RM_MAX_APP_NAME = 255;
const int CCH_RM_MAX_SVC_NAME = 63;
liệt kê RM_APP_TYPE
{
RmUnknownApp = 0,
RmMainWindow = 1,
RmOtherWindow = 2,
RmDịch vụ = 3,
RmExplorer = 4,
RmConsole = 5,
RmCritical=1000
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
cấu trúc RM_PROCESS_INFO
{
Quy trình RM_UNIQUE_PROCESS công khai;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCH_RM_MAX_APP_NAME + 1)]
chuỗi công khai strAppName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCH_RM_MAX_SVC_NAME + 1)]
chuỗi công khai strServiceShortName;
Loại ứng dụng RM_APP_TYPE công khai;
uint công khai AppStatus;
TSSessionId uint công khai;
[MarshalAs(UnmanagedType.Bool)]
bool công khai bCó thể khởi động lại;
}
[DllImport("rsstrtmgr.dll", CharSet = CharSet.Unicode)]
static extern int RmRegisterResources(uint pSessionHandle,
UInt32 nFiles,
chuỗi [] rgsTên tệp,
Ứng dụng UInt32 n,
[Trong] RM_UNIQUE_PROCESS[] rgApplications,
Dịch vụ UInt32 n,
chuỗi [] rgsServiceNames);
[DllImport("rsstrtmgr.dll", CharSet = CharSet.Auto)]
static extern int RmStartSession(out uint pSessionHandle, int dwSessionFlags, string strSessionKey);
[DllImport("rsstrtmgr.dll")]
static extern int RmEndSession(uint pSessionHandle);
[DllImport("rsstrtmgr.dll")]
static extern int RmGetList(uint dwSessionHandle,
out uint pnProcInfoNeeded,
giới thiệu pnProcInfo,
[Vào, ra] RM_PROCESS_INFO[] rgAffectedApps,
ref uint lpdwRebootReasons);
///
/// Tìm hiểu (các) quy trình nào có khóa trên tệp được chỉ định.
///
/// Đường dẫn của tệp.
/// Quy trình khóa tập tin
/// Xem thêm:
/// http://msdn.microsoft.com/en-us/library/windows/desktop/aa373661(v=vs.85).aspx
/// http://wyupdate.googlecode.com/svn-history/r401/trunk/frmFilesInUse.cs (không có bản quyền về mã tại thời điểm xem)
///
///
Danh sách công khai tĩnh WhoIsLocking(đường dẫn chuỗi)
{
xử lý uint;
khóa chuỗi = Guid.NewGuid().ToString();
Danh sách quy trình = Danh sách mới();
int res = RmStartSession(outhandle, 0, key);
if (res != 0) ném Ngoại lệ mới ("Không thể bắt đầu phiên khởi động lại. Không thể xác định khóa tệp.");
thử
{
const int ERROR_MORE_DATA = 234;
uint pnProcInfoNeeded = 0,
pnProcInfo = 0,
lpdwRebootReasons = RmRebootReasonNone;
string[] Resources = new string[] { path }; // Chỉ kiểm tra một tài nguyên.
res = RmRegisterResources(xử lý, (uint)resources.Length, tài nguyên, 0, null, 0, null);
if (res != 0) ném ngoại lệ mới("Không thể đăng ký tài nguyên.");
//Lưu ý: có một điều kiện chạy đua ở đây -- lệnh gọi đầu tiên tới RmGetList() trả về
// tổng số tiến trình Tuy nhiên, khi chúng ta gọi lại RmGetList() để nhận
// số tiến trình thực tế con số này có thể đã tăng lên.
res = RmGetList(xử lý, out pnProcInfoNeeded, ref pnProcInfo, null, ref lpdwRebootReasons);
nếu (res == ERROR_MORE_DATA)
{
// Tạo một mảng để lưu trữ kết quả của quá trình
RM_PROCESS_INFO[] processInfo = new RM_PROCESS_INFO[pnProcInfoNeeded];
pnProcInfo = pnProcInfoNeeded;
// Lấy danh sách
res = RmGetList(xử lý, out pnProcInfoNeeded, ref pnProcInfo, processInfo, ref lpdwRebootReasons);
nếu (res == 0)
{
quy trình = Danh sách mới((int)pnProcInfo);
// Liệt kê tất cả các kết quả và thêm chúng vào
// danh sách được trả về
cho (int i = 0; i < pnProcInfo; i++)
{
thử
{
quy trình.Add(Process.GetProcessById(processInfo[i].Process.dwProcessId));
}
// bắt lỗi -- trong trường hợp tiến trình không còn chạy nữa
bắt (ArgumentException) { }
}
}
nếu không thì ném Ngoại lệ mới ("Không thể liệt kê các quy trình khóa tài nguyên.");
}
khác nếu (res != 0) ném Ngoại lệ mới ("Không thể liệt kê các quy trình khóa tài nguyên. Không thể lấy được kích thước của kết quả.");
}
finally
{
RmEndSession(xử lý);
}
quá trình trả lại;
}
}
Sử dụng các quyền hạn chế (ví dụ: IIS)
Cuộc gọi này truy cập vào sổ đăng ký. Nếu tiến trình không có quyền thực hiện việc này, bạn sẽ nhận được ERROR_WRITE_FAULT,nghĩa Một thao tác không thể đọc hoặc ghi vào sổ đăng ký
.BạnCó thểChọn lọc cấp quyền tài khoản hạn chế của bạn cho các phần cần thiết của sổ đăng ký. Mặc dù sẽ an toàn hơn nếu quy trình truy cập hạn chế của bạn đặt cờ (chẳng hạn như trong cơ sở dữ liệu hoặc hệ thống tệp hoặc bằng cách sử dụng cơ chế giao tiếp giữa các quy trình như hàng đợi hoặc đường dẫn có tên) và yêu cầu quy trình thứ hai gọi API Trình quản lý khởi động lại .
Việc cấp các đặc quyền không tối thiểu cho người dùng IIS là một rủi ro bảo mật.
Tôi là một lập trình viên xuất sắc, rất giỏi!