الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

معرفة التطبيق الذي يستخدم الملف وإغلاقه

بدأه vbnetvbnet في 22 فبراير 2014 · 0 رد · 344 مشاهدة · في Microsoft Visual Basic.NET
مشاركة: واتساب X فيسبوك تيليجرام
#1

.

 

منقول

 

 

 

لحذف أو تعديل على ملف ما زال قيد الاستخدام لا بد من معرفة ذلك التطبيق لغلقه

 

هذا مثال طريقة استخدام كلاس 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

تم تعديل هذه المشاركة بواسطة vbnetvbnet في 22 فبراير 2014 في 20:43

.

أقوال مميزة من منتدى الفريق العربي للبرمجة (قيد التحديث)

 

الأستاذ: محمد طلال بدوي كتب:

إن صحبة الناجحين تصيب بعدوى النجاح، ويا لها من عدوى جميلة، تشعرك بجو من الحماسة والمنافسة، وتبقيك مشتعلا في بحث مستمر عن المراكز الأولى.

الدكتورة: زهرة (أم عهود) كتب:

والله لا نريد من هذه الدنيا شيء إلا ان نكون اخوة متحابين في الله يجمعنا طلب العلم ومساعدة الآخرين لوجه الله تعالى.

.

مواضيع مشابهة