VB.Net 3.5 تحقق مما إذا كان الملف قيد الاستخدام

StackOverflow https://stackoverflow.com/questions/1079036

  •  21-08-2019
  •  | 
  •  

سؤال

لدي برنامج تحديث مستقل تمامًا عن تطبيقي الرئيسي.أقوم بتشغيل update.exe لتحديث app.exe.للتحقق لمعرفة ما إذا كان الملف قيد الاستخدام، أنقله إلى ملف آخر وأكتشف خطأ إذا كان قيد الاستخدام.إذا لم تحدث أي مشاكل سأعيد تسميتها مرة أخرى.على الأقل تلك كانت خطتي..

البرنامج الرئيسي:app.exe
تحديث البرنامج:update.exe

يتم استخدام هذا البرنامج عبر الشبكة دون تشغيل أية خدمات.لذا، يقوم المستخدمون حرفيًا بتشغيل ملف exe عبر الشبكة على أجهزتهم.

أحتاج إلى تحديث app.exe عند تشغيل التحديث.للتحقق لمعرفة ما إذا كان app.exe لا يزال قيد الاستخدام، كنت أقوم بتغليف ما يلي في محاولة/التقاط لمعرفة ما إذا كان قد فشل:

IO.File.Move(upddir & "\app.exe"، upddir & "\app.exe.tst")
IO.File.Move(upddir & "\app.exe.tst"، upddir & "\app.exe")

والشيء المضحك هو أنه حتى إذا كان app.exe قيد التشغيل، فيمكن لعملية النقل إعادة تسميته إلى app.exe.tst دون أي خطأ.يمكنني حتى الاستمرار في التطبيق دون أي أخطاء.

ظننت أنني فقدت عقلي، لذلك أطلعت مبرمجًا آخر على هذا الأمر وتحقق مما قلته أعلاه.

لذلك، جربنا هذا ملفوفًا في محاولة الصيد:

تعتيم ملف القراءة كـ FileStream جديد (upddir & "\app.exe"، FileMode.Open، FileAccess.Read، FileShare.None)
قراءة الملف. التخلص ()

لقد وضعت مشاركة الملفات على أنها لا تظهر، على الأقل اعتقدت أنها ستُظهر أن هناك شخصًا ما في الملف.

وما زال مستمرا دون أي خطأ.

هل يعرف أحد لماذا يمكنني إعادة تسمية ملف قيد الاستخدام؟وأيضًا، هل هناك طريقة أفضل للقيام بذلك مما أفعله الآن؟

شكرًا!إيروك

هل كانت مفيدة؟

المحلول

يمكنك القيام بما يلي للتحقق مما إذا كان التطبيق يحتوي على مثيلات أخرى قيد التشغيل:

Process.GetProcessesByName("app.exe", "Machine1").Length > 0

وهي الطريقة الأكثر ملاءمة للتحقق مما إذا كان التطبيق قيد التشغيل.

القي نظرة على ملف.نقل وثائق MSDN.وهو يوضح بالتفصيل الاستثناءات التي تم طرحها.يُسمح لك بإعادة تسمية ملف exe حتى لو كان قيد الاستخدام في نظام التشغيل Vista.

نصائح أخرى

والرمز نفسه باستخدام "باستخدام":)

Public Function FileInUse(ByVal sFile As String) As Boolean
 Dim thisFileInUse As Boolean = False
 If System.IO.File.Exists(sFile) Then
     Try
       Using f As New IO.FileStream(sFile, FileMode.Open, FileAccess.ReadWrite, FileShare.None)
                ' thisFileInUse = False
       End Using
     Catch
       thisFileInUse = True
     End Try
 End If
 Return thisFileInUse
End Function

ما الذي يمكن القيام به هو استبدال التطبيق الهدف مع إكس المؤقتة.

وهذا المؤقتة ثم يولد التطبيق الهدف، ولكن أيضا بإنشاء ملف مقفل في موقع مشترك. يتم تحرير التأمين ويتم حذف الملف عند إنهاء التطبيق.

وبعد ذلك، قبل تحديث app.exe، يمكنك الاختيار هل هناك أي ملفات مؤمن في موقع مشترك، إذا كانت هناك مقفل الملفات ثم app.exe قيد الاستخدام.

ويمكن أن يكون هذا البرنامج مؤقتة تطبيق النافذة أقل، التطبيق وحدة التحكم التالية لا حد كبير ما يتعين عليها القيام به

class Program
{
    static string lockFileName;
    static System.IO.StreamWriter lockFileWrtier;
    static void Main(string[] args)
    {
        lockFileName = "AppLock_" + System.IO.Path.GetRandomFileName();

        lockFileWrtier = new System.IO.StreamWriter(lockFileName);

        System.Diagnostics.Process p = new Process();
        p.StartInfo.FileName = "cmd.exe";
        p.EnableRaisingEvents = true;
        p.Exited += new EventHandler(p_Exited);

        p.Start();

        Console.WriteLine("Press any key to stop");
        Console.ReadKey();
    }

    static void p_Exited(object sender, EventArgs e)
    {
        lockFileWrtier.Dispose();
        System.IO.File.Delete(lockFileName);

        Console.WriteLine("Process has exited");
    }
}

والمحدث ثم يبدو للجميع "AppLock_ *" الملفات، ومحاولات لفتحها مع تأمين كتابة، إذا كان لا يمكن الحصول على تأمين الكتابة على واحد منهم، إكس قيد الاستخدام.

وآمل أن يساعد هذا.

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

وعلى أية حال، ومن هنا:

<اقتباس فقرة>   

والخاص الفرعية CheckFileIfFileIsInUse (الأساسية ByVal thefilename كسلسلة)
        محاولة
            "على نظام التشغيل ويندوز فيستا يمكنك إعادة تسمية ملف قيد الاستخدام
            'و' في استخدام "الملف الأصلي يتبع اسم الملف الجديد

      Dim testfile As String = thefilename & ".tst"<br />

      If IO.File.Exists(testfile) Then<br />
          IO.File.Delete(testfile)<br />
      End If<br />

      ' so we have to rename it to something else<br />
      IO.File.Move(thefilename, testfile)<br />

      ' copy it back to the original file name in case something <br />breaks 
      ' this just keeps them in working order if it does<br />
      IO.File.Copy(testfile, thefilename)<br />

      ' then we try to delete the original file that could be in use <br />
      ' which will return an 'in use' error at this point<br />
      If IO.File.Exists(testfile) Then<br />
          IO.File.Delete(testfile)<br />
      End If<br />

  Catch ex As Exception<br />
      'throw it to the originating method<br />
      Throw<br />
  End Try<br />
     

النهاية الفرعية

وآمل أن يساعد هذا الشخص القادم.

Public Function FileInUse(ByVal sFile As String) As Boolean
    If System.IO.File.Exists(sFile) Then
        Try
            Dim F As Short = FreeFile()
            FileOpen(F, sFile, OpenMode.Binary, OpenAccess.ReadWrite, OpenShare.LockReadWrite)
            FileClose(F)
        Catch
            Return True
        End Try
    End If
End Function
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top