/// <summary> /// Create the full-blown Clip object /// </summary> /// <param name="clipboardUpdateInformation">ClipboardContents</param> /// <returns>Clip</returns> private Clip CreateClip(ClipboardUpdateInformation clipboardUpdateInformation) { if (clipboardUpdateInformation.OwnerHandle == IntPtr.Zero) { // TODO: Handle "0" here!!! Log.Warn().WriteLine("Clipboard content is owned by process 0"); } var interopWindow = InteropWindowFactory.CreateFor(clipboardUpdateInformation.OwnerHandle); // Make sure we use the parent window (top level) for the title. IInteropWindow toplevelWindow = interopWindow; var parent = toplevelWindow.GetParent(); while (true) { if (parent == IntPtr.Zero) { break; } toplevelWindow = toplevelWindow?.GetParentWindow(); parent = toplevelWindow.GetParent(); } var caption = toplevelWindow.GetCaption(); Clip clip; using (var process = Process.GetProcessById(interopWindow.GetProcessId())) { // Make sure we got something, when the caption is emtry up to now if (string.IsNullOrEmpty(caption)) { caption = process.MainWindowTitle; } // Try to create the product name string productName = process.ProcessName; try { var versionInfo = FileVersionInfo.GetVersionInfo(process.MainModule.FileName); productName = versionInfo.ProductName; } catch (Win32Exception ex) { // This happens with elevated processes Log.Warn().WriteLine(ex, "Problem retrieving process information for a process with ID {0} and name {1}", process.Id, process.ProcessName); } clip = new Clip { WindowTitle = caption, OwnerIcon = interopWindow.GetIcon <BitmapSource>(true) ?? toplevelWindow.GetIcon <BitmapSource>(true), SessionId = _currentSession.Id, ProcessName = process.ProcessName, ProductName = productName, OriginalWindowHandle = clipboardUpdateInformation.OwnerHandle, SequenceNumber = clipboardUpdateInformation.Id, OriginalFormats = clipboardUpdateInformation.Formats.ToList() }; } using (var clipboardAccessToken = ClipboardNative.Access()) { clip.Filenames = clipboardAccessToken.GetFilenames().ToList(); if (clip.OriginalFormats.Contains("CF_UNICODETEXT")) { clip.ClipboardText = clipboardAccessToken.GetAsUnicodeString(); } foreach (var format in clipboardUpdateInformation.Formats) { if (!_dopyConfiguration.IncludeFormats.Contains(format)) { continue; } clip.Formats.Add(format); using var clipboardStream = clipboardAccessToken.GetAsStream(format); var memoryStream = new MemoryStream((int)clipboardStream.Length); clipboardStream.CopyTo(memoryStream); memoryStream.Seek(0, SeekOrigin.Begin); clip.Contents[format] = memoryStream; } } return(clip); }
/// <summary> /// Test if the ClipboardUpdateInformation was created indirectly by Dopy, so we can excluding this from processing /// </summary> /// <param name="clipboardUpdateInformation">ClipboardUpdateInformation</param> /// <returns>bool if Dopy made this</returns> public static bool IsModifiedByDopy(this ClipboardUpdateInformation clipboardUpdateInformation) { return(clipboardUpdateInformation.Formats.Contains(Dopy)); }