คัดลอกไฟล์จากโวลุ่ม TrueCrypt ไปยังคลิปบอร์ดหรือไม่

ฉันใช้รหัสนี้เพื่อคัดลอกไฟล์ไปยังคลิปบอร์ด:

IDataObject data = new DataObject();
data.SetData(DataFormats.FileDrop, new string[] {@"X:\test.doc"});
MemoryStream memo = new MemoryStream(4);
byte[] bytes = new byte[] { (byte)(5), 0, 0, 0 };
memo.Write(bytes, 0, bytes.Length);
data.SetData("Preferred DropEffect", memo);
Clipboard.SetDataObject(data);

น่าเสียดายที่วิธีนี้ใช้ไม่ได้หากดิสก์เป็นโวลุ่มที่ติดตั้ง TrueCrypt วิธีการทำเช่นนี้บนโวลุ่ม TrueCrypt คืออะไร?


person Ivan Ičin    schedule 02.02.2011    source แหล่งที่มา
comment
ขอแสดงความยินดีกับศตวรรษของคุณ :)   -  person Javed Akram    schedule 02.02.2011
comment
มันใช้งานไม่ได้จริงๆ เหรอ? มันแสดงในโปรแกรมดูคลิปบอร์ดเลยหรือเปล่า?   -  person fejesjoco    schedule 02.02.2011


คำตอบ (1)


น่าเสียดายที่ฉันไม่คิดว่าคุณจะหนีไปได้หากไม่มีรายการ Shell ID ที่ถูกต้อง ใน Windows 7 ของฉัน รหัสของคุณใช้งานไม่ได้กับระบบไฟล์ทั่วไปด้วยซ้ำ รหัสที่เหมาะสมจะต้องระบุ CIDL ก่อน:

    var data = new DataObject();
    var files = new StringCollection() { @"T:\Test.doc" };
    data.SetFileDropList(files);
    data.SetData("Preferred DropEffect", true, new MemoryStream(new byte[] { 5, 0, 0, 0 }));
    data.SetData("Shell IDList Array", true, CreateShellIDList(files));
    Clipboard.SetDataObject(data, true);

โดยที่ CreateShellIDList สร้างการแสดงไบนารีของโครงสร้าง CIDA (CFSTR_SHELLIDLIST) ที่จำเป็น การใช้งานอยู่ด้านล่าง:

[DllImport("shell32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr ILCreateFromPath(string path);
[DllImport("shell32.dll", CharSet = CharSet.None)]
public static extern void ILFree(IntPtr pidl);
[DllImport("shell32.dll", CharSet = CharSet.None)]
public static extern int ILGetSize(IntPtr pidl);

private static MemoryStream CreateShellIDList(StringCollection filenames)
{
    // first convert all files into pidls list
    int pos = 0;
    byte[][] pidls = new byte[filenames.Count][];
    foreach (var filename in filenames)
    {
        // Get pidl based on name
        IntPtr pidl = ILCreateFromPath(filename);
        int pidlSize = ILGetSize(pidl);
        // Copy over to our managed array
        pidls[pos] = new byte[pidlSize];
        Marshal.Copy(pidl, pidls[pos++], 0, pidlSize);
        ILFree(pidl);
    }

    // Determine where in CIDA we will start pumping PIDLs
    int pidlOffset = 4 * (filenames.Count + 2);
    // Start the CIDA stream stream
    var memStream = new MemoryStream();
    var sw = new BinaryWriter(memStream);
    // Initialize CIDA witha count of files
    sw.Write(filenames.Count);
    // Calcualte and write relative offsets of every pidl starting with root
    sw.Write(pidlOffset);
    pidlOffset += 4; // root is 4 bytes
    foreach(var pidl in pidls)
    {
        sw.Write(pidlOffset);
        pidlOffset += pidl.Length;
    }

    // Write the root pidl (0) followed by all pidls
    sw.Write(0);
    foreach(var pidl in pidls) sw.Write(pidl);
    // stream now contains the CIDA
    return memStream;
}

ฉันไม่สามารถรับเครดิตทั้งหมดที่นี่ ฉันพบรหัส CIDA นี้เมื่อไม่นานมานี้ และเพิ่งย้ายไปยัง c# จำแหล่งที่มาดั้งเดิมไม่ได้จริงๆ แต่ใช้งานได้ดีจนถึงตอนนี้ (ฉันเพิ่งทดสอบกับ TrueCrypt ด้วย)

person mmix    schedule 07.02.2011
comment
ขอบคุณสำหรับคำตอบ ฉันจะตรวจสอบ (ต้องติดตั้ง TrueCrypt บนคอมพิวเตอร์เครื่องนี้ก่อน อย่างไรก็ตาม รหัสของฉันใช้ได้กับ Winodws 7 Professional ฉันเพิ่งคัดลอกและวางและทดสอบแล้ว แต่นั่นสำคัญน้อยกว่า - person Ivan Ičin; 08.02.2011
comment
มันได้ผล ฉันรู้ว่าต้องทำอะไรบางอย่างในการพิจารณากำหนดตำแหน่งของเชลล์ แต่ไม่พบอะไรเลย - person Ivan Ičin; 08.02.2011
comment
นักพัฒนาดั้งเดิมของการนำ CreateShellIDList ไปใช้ C++ คือ Pascal Hurni - person pcunite; 26.04.2014