Hallo zusammen!
Ich komme momentan nicht weiter, der Explorer stürzt immer nach einigen ComExceptions mit der Fehlermeldung "Ungültige Formattec Struktur" ab. Das Problem liegt in der Methode GetData(ref System.Runtime.InteropServices.ComTypes.FORMATETC formatetc, out System.Runtime.InteropServices.ComTypes.STGMEDIUM medium).
Ich hab das Testprojekt angehängt.
[SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
void System.Runtime.InteropServices.ComTypes.IDataObject.GetData(ref System.Runtime.InteropServices.ComTypes.FORMATETC formatetc, out System.Runtime.InteropServices.ComTypes.STGMEDIUM medium)
{
medium = new STGMEDIUM();
Debug.WriteLine("Format requested: " + DataFormats.GetFormat(formatetc.cfFormat).Name);
if (DataFormats.GetFormat(formatetc.cfFormat).Name == NativeMethods.ShellClipboardFormats.CFSTR_FILEDESCRIPTORW.Name)
{
Debug.WriteLine("---- FileDescriptor wird übergeben");
MemoryStream fdStream = new MemoryStream();
fdStream.Write(BitConverter.GetBytes(files.Count), 0, sizeof(UInt32));
NativeMethods.FILEDESCRIPTORW fd = new NativeMethods.FILEDESCRIPTORW();
fd.cFileName = files[0].FileName;
fd.nFileSizeHigh = (UInt32)(files[0].FileSize >> 32);
fd.nFileSizeLow = (UInt32)(files[0].FileSize & 0xFFFFFFFF);
Int64 fileWriteTimeUtc = DateTime.Now.ToFileTimeUtc();
fd.ftLastWriteTime = new NativeMethods.FILETIME();
fd.ftLastWriteTime.nFileTimeHigh = (uint)(fileWriteTimeUtc >> 32);
fd.ftLastWriteTime.nFileTimeLow = (uint)(fileWriteTimeUtc & 0xFFFFFFFF);
// FileDescriptor in Memory Stream schreiben
int fdSize = Marshal.SizeOf(fd);
IntPtr fdPtr = Marshal.AllocHGlobal(fdSize);
Marshal.StructureToPtr(fd, fdPtr, true);
byte[] fdByteArray = new byte[fdSize];
Marshal.Copy(fdPtr, fdByteArray, 0, fdSize);
Marshal.FreeHGlobal(fdPtr);
fdStream.Write(fdByteArray, 0, fdByteArray.Length);
SetData(NativeMethods.ShellClipboardFormats.CFSTR_FILEDESCRIPTORW.Name, fdStream);
return;
}
if (IsAllowedTymed(formatetc.tymed))
{
if ((formatetc.tymed & TYMED.TYMED_ISTREAM) != TYMED.TYMED_NULL)
{
medium.tymed = TYMED.TYMED_HGLOBAL | TYMED.TYMED_ISTREAM;
if (formatetc.cfFormat == NativeMethods.ShellClipboardFormats.CFSTR_FILECONTENTS.Id)
{
if (istream != null)
{
medium.unionmember = pointer;
}
else
{
istream = new ComIStreamWrapper(File.Open(files[0].FullPath, FileMode.Open));
pointer = Marshal.GetIUnknownForObject(istream);
medium.unionmember = pointer;
}
}
try
{
((System.Runtime.InteropServices.ComTypes.IDataObject)this).GetDataHere(ref formatetc, ref medium);
return;
}
catch (Exception exc)
{
NativeMethods.GlobalFree(new HandleRef((STGMEDIUM)medium, medium.unionmember));
medium.unionmember = IntPtr.Zero;
Debug.WriteLine(exc);
}
}
medium.tymed = formatetc.tymed;
((System.Runtime.InteropServices.ComTypes.IDataObject)this).GetDataHere(ref formatetc, ref medium);
}
}
So wie es scheint gibt es bis jetzt niemanden der das hinbekommen hat. (Zumindest findet sich per Google nichts)
Viele Grüße,
Simon