Merge pull request #21 from greenshot/bugfix/BUG-1935_clipboard_retry

BUG-1935: Trying to make clipboard actions more stable.
This commit is contained in:
Robin Krom 2016-04-11 10:40:49 +02:00
commit fca40f1c97

View file

@ -40,7 +40,7 @@ namespace GreenshotPlugin.Core {
/// </summary> /// </summary>
public static class ClipboardHelper { public static class ClipboardHelper {
private static readonly ILog LOG = LogManager.GetLogger(typeof(ClipboardHelper)); private static readonly ILog LOG = LogManager.GetLogger(typeof(ClipboardHelper));
private static readonly Object clipboardLockObject = new Object(); private static readonly object clipboardLockObject = new object();
private static readonly CoreConfiguration config = IniConfig.GetIniSection<CoreConfiguration>(); private static readonly CoreConfiguration config = IniConfig.GetIniSection<CoreConfiguration>();
private static readonly string FORMAT_FILECONTENTS = "FileContents"; private static readonly string FORMAT_FILECONTENTS = "FileContents";
private static readonly string FORMAT_PNG = "PNG"; private static readonly string FORMAT_PNG = "PNG";
@ -103,22 +103,37 @@ EndSelection:<<<<<<<4
try { try {
IntPtr hWnd = User32.GetClipboardOwner(); IntPtr hWnd = User32.GetClipboardOwner();
if (hWnd != IntPtr.Zero) { if (hWnd != IntPtr.Zero) {
try
{
int pid; int pid;
User32.GetWindowThreadProcessId( hWnd, out pid); User32.GetWindowThreadProcessId(hWnd, out pid);
using (Process me = Process.GetCurrentProcess()) using (Process me = Process.GetCurrentProcess())
using (Process ownerProcess = Process.GetProcessById(pid)) { using (Process ownerProcess = Process.GetProcessById(pid))
{
// Exclude myself // Exclude myself
if (ownerProcess != null && me.Id != ownerProcess.Id) { if (ownerProcess != null && me.Id != ownerProcess.Id)
{
// Get Process Name // Get Process Name
owner = ownerProcess.ProcessName; owner = ownerProcess.ProcessName;
// Try to get the starting Process Filename, this might fail. // Try to get the starting Process Filename, this might fail.
try { try
{
owner = ownerProcess.Modules[0].FileName; owner = ownerProcess.Modules[0].FileName;
} catch (Exception) { }
catch (Exception)
{
} }
} }
} }
} }
catch(Exception e)
{
LOG.Warn("Non critical error: Couldn't get clipboard process, trying to use the title.", e);
StringBuilder title = new StringBuilder(260, 260);
User32.GetWindowText(hWnd, title, title.Capacity);
owner = title.ToString();
}
}
} catch (Exception e) { } catch (Exception e) {
LOG.Warn("Non critical error: Couldn't get clipboard owner.", e); LOG.Warn("Non critical error: Couldn't get clipboard owner.", e);
} }
@ -133,27 +148,31 @@ EndSelection:<<<<<<<4
/// <param name="copy"></param> /// <param name="copy"></param>
private static void SetDataObject(IDataObject ido, bool copy) { private static void SetDataObject(IDataObject ido, bool copy) {
lock (clipboardLockObject) { lock (clipboardLockObject) {
int retryCount = 5; // Clear first, this seems to solve some issues
while (retryCount >= 0) { try
try { {
Clipboard.SetDataObject(ido, copy); Clipboard.Clear();
break; }
} catch (Exception ee) { catch (Exception clearException)
if (retryCount == 0) { {
LOG.Warn(clearException.Message);
}
try
{
Clipboard.SetDataObject(ido, copy, 5, 200);
}
catch (Exception clipboardSetException)
{
string messageText = null; string messageText = null;
string clipboardOwner = GetClipboardOwner(); string clipboardOwner = GetClipboardOwner();
if (clipboardOwner != null) { if (clipboardOwner != null)
{
messageText = Language.GetFormattedString("clipboard_inuse", clipboardOwner); messageText = Language.GetFormattedString("clipboard_inuse", clipboardOwner);
} else { }
else {
messageText = Language.GetString("clipboard_error"); messageText = Language.GetString("clipboard_error");
} }
LOG.Error(messageText, ee); LOG.Error(messageText, clipboardSetException);
} else {
Thread.Sleep(100);
}
} finally {
--retryCount;
}
} }
} }
} }