srwi / EverythingToolbar

Everything integration for the Windows taskbar.
Other
9.49k stars 412 forks source link

Copy file always failed with 0x800401D0 (CLIPBRD_E_CANT_OPEN) after 1 second on some PC, but copy success. #362

Closed yyjdelete closed 1 year ago

yyjdelete commented 1 year ago

Preflight Checklist

EverythingToolbar Version

1.0.3.0

Windows Version

Win10 22H2

Steps to reproduce

  1. Search any file in EverythingToolbar;
  2. Right on it and click copy;

Expected Behavior

Copy should success immediately

Actual Behavior

It freezen for 1 second, After about 1 second, a messagebox is shown with translated message of MessageBoxFailedToCopyFile But the file does in clipboard and can be paste by Ctrl+V

Screenshots

No response

Log output

2023-04-09 11:56:19.5701|ERROR|EverythingToolbar.Data.SearchResult|Failed to copy file.|System.Runtime.InteropServices.COMException (0x800401D0): OpenClipboard 失败 (异常来自 HRESULT:0x800401D0 (CLIPBRD_E_CANT_OPEN))
   在 System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo)
   在 System.Windows.Clipboard.Flush()
   在 System.Windows.Clipboard.CriticalSetDataObject(Object data, Boolean copy)
   在 System.Windows.Clipboard.SetDataInternal(String format, Object data)
   在 EverythingToolbar.Data.SearchResult.CopyToClipboard() 位置 C:\Users\Stephan\Entwicklung\EverythingToolbar\EverythingToolbar\Data\SearchResult.cs:行号 136

Additional Information

The CLIPBRD_E_CANT_OPEN only happens on one of my PC, but works well on another one even without the below patch.

I try to find it on the web, seems it's an bug of winapi, and the only workaroud is to disable flush by Clipboard.SetDataObject(dataObj , copy: false); with copy: false directly. And change the code of SearchResult.CopyToClipboard to the below works well on my PC.

https://learn.microsoft.com/en-us/dotnet/api/system.windows.clipboard.setdataobject?view=netframework-4.8.1#system-windows-clipboard-setdataobject(system-object-system-boolean)

copy: true to leave the data on the system Clipboard when the application exits; false to clear the data from the system Clipboard when the application exits.

public void CopyToClipboard()
{
try
{
DataObject dataObj = new DataObject();
dataObj .SetFileDropList(new StringCollection
{
this.FullPathAndFileName
});
Clipboard.SetDataObject(dataObj , copy: false);
}
catch (Exception e)
{
SearchResult.Logger.Error(e, "Failed to copy file.");
MessageBox.Show(Resources.MessageBoxFailedToCopyFile, Resources.MessageBoxErrorTitle, MessageBoxButton.OK, MessageBoxImage.Hand);
}
}
srwi commented 1 year ago

Thank you for looking into it!

Probably another application is blocking the clipboard on your one computer, leading to this error. If your changes make it work consistently, I think there is no real downside to setting copy: false.

Would you like to open a pull request for your changes?