mirror of
https://github.com/greenshot/greenshot
synced 2025-07-31 04:00:13 -07:00
Implemented some TODO's, fixed freezing the wrong processes, fixed retrieval of window icon for some windows and cleaned some code.
git-svn-id: http://svn.code.sf.net/p/greenshot/code/trunk@1831 7dccd23d-a4a3-4e1f-8c07-b4c1b4018ab4
This commit is contained in:
parent
6e95cf210d
commit
6905a353c1
9 changed files with 136 additions and 40 deletions
|
@ -72,6 +72,7 @@ namespace Greenshot.Destinations {
|
||||||
exePath = GetExePath("OUTLOOK.EXE");
|
exePath = GetExePath("OUTLOOK.EXE");
|
||||||
if (exePath != null && File.Exists(exePath)) {
|
if (exePath != null && File.Exists(exePath)) {
|
||||||
applicationIcon = GetExeIcon(exePath, 0);
|
applicationIcon = GetExeIcon(exePath, 0);
|
||||||
|
WindowDetails.AddProcessToExcludeFromFreeze("outlook");
|
||||||
if (conf.OutlookAllowExportInMeetings) {
|
if (conf.OutlookAllowExportInMeetings) {
|
||||||
meetingIcon = GetExeIcon(exePath, 2);
|
meetingIcon = GetExeIcon(exePath, 2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,7 @@ namespace Greenshot.Destinations {
|
||||||
if (exePath != null && File.Exists(exePath)) {
|
if (exePath != null && File.Exists(exePath)) {
|
||||||
applicationIcon = GetExeIcon(exePath, 0);
|
applicationIcon = GetExeIcon(exePath, 0);
|
||||||
workbookIcon = GetExeIcon(exePath, 1);
|
workbookIcon = GetExeIcon(exePath, 1);
|
||||||
|
WindowDetails.AddProcessToExcludeFromFreeze("excel");
|
||||||
} else {
|
} else {
|
||||||
exePath = null;
|
exePath = null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,7 @@ namespace Greenshot.Destinations {
|
||||||
if (exePath != null && File.Exists(exePath)) {
|
if (exePath != null && File.Exists(exePath)) {
|
||||||
applicationIcon = GetExeIcon(exePath, 0);
|
applicationIcon = GetExeIcon(exePath, 0);
|
||||||
notebookIcon = GetExeIcon(exePath, 0);
|
notebookIcon = GetExeIcon(exePath, 0);
|
||||||
|
WindowDetails.AddProcessToExcludeFromFreeze("onenote");
|
||||||
} else {
|
} else {
|
||||||
exePath = null;
|
exePath = null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,7 @@ namespace Greenshot.Destinations {
|
||||||
if (exePath != null && File.Exists(exePath)) {
|
if (exePath != null && File.Exists(exePath)) {
|
||||||
applicationIcon = GetExeIcon(exePath, 0);
|
applicationIcon = GetExeIcon(exePath, 0);
|
||||||
presentationIcon = GetExeIcon(exePath, 1);
|
presentationIcon = GetExeIcon(exePath, 1);
|
||||||
|
WindowDetails.AddProcessToExcludeFromFreeze("powerpnt");
|
||||||
} else {
|
} else {
|
||||||
exePath = null;
|
exePath = null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,7 +107,10 @@ namespace Greenshot.Forms {
|
||||||
|
|
||||||
// Make sure we never capture the captureform
|
// Make sure we never capture the captureform
|
||||||
WindowDetails.RegisterIgnoreHandle(this.Handle);
|
WindowDetails.RegisterIgnoreHandle(this.Handle);
|
||||||
// TODO: Need to call unregister at close
|
// Unregister at close
|
||||||
|
this.FormClosing += delegate {
|
||||||
|
WindowDetails.UnregisterIgnoreHandle(this.Handle);
|
||||||
|
};
|
||||||
|
|
||||||
// set cursor location
|
// set cursor location
|
||||||
cursorPos = WindowCapture.GetCursorLocation();
|
cursorPos = WindowCapture.GetCursorLocation();
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
/*
|
|
||||||
* User: Robin
|
|
||||||
* Date: 05.04.2010
|
|
||||||
*/
|
|
||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using log4net.Util;
|
|
||||||
|
|
||||||
namespace Greenshot.Helpers {
|
|
||||||
/// <summary>
|
|
||||||
/// Description of Log4NET.
|
|
||||||
/// </summary>
|
|
||||||
public class SpecialFolderPatternConverter : PatternConverter {
|
|
||||||
override protected void Convert(TextWriter writer, object state) {
|
|
||||||
Environment.SpecialFolder specialFolder = (Environment.SpecialFolder)Enum.Parse(typeof(Environment.SpecialFolder), base.Option, true);
|
|
||||||
writer.Write(Environment.GetFolderPath(specialFolder));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -166,6 +166,13 @@ namespace GreenshotPlugin.Core {
|
||||||
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
|
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
|
||||||
private static List<IntPtr> ignoreHandles = new List<IntPtr>();
|
private static List<IntPtr> ignoreHandles = new List<IntPtr>();
|
||||||
private static Dictionary<string, Image> iconCache = new Dictionary<string, Image>();
|
private static Dictionary<string, Image> iconCache = new Dictionary<string, Image>();
|
||||||
|
private static List<string> excludeProcessesFromFreeze = new List<string>();
|
||||||
|
|
||||||
|
public static void AddProcessToExcludeFromFreeze(string processname) {
|
||||||
|
if (!excludeProcessesFromFreeze.Contains(processname)) {
|
||||||
|
excludeProcessesFromFreeze.Add(processname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal static bool isIgnoreHandle(IntPtr handle) {
|
internal static bool isIgnoreHandle(IntPtr handle) {
|
||||||
return ignoreHandles.Contains(handle);
|
return ignoreHandles.Contains(handle);
|
||||||
|
@ -223,13 +230,67 @@ namespace GreenshotPlugin.Core {
|
||||||
frozen = false;
|
frozen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string ProcessPath {
|
||||||
|
get {
|
||||||
|
if (Handle == IntPtr.Zero) {
|
||||||
|
// not a valid window handle
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
StringBuilder _PathBuffer = new StringBuilder(512);
|
||||||
|
// Get the process id
|
||||||
|
uint processid;
|
||||||
|
User32.GetWindowThreadProcessId(Handle, out processid);
|
||||||
|
|
||||||
|
// Try the GetModuleFileName method first since it's the fastest.
|
||||||
|
// May return ACCESS_DENIED (due to VM_READ flag) if the process is not owned by the current user.
|
||||||
|
// Will fail if we are compiled as x86 and we're trying to open a 64 bit process...not allowed.
|
||||||
|
IntPtr hprocess = Kernel32.OpenProcess(ProcessAccessFlags.QueryInformation | ProcessAccessFlags.VMRead, false, processid);
|
||||||
|
if (hprocess != IntPtr.Zero) {
|
||||||
|
try {
|
||||||
|
if (Kernel32.GetModuleFileNameEx(hprocess, IntPtr.Zero, _PathBuffer, (uint)_PathBuffer.Capacity) > 0) {
|
||||||
|
return _PathBuffer.ToString();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
Kernel32.CloseHandle(hprocess);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hprocess = Kernel32.OpenProcess(ProcessAccessFlags.QueryInformation, false, processid);
|
||||||
|
if (hprocess != IntPtr.Zero) {
|
||||||
|
try {
|
||||||
|
// Try this method for Vista or higher operating systems
|
||||||
|
uint size = (uint)_PathBuffer.Capacity;
|
||||||
|
if ((Environment.OSVersion.Version.Major >= 6) && (Kernel32.QueryFullProcessImageName(hprocess, 0, _PathBuffer, ref size) && (size > 0))) {
|
||||||
|
return _PathBuffer.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try the GetProcessImageFileName method
|
||||||
|
if (Kernel32.GetProcessImageFileName(hprocess, _PathBuffer, (uint)_PathBuffer.Capacity) > 0) {
|
||||||
|
string dospath = _PathBuffer.ToString();
|
||||||
|
foreach (string drive in Environment.GetLogicalDrives()) {
|
||||||
|
if (Kernel32.QueryDosDevice(drive.TrimEnd('\\'), _PathBuffer, (uint)_PathBuffer.Capacity) > 0) {
|
||||||
|
if (dospath.StartsWith(_PathBuffer.ToString())) {
|
||||||
|
return drive + dospath.Remove(0, _PathBuffer.Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
Kernel32.CloseHandle(hprocess);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the icon belonging to the process
|
/// Get the icon belonging to the process
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Image DisplayIcon {
|
public Image DisplayIcon {
|
||||||
get {
|
get {
|
||||||
try {
|
try {
|
||||||
string filename = Process.MainModule.FileName;
|
string filename = ProcessPath;
|
||||||
if (!iconCache.ContainsKey(filename)) {
|
if (!iconCache.ContainsKey(filename)) {
|
||||||
Image icon = null;
|
Image icon = null;
|
||||||
if (File.Exists(filename)) {
|
if (File.Exists(filename)) {
|
||||||
|
@ -244,6 +305,7 @@ namespace GreenshotPlugin.Core {
|
||||||
return iconCache[filename];
|
return iconCache[filename];
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
LOG.WarnFormat("Couldn't get icon for window {0} due to: {1}", Text, ex.Message);
|
LOG.WarnFormat("Couldn't get icon for window {0} due to: {1}", Text, ex.Message);
|
||||||
|
LOG.Warn(ex);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -1211,26 +1273,38 @@ namespace GreenshotPlugin.Core {
|
||||||
User32.SendMessage(Handle, (int)WindowsMessages.WM_VSCROLL, ptrWparam, ptrLparam);
|
User32.SendMessage(Handle, (int)WindowsMessages.WM_VSCROLL, ptrWparam, ptrLparam);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool CanFreezeOrUnfreeze(string titleOrProcessname) {
|
||||||
|
if (string.IsNullOrEmpty(titleOrProcessname)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (titleOrProcessname.ToLower().Contains("greenshot")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (string excludeProcess in excludeProcessesFromFreeze) {
|
||||||
|
if (titleOrProcessname.ToLower().Contains(excludeProcess)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Freezes the process belonging to the window
|
/// Freezes the process belonging to the window
|
||||||
/// Warning: Use only if no other way!!
|
/// Warning: Use only if no other way!!
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void FreezeWindow() {
|
private void FreezeWindow() {
|
||||||
Process proc = Process.GetProcessById(this.ProcessId.ToInt32());
|
Process proc = Process.GetProcessById(this.ProcessId.ToInt32());
|
||||||
|
string processName = proc.ProcessName;
|
||||||
if (proc.ProcessName == string.Empty){
|
if (!CanFreezeOrUnfreeze(processName)) {
|
||||||
|
LOG.DebugFormat("Not freezing {0}", processName);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (proc.ProcessName.ToLower().Contains("greenshot")) {
|
if (!CanFreezeOrUnfreeze(Text)) {
|
||||||
LOG.DebugFormat("Not freezing ourselves, process was: {0}", proc.ProcessName);
|
LOG.DebugFormat("Not freezing {0}", processName);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// TODO: Check Outlook, Office etc?
|
LOG.DebugFormat("Freezing process: {0}", processName);
|
||||||
if (proc.ProcessName.ToLower().Contains("outlook")) {
|
|
||||||
LOG.DebugFormat("Not freezing outlook due to Destinations, process was: {0}", proc.ProcessName);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
LOG.DebugFormat("Freezing process: {0}", proc.ProcessName);
|
|
||||||
|
|
||||||
foreach (ProcessThread pT in proc.Threads) {
|
foreach (ProcessThread pT in proc.Threads) {
|
||||||
IntPtr pOpenThread = Kernel32.OpenThread(ThreadAccess.SUSPEND_RESUME, false, (uint)pT.Id);
|
IntPtr pOpenThread = Kernel32.OpenThread(ThreadAccess.SUSPEND_RESUME, false, (uint)pT.Id);
|
||||||
|
@ -1249,14 +1323,16 @@ namespace GreenshotPlugin.Core {
|
||||||
public void UnfreezeWindow() {
|
public void UnfreezeWindow() {
|
||||||
Process proc = Process.GetProcessById(this.ProcessId.ToInt32());
|
Process proc = Process.GetProcessById(this.ProcessId.ToInt32());
|
||||||
|
|
||||||
if (proc.ProcessName == string.Empty) {
|
string processName = proc.ProcessName;
|
||||||
|
if (!CanFreezeOrUnfreeze(processName)) {
|
||||||
|
LOG.DebugFormat("Not unfreezing {0}", processName);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (proc.ProcessName.ToLower().Contains("greenshot")) {
|
if (!CanFreezeOrUnfreeze(Text)) {
|
||||||
LOG.DebugFormat("Not unfreezing ourselves, process was: {0}", proc.ProcessName);
|
LOG.DebugFormat("Not unfreezing {0}", processName);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LOG.DebugFormat("Unfreezing process: {0}", proc.ProcessName);
|
LOG.DebugFormat("Unfreezing process: {0}", processName);
|
||||||
|
|
||||||
foreach (ProcessThread pT in proc.Threads) {
|
foreach (ProcessThread pT in proc.Threads) {
|
||||||
IntPtr pOpenThread = Kernel32.OpenThread(ThreadAccess.SUSPEND_RESUME, false, (uint)pT.Id);
|
IntPtr pOpenThread = Kernel32.OpenThread(ThreadAccess.SUSPEND_RESUME, false, (uint)pT.Id);
|
||||||
|
|
|
@ -926,4 +926,18 @@ namespace GreenshotPlugin.UnmanagedHelpers {
|
||||||
SMTO_ABORTIFHUNG = 0x2,
|
SMTO_ABORTIFHUNG = 0x2,
|
||||||
SMTO_NOTIMEOUTIFNOTHUNG = 0x8
|
SMTO_NOTIMEOUTIFNOTHUNG = 0x8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
public enum ProcessAccessFlags : uint {
|
||||||
|
All = 0x001F0FFF,
|
||||||
|
Terminate = 0x00000001,
|
||||||
|
CreateThread = 0x00000002,
|
||||||
|
VMOperation = 0x00000008,
|
||||||
|
VMRead = 0x00000010,
|
||||||
|
VMWrite = 0x00000020,
|
||||||
|
DupHandle = 0x00000040,
|
||||||
|
SetInformation = 0x00000200,
|
||||||
|
QueryInformation = 0x00000400,
|
||||||
|
Synchronize = 0x00100000
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
*/
|
*/
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace GreenshotPlugin.UnmanagedHelpers {
|
namespace GreenshotPlugin.UnmanagedHelpers {
|
||||||
[Flags]
|
[Flags]
|
||||||
|
@ -48,11 +49,28 @@ namespace GreenshotPlugin.UnmanagedHelpers {
|
||||||
[return: MarshalAs(UnmanagedType.Bool)]
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
public static extern bool AllocConsole();
|
public static extern bool AllocConsole();
|
||||||
|
|
||||||
[DllImport("kernel32")]
|
[DllImport("kernel32", SetLastError = true)]
|
||||||
public static extern IntPtr OpenThread(ThreadAccess dwDesiredAccess, bool bInheritHandle, uint dwThreadId);
|
public static extern IntPtr OpenThread(ThreadAccess dwDesiredAccess, bool bInheritHandle, uint dwThreadId);
|
||||||
[DllImport("kernel32")]
|
[DllImport("kernel32", SetLastError = true)]
|
||||||
public static extern uint SuspendThread(IntPtr hThread);
|
public static extern uint SuspendThread(IntPtr hThread);
|
||||||
[DllImport("kernel32")]
|
[DllImport("kernel32", SetLastError = true)]
|
||||||
public static extern int ResumeThread(IntPtr hThread);
|
public static extern int ResumeThread(IntPtr hThread);
|
||||||
|
[DllImport("kernel32", SetLastError = true)]
|
||||||
|
public static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, bool bInheritHandle, uint dwProcessId);
|
||||||
|
[DllImport("kernel32", SetLastError = true)]
|
||||||
|
public static extern bool QueryFullProcessImageName(IntPtr hProcess, uint dwFlags, StringBuilder lpExeName, ref uint lpdwSize);
|
||||||
|
[DllImport("kernel32", SetLastError = true)]
|
||||||
|
public static extern uint QueryDosDevice(string lpDeviceName, StringBuilder lpTargetPath, uint uuchMax);
|
||||||
|
[DllImport("kernel32", SetLastError = true)]
|
||||||
|
public static extern IntPtr GetModuleHandle(string lpModuleName);
|
||||||
|
[DllImport("kernel32", SetLastError = true)]
|
||||||
|
public static extern bool CloseHandle(IntPtr hObject);
|
||||||
|
|
||||||
|
// TODO: Move to PSAPI.cs ??
|
||||||
|
[DllImport("psapi", SetLastError = true)]
|
||||||
|
public static extern uint GetModuleFileNameEx(IntPtr hProcess, IntPtr hModule, StringBuilder lpFilename, uint nSize);
|
||||||
|
[DllImport("psapi", SetLastError = true)]
|
||||||
|
public static extern uint GetProcessImageFileName(IntPtr hProcess, StringBuilder lpImageFileName, uint nSize);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue