К сожалению, я не думаю, что вы можете уйти без надлежащего списка идентификаторов оболочки, в моей 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)
Хороший вопрос +1. – Shoban
Поздравляем с вашим столетием :) –
как именно он не работает? он вообще отображается в средстве просмотра буфера обмена? – fejesjoco