2012-12-20 10 views
6

मुझे हाल ही में File.Copy() से CopyFileEx का उपयोग करने से बदलना पड़ा है और मैं इसका उपयोग करने के तरीके के लिए संघर्ष कर रहा हूं।CopyFileEx wrapper पैरामीटर

बहुत सारे गुगलिंग के बाद मुझे this इसका उपयोग करने के लिए अच्छा रैपर मिला, लेकिन मुझे वर्तमान फ़ाइल की प्रतिलिपि बाइट्स की प्रगति प्राप्त करने की आवश्यकता है, और यदि संभव हो तो मैं उन सभी फ़ाइलों की प्रतिलिपि बनाने की प्रगति की गणना करता हूं जो मैं इसे पास करता हूं ।

(मुझे पता है कि ऐसी परियोजनाएं हैं जिनमें CopyFileEx से प्रगति बार हैं, लेकिन मुझे प्रासंगिक कोड खींचने के लिए पर्याप्त अनुभव नहीं हुआ है, और मैं इस रैपर का उपयोग करना चाहता हूं)।

संभावित रूप से इसे कॉपी करने के लिए फ़ाइलों के कुल बाइट्स की तुलना करके, जो मैं पहले से पाता हूं, और उस से प्रतिशत का काम कर रहा हूं।

मेरे नकल की वर्तमान पद्धति

FileRoutines.CopyFile(new FileInfo("source.txt"), new FileInfo("dest.txt")); 

मैं पर क्या अटक कर रहा हूँ कैसे पैरामीटर की प्रगति की जानकारी प्राप्त करने के लिए की जरूरत के साथ यह ओवरलोड है।

public sealed class FileRoutines 
{ 
    public static void CopyFile(FileInfo source, FileInfo destination) 
    { 
     CopyFile(source, destination, CopyFileOptions.None); 
    } 

    public static void CopyFile(FileInfo source, FileInfo destination, 
     CopyFileOptions options) 
    { 
     CopyFile(source, destination, options, null); 
    } 

    public static void CopyFile(FileInfo source, FileInfo destination, 
     CopyFileOptions options, CopyFileCallback callback) 
    { 
     CopyFile(source, destination, options, callback, null); 
    } 

    public static void CopyFile(FileInfo source, FileInfo destination, 
     CopyFileOptions options, CopyFileCallback callback, object state) 
    { 
     if (source == null) throw new ArgumentNullException("source"); 
     if (destination == null) 
      throw new ArgumentNullException("destination"); 
     if ((options & ~CopyFileOptions.All) != 0) 
      throw new ArgumentOutOfRangeException("options"); 

     new FileIOPermission(
      FileIOPermissionAccess.Read, source.FullName).Demand(); 
     new FileIOPermission(
      FileIOPermissionAccess.Write, destination.FullName).Demand(); 

     CopyProgressRoutine cpr = callback == null ? 
      null : new CopyProgressRoutine(new CopyProgressData(
       source, destination, callback, state).CallbackHandler); 

     bool cancel = false; 
     if (!CopyFileEx(source.FullName, destination.FullName, cpr, 
      IntPtr.Zero, ref cancel, (int)options)) 
     { 
      throw new IOException(new Win32Exception().Message); 
     } 
    } 

    private class CopyProgressData 
    { 
     private FileInfo _source = null; 
     private FileInfo _destination = null; 
     private CopyFileCallback _callback = null; 
     private object _state = null; 

     public CopyProgressData(FileInfo source, FileInfo destination, 
      CopyFileCallback callback, object state) 
     { 
      _source = source; 
      _destination = destination; 
      _callback = callback; 
      _state = state; 
     } 

     public int CallbackHandler(
      long totalFileSize, long totalBytesTransferred, 
      long streamSize, long streamBytesTransferred, 
      int streamNumber, int callbackReason, 
      IntPtr sourceFile, IntPtr destinationFile, IntPtr data) 
     { 
      return (int)_callback(_source, _destination, _state, 
       totalFileSize, totalBytesTransferred); 
     } 
    } 

    private delegate int CopyProgressRoutine(
     long totalFileSize, long TotalBytesTransferred, long streamSize, 
     long streamBytesTransferred, int streamNumber, int callbackReason, 
     IntPtr sourceFile, IntPtr destinationFile, IntPtr data); 

    [SuppressUnmanagedCodeSecurity] 
    [DllImport("Kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)] 
    private static extern bool CopyFileEx(
     string lpExistingFileName, string lpNewFileName, 
     CopyProgressRoutine lpProgressRoutine, 
     IntPtr lpData, ref bool pbCancel, int dwCopyFlags); 
} 

public delegate CopyFileCallbackAction CopyFileCallback(
    FileInfo source, FileInfo destination, object state, 
    long totalFileSize, long totalBytesTransferred); 

public enum CopyFileCallbackAction 
{ 
    Continue = 0, 
    Cancel = 1, 
    Stop = 2, 
    Quiet = 3 
} 

[Flags] 
public enum CopyFileOptions 
{ 
    None = 0x0, 
    FailIfDestinationExists = 0x1, 
    Restartable = 0x2, 
    AllowDecryptedDestination = 0x8, 
    All = FailIfDestinationExists | Restartable | AllowDecryptedDestination 
} 

किसी भी पॉइंटर्स ने वास्तव में सराहना की।

+0

यह कोड एक एमएसडीएन पत्रिका लेख के कोड के समान दिखता है। यदि ऐसा है, तो आपको मूल क्रेडिट करना चाहिए। http://msdn.microsoft.com/en-us/magazine/cc163851.aspx –

+1

@ क्रिसडोलन - लिंक सिर्फ एमएसडीएन पत्रिका संग्रह को इंगित करता है - एमएसडीएन पत्रिका फरवरी 2005 के लिए सीएम देखें। नेट मैटर्स चित्रा 1 FileRoutines.CopyFile का उपयोग Win32 CopyFileEx –

+1

@TheLonelyCoder - हम्म, आप सही हैं। मैंने इसे यहां पुनः पाया: https://web.archive.org/web/20130304214632/http://msdn.microsoft.com/en-us/magazine/cc163851.aspx लेकिन सीएसएस के बिना, इसलिए यह बहुत कठिन है –

उत्तर

8

रैपर में प्रगति को संभालने के लिए पहले से ही नलसाजी की आवश्यकता है। वापसी से पहले CallbackHandler में अपनी प्रगति पट्टी को अपडेट करने के लिए कोड को बस कार्यान्वित करें। प्रगतिबार 1। अधिकतम डिफ़ॉल्ट 100 पर है, इसलिए नीचे दिया गया कोड प्रतिशत की गणना करेगा।

इस के साथ अपने वर्तमान CopyFile कॉल बदलें:

CopyFileCallbackAction myCallback(FileInfo source, FileInfo destination, object state, long totalFileSize, long totalBytesTransferred) 
{ 
    double dProgress = (totalBytesTransferred/(double)totalFileSize) * 100.0; 
    progressBar1.Value = (int)dProgress; 
    return CopyFileCallbackAction.Continue; 
} 

FileRoutines.CopyFile(new FileInfo("source.txt"), new FileInfo("dest.txt"), myCallback); 
+0

पढ़ें आपके उत्तर के लिए धन्यवाद। मुझे पता है कि कोड पहले से ही है, मुझे नहीं पता कि इसका उपयोग कैसे करें :) क्या आप मुझे एक कोड उदाहरण दे सकते हैं? –

+0

@ बालीसी - कोड अनुरोध के रूप में जोड़ा गया। :) –

+0

बहुत बहुत धन्यवाद, मैं आज रात का परीक्षण करूंगा और यह बताएगा कि यह काम करता है :) –

0

तुम सिर्फ एक फ़ाइल प्रतिलिपि के लिए एक प्रगति बार दिखाना चाहते हैं, तो आप this कर सकते हैं। यह विंडोज मानक संवाद का उपयोग करता है जो एक प्रगति पट्टी और शेष समय दिखाता है, और इसमें एक रद्द बटन है। यह वही था जो मुझे मूल रूप से कोड की एक पंक्ति में चाहिए था।

// The following using directive requires a project reference to Microsoft.VisualBasic. 
using Microsoft.VisualBasic.FileIO; 

class FileProgress 
{ 
    static void Main() 
    { 
     // Specify the path to a folder that you want to copy. If the folder is small, 
     // you won't have time to see the progress dialog box. 
     string sourcePath = @"C:\Windows\symbols\"; 
     // Choose a destination for the copied files. 
     string destinationPath = @"C:\TestFolder"; 

     FileSystem.CopyDirectory(sourcePath, destinationPath, 
      UIOption.AllDialogs); 
    } 
} 
संबंधित मुद्दे