我的Computer
上有一个Excel File
。这个文件我想copy and Paste
到我在Remote Computer.
上运行的程序
在Copy
之后,我想使用这个文件并制作Excel.Interop changes
,然后我想保存一个新的Excel文件,它与我复制到程序中的文件不同。
如果我想从仍在same Remote Computer
上运行的程序中的Remote Computer
复制文件,它将使用以下代码:
IDataObject data = Clipboard.GetDataObject();
if (!data.GetDataPresent(DataFormats.FileDrop))
return;
string[] filePath = (string[])
data.GetData(DataFormats.FileDrop);
但是,当我想将数据从主电脑复制到运行该程序的远程电脑时,它就不起作用了。
从其他计算机的粘贴文件中获取一些数据的唯一方法是使用以下代码:
MemoryStream fileGroupDescriptorStream = (MemoryStream)dataObject.GetData("FileGroupDescriptorW", true);
使用FileGroupDescriptorW
,我可以从文件中获取字节,但使用它,我不能做太多事情,因为我无法访问我复制粘贴到这里的excel文件。
为了加密它并获得文件以获得文件名等,我从这个问题中找到了这个代码:问题
有了它,我尝试了这个代码:
private System.Windows.IDataObject underlyingDataObject;
private System.Runtime.InteropServices.ComTypes.IDataObject comUnderlyingDataObject;
private System.Windows.IDataObject oleUnderlyingDataObject;
private MethodInfo getDataFromHGLOBLALMethod;
public void ObjectData(System.Windows.IDataObject underlyingDataObject)
{
this.underlyingDataObject = underlyingDataObject;
this.comUnderlyingDataObject = (System.Runtime.InteropServices.ComTypes.IDataObject)this.underlyingDataObject;
//FieldInfo innerDataField = this.underlyingDataObject.GetType().GetField("innerData", BindingFlags.NonPublic | BindingFlags.Instance);
//FieldInfo innerDataField = this.underlyingDataObject.GetType().GetField("innerData", BindingFlags.NonPublic | BindingFlags.Instance);
FieldInfo innerDataField = this.underlyingDataObject.GetType().GetField("_innerData", BindingFlags.NonPublic | BindingFlags.Instance);
this.oleUnderlyingDataObject = (System.Windows.IDataObject)innerDataField.GetValue(this.underlyingDataObject);
this.getDataFromHGLOBLALMethod = this.oleUnderlyingDataObject.GetType().GetMethod("GetDataFromHGLOBLAL", BindingFlags.NonPublic | BindingFlags.Instance);
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public sealed class FILEGROUPDESCRIPTORW
{
public uint cItems;
public FILEDESCRIPTORW[] fgd;
}
public sealed class SIZEL
{
public int cx;
public int cy;
}
public sealed class POINTL
{
public int x;
public int y;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public sealed class FILEDESCRIPTORW
{
public uint dwFlags;
public Guid clsid;
public SIZEL sizel;
public POINTL pointl;
public uint dwFileAttributes;
public System.Runtime.InteropServices.ComTypes.FILETIME ftCreationTime;
public System.Runtime.InteropServices.ComTypes.FILETIME ftLastAccessTime;
public System.Runtime.InteropServices.ComTypes.FILETIME ftLastWriteTime;
public uint nFileSizeHigh;
public uint nFileSizeLow;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string cFileName;
}
以及我粘贴文件的部分:
private void Border_PreviewKeyDown(object sender, KeyEventArgs e)
{
View.path = null;
if (e.KeyboardDevice.Modifiers == ModifierKeys.Control)
{
if (e.Key == Key.V)
{
IDataObject dataObject = Clipboard.GetDataObject();
IntPtr fileGroupDescriptorWPointer = IntPtr.Zero;
MemoryStream fileGroupDescriptorStream = (MemoryStream)dataObject.GetData("FileGroupDescriptorW", true);
byte[] fileGroupDescriptorBytes = new byte[fileGroupDescriptorStream.Length];
fileGroupDescriptorStream.Read(fileGroupDescriptorBytes, 0, fileGroupDescriptorBytes.Length);
fileGroupDescriptorStream.Close();
fileGroupDescriptorWPointer = Marshal.AllocHGlobal(fileGroupDescriptorBytes.Length);
Marshal.Copy(fileGroupDescriptorBytes, 0, fileGroupDescriptorWPointer, fileGroupDescriptorBytes.Length);
object fileGroupDescriptorObject = Marshal.PtrToStructure(fileGroupDescriptorWPointer, typeof(FILEGROUPDESCRIPTORW));
FILEGROUPDESCRIPTORW fileGroupDescriptor = (FILEGROUPDESCRIPTORW)fileGroupDescriptorObject;
string[] fileNames = new string[fileGroupDescriptor.cItems];
IntPtr fileDescriptorPointer = (IntPtr)((int)fileGroupDescriptorWPointer + Marshal.SizeOf(fileGroupDescriptor.cItems));
for (int fileDescriptorIndex = 0; fileDescriptorIndex < fileGroupDescriptor.cItems; fileDescriptorIndex++)
{
//marshal the pointer top the file descriptor as a FILEDESCRIPTORW struct and get the file name
FILEDESCRIPTORW fileDescriptor = (FILEDESCRIPTORW)Marshal.PtrToStructure(fileDescriptorPointer, typeof(FILEDESCRIPTORW));
fileNames[fileDescriptorIndex] = fileDescriptor.cFileName;
//move the file descriptor pointer to the next file descriptor
fileDescriptorPointer = (IntPtr)((int)fileDescriptorPointer + Marshal.SizeOf(fileDescriptor));
}
MessageBox.Show(fileNames[0]);
}
}
}
但现在我得到了一个例外:"试图读取或写入受保护的内存。这通常表示其他内存已损坏">
那么,有人知道如何从我的计算机上复制Excel文件,然后将Excel文件粘贴到我在RemoteDesktop上运行的程序中吗。然后从那里编辑文件,这样最好将粘贴的文件复制到临时文件夹中。
我在.NET7中拖放文件时也遇到了同样的问题。您必须更改:
IntPtr fileDescriptorPointer = (IntPtr)((int)fileGroupDescriptorWPointer + Marshal.SizeOf(fileGroupDescriptor.cItems));
至
IntPtr fileDescriptorPointer = (IntPtr)((long)fileGroupDescriptorWPointer + Marshal.SizeOf(fileGroupDescriptor.cItems));
这个:
fileDescriptorPointer = (IntPtr)((int)fileDescriptorPointer + Marshal.SizeOf(fileDescriptor));
至
fileDescriptorPointer = (IntPtr)((long)fileDescriptorPointer + Marshal.SizeOf(fileDescriptor));
这在.NET 7 中对我很有效