2011-02-02 2 views
6

Я использую этот код, чтобы скопировать файлы в буфер обмена:Скопировать файл из тома 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?

+0

Хороший вопрос +1. – Shoban

+0

Поздравляем с вашим столетием :) –

+2

как именно он не работает? он вообще отображается в средстве просмотра буфера обмена? – fejesjoco

ответ

5

К сожалению, я не думаю, что вы можете уйти без надлежащего списка идентификаторов оболочки, в моей 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; 
} 

Я не могу взять весь кредит здесь, я нашел этот КМАР код некоторое время назад и просто портировать его на C#. Не могу вспомнить исходный источник, но он хорошо работает до сих пор (я просто тестировал его на TrueCrypt)

+0

Thnks для ответа, я проверю его (сначала нужно установить TrueCrypt на этом компьютере. Во всяком случае, мой код работает на Winodws 7 Professional, я только что скопировал пасту и протестировал ее, но это менее важно. –

+0

Ну, это работает , Я знал, что что-то, что касается установки местоположений Shell, должно быть выполнено, но ничего не могло найти. –

+0

Исходным разработчиком C++-реализации CreateShellIDList был Паскаль Хурни. – pcunite