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,21 +103,36 @@ EndSelection:<<<<<<<4
try { try {
IntPtr hWnd = User32.GetClipboardOwner(); IntPtr hWnd = User32.GetClipboardOwner();
if (hWnd != IntPtr.Zero) { if (hWnd != IntPtr.Zero) {
int pid; try
User32.GetWindowThreadProcessId( hWnd, out pid); {
using (Process me = Process.GetCurrentProcess()) int pid;
using (Process ownerProcess = Process.GetProcessById(pid)) { User32.GetWindowThreadProcessId(hWnd, out pid);
// Exclude myself using (Process me = Process.GetCurrentProcess())
if (ownerProcess != null && me.Id != ownerProcess.Id) { using (Process ownerProcess = Process.GetProcessById(pid))
// Get Process Name {
owner = ownerProcess.ProcessName; // Exclude myself
// Try to get the starting Process Filename, this might fail. if (ownerProcess != null && me.Id != ownerProcess.Id)
try { {
owner = ownerProcess.Modules[0].FileName; // Get Process Name
} catch (Exception) { owner = ownerProcess.ProcessName;
// Try to get the starting Process Filename, this might fail.
try
{
owner = ownerProcess.Modules[0].FileName;
}
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) { {
string messageText = null; LOG.Warn(clearException.Message);
string clipboardOwner = GetClipboardOwner(); }
if (clipboardOwner != null) { try
messageText = Language.GetFormattedString("clipboard_inuse", clipboardOwner); {
} else { Clipboard.SetDataObject(ido, copy, 5, 200);
messageText = Language.GetString("clipboard_error"); }
} catch (Exception clipboardSetException)
LOG.Error(messageText, ee); {
} else { string messageText = null;
Thread.Sleep(100); string clipboardOwner = GetClipboardOwner();
} if (clipboardOwner != null)
} finally { {
--retryCount; messageText = Language.GetFormattedString("clipboard_inuse", clipboardOwner);
} }
else {
messageText = Language.GetString("clipboard_error");
}
LOG.Error(messageText, clipboardSetException);
} }
} }
} }