.
منقول
لحذف أو تعديل على ملف ما زال قيد الاستخدام لا بد من معرفة ذلك التطبيق لغلقه
هذا مثال طريقة استخدام كلاس Util
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim op As New OpenFileDialog
If op.ShowDialog = Windows.Forms.DialogResult.OK Then
Dim p As Process = Util.GetProcessUsingFile(op.FileName)
If p IsNot Nothing Then
Dim ProcessFileName As String = p.MainModule.FileName.ToString
If MsgBox("الملف مستخدم بواسطة التطبيق التالي" & vbNewLine & ProcessFileName & vbNewLine & vbNewLine & "هل تريد إغلاقه؟", MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
p.Kill()
End If
Else
MsgBox("الملف غير مستخدم")
End If
End If
End Sub
كلاس Util معرفة الـ Process التي تستخدم الملفات وفيها دالتين
()Util.GetProcessesUsingFiles فحص مجموعة ملفات
()Util.GetProcessUsingFile فحص ملف واحد
Imports System.ComponentModel
Imports System.Runtime.InteropServices
Public Class Util
<DllImport("rstrtmgr.dll", CharSet:=CharSet.Unicode)> _
Private Shared Function RmStartSession(ByRef pSessionHandle As UInteger, ByVal dwSessionFlags As Integer, ByVal strSessionKey As String) As Integer
End Function
<DllImport("rstrtmgr.dll")> _
Private Shared Function RmEndSession(ByVal pSessionHandle As UInteger) As Integer
End Function
<DllImport("rstrtmgr.dll", CharSet:=CharSet.Unicode)> _
Private Shared Function RmRegisterResources(ByVal pSessionHandle As UInteger, ByVal nFiles As UInt32, ByVal rgsFilenames As String(), ByVal nApplications As UInt32, <[In]()> ByVal rgApplications As RM_UNIQUE_PROCESS(), ByVal nServices As UInt32, ByVal rgsServiceNames As String()) As Integer
End Function
<DllImport("rstrtmgr.dll")> _
Private Shared Function RmGetList(ByVal dwSessionHandle As UInteger, ByRef pnProcInfoNeeded As UInteger, ByRef pnProcInfo As UInteger, <[In](), Out()> ByVal rgAffectedApps As RM_PROCESS_INFO(), ByRef lpdwRebootReasons As UInteger) As Integer
End Function
Private Const RmRebootReasonNone As Integer = 0
Private Const CCH_RM_MAX_APP_NAME As Integer = 255
Private Const CCH_RM_MAX_SVC_NAME As Integer = 63
<StructLayout(LayoutKind.Sequential)> _
Private Structure RM_UNIQUE_PROCESS
Public dwProcessId As Integer
Public ProcessStartTime As ComTypes.FILETIME
End Structure
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
Private Structure RM_PROCESS_INFO
Public Process As RM_UNIQUE_PROCESS
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=CCH_RM_MAX_APP_NAME + 1)> _
Public strAppName As String
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=CCH_RM_MAX_SVC_NAME + 1)> _
Public strServiceShortName As String
Public ApplicationType As RM_APP_TYPE
Public AppStatus As UInteger
Public TSSessionId As UInteger
<MarshalAs(UnmanagedType.Bool)> _
Public bRestartable As Boolean
End Structure
Private Enum RM_APP_TYPE
RmUnknownApp = 0
RmMainWindow = 1
RmOtherWindow = 2
RmService = 3
RmExplorer = 4
RmConsole = 5
RmCritical = 1000
End Enum
Public Shared Function GetProcessUsingFile(ByVal filePath As String) As Process
Dim sessionHandle As UInteger
Dim processes As New List(Of Process)()
' Create a restart manager session
Dim rv As Integer = RmStartSession(sessionHandle, 0, Guid.NewGuid().ToString())
If rv <> 0 Then
Throw New Win32Exception()
End If
Try
' Let the restart manager know what files we’re interested in
Dim pathStrings(0) As String
pathStrings(0) = filePath
'= New String(filePaths.Count - 1) {}
'filePaths.CopyTo(pathStrings, 0)
rv = RmRegisterResources(sessionHandle, CUInt(pathStrings.Length), pathStrings, 0, Nothing, 0, Nothing)
If rv <> 0 Then
Throw New Win32Exception()
End If
' Ask the restart manager what other applications
' are using those files
Const ERROR_MORE_DATA As Integer = 234
Dim pnProcInfoNeeded As UInteger = 0, pnProcInfo As UInteger = 0, lpdwRebootReasons As UInteger = RmRebootReasonNone
rv = RmGetList(sessionHandle, pnProcInfoNeeded, pnProcInfo, Nothing, lpdwRebootReasons)
If rv = ERROR_MORE_DATA Then
' Create an array to store the process results
Dim processInfo As RM_PROCESS_INFO() = New RM_PROCESS_INFO(pnProcInfoNeeded - 1) {}
pnProcInfo = CUInt(processInfo.Length)
' Get the list
rv = RmGetList(sessionHandle, pnProcInfoNeeded, pnProcInfo, processInfo, lpdwRebootReasons)
If rv = 0 Then
' Enumerate all of the results and add them to the
' list to be returned
For i As Integer = 0 To pnProcInfo - 1
Try
processes.Add(Process.GetProcessById(processInfo(i).Process.dwProcessId))
' in case the process is no longer running
Catch generatedExceptionName As ArgumentException
End Try
Next
Else
Throw New Win32Exception()
End If
ElseIf rv <> 0 Then
Throw New Win32Exception()
End If
Finally
' Close the resource manager
RmEndSession(sessionHandle)
End Try
Dim p As Process
Try
p = processes(0)
Catch ex As Exception
End Try
Return p
End Function
Public Shared Function GetProcessesUsingFiles(ByVal filePaths As IList(Of String)) As IList(Of Process)
Dim sessionHandle As UInteger
Dim processes As New List(Of Process)()
' Create a restart manager session
Dim rv As Integer = RmStartSession(sessionHandle, 0, Guid.NewGuid().ToString())
If rv <> 0 Then
Throw New Win32Exception()
End If
Try
' Let the restart manager know what files we’re interested in
Dim pathStrings As String() = New String(filePaths.Count - 1) {}
filePaths.CopyTo(pathStrings, 0)
rv = RmRegisterResources(sessionHandle, CUInt(pathStrings.Length), pathStrings, 0, Nothing, 0, Nothing)
If rv <> 0 Then
Throw New Win32Exception()
End If
' Ask the restart manager what other applications
' are using those files
Const ERROR_MORE_DATA As Integer = 234
Dim pnProcInfoNeeded As UInteger = 0, pnProcInfo As UInteger = 0, lpdwRebootReasons As UInteger = RmRebootReasonNone
rv = RmGetList(sessionHandle, pnProcInfoNeeded, pnProcInfo, Nothing, lpdwRebootReasons)
If rv = ERROR_MORE_DATA Then
' Create an array to store the process results
Dim processInfo As RM_PROCESS_INFO() = New RM_PROCESS_INFO(pnProcInfoNeeded - 1) {}
pnProcInfo = CUInt(processInfo.Length)
' Get the list
rv = RmGetList(sessionHandle, pnProcInfoNeeded, pnProcInfo, processInfo, lpdwRebootReasons)
If rv = 0 Then
' Enumerate all of the results and add them to the
' list to be returned
For i As Integer = 0 To pnProcInfo - 1
Try
processes.Add(Process.GetProcessById(processInfo(i).Process.dwProcessId))
' in case the process is no longer running
Catch generatedExceptionName As ArgumentException
End Try
Next
Else
Throw New Win32Exception()
End If
ElseIf rv <> 0 Then
Throw New Win32Exception()
End If
Finally
' Close the resource manager
RmEndSession(sessionHandle)
End Try
Return processes
End Function
End Class