mirror of
https://github.com/greenshot/greenshot
synced 2025-07-30 11:40:40 -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");
|
||||
if (exePath != null && File.Exists(exePath)) {
|
||||
applicationIcon = GetExeIcon(exePath, 0);
|
||||
WindowDetails.AddProcessToExcludeFromFreeze("outlook");
|
||||
if (conf.OutlookAllowExportInMeetings) {
|
||||
meetingIcon = GetExeIcon(exePath, 2);
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ namespace Greenshot.Destinations {
|
|||
if (exePath != null && File.Exists(exePath)) {
|
||||
applicationIcon = GetExeIcon(exePath, 0);
|
||||
workbookIcon = GetExeIcon(exePath, 1);
|
||||
WindowDetails.AddProcessToExcludeFromFreeze("excel");
|
||||
} else {
|
||||
exePath = null;
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@ namespace Greenshot.Destinations {
|
|||
if (exePath != null && File.Exists(exePath)) {
|
||||
applicationIcon = GetExeIcon(exePath, 0);
|
||||
notebookIcon = GetExeIcon(exePath, 0);
|
||||
WindowDetails.AddProcessToExcludeFromFreeze("onenote");
|
||||
} else {
|
||||
exePath = null;
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ namespace Greenshot.Destinations {
|
|||
if (exePath != null && File.Exists(exePath)) {
|
||||
applicationIcon = GetExeIcon(exePath, 0);
|
||||
presentationIcon = GetExeIcon(exePath, 1);
|
||||
WindowDetails.AddProcessToExcludeFromFreeze("powerpnt");
|
||||
} else {
|
||||
exePath = null;
|
||||
}
|
||||
|
|
|
@ -107,7 +107,10 @@ namespace Greenshot.Forms {
|
|||
|
||||
// Make sure we never capture the captureform
|
||||
WindowDetails.RegisterIgnoreHandle(this.Handle);
|
||||
// TODO: Need to call unregister at close
|
||||
// Unregister at close
|
||||
this.FormClosing += delegate {
|
||||
WindowDetails.UnregisterIgnoreHandle(this.Handle);
|
||||
};
|
||||
|
||||
// set cursor location
|
||||
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 List<IntPtr> ignoreHandles = new List<IntPtr>();
|
||||
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) {
|
||||
return ignoreHandles.Contains(handle);
|
||||
|
@ -223,13 +230,67 @@ namespace GreenshotPlugin.Core {
|
|||
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>
|
||||
/// Get the icon belonging to the process
|
||||
/// </summary>
|
||||
public Image DisplayIcon {
|
||||
get {
|
||||
try {
|
||||
string filename = Process.MainModule.FileName;
|
||||
string filename = ProcessPath;
|
||||
if (!iconCache.ContainsKey(filename)) {
|
||||
Image icon = null;
|
||||
if (File.Exists(filename)) {
|
||||
|
@ -244,6 +305,7 @@ namespace GreenshotPlugin.Core {
|
|||
return iconCache[filename];
|
||||
} catch (Exception ex) {
|
||||
LOG.WarnFormat("Couldn't get icon for window {0} due to: {1}", Text, ex.Message);
|
||||
LOG.Warn(ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -1211,26 +1273,38 @@ namespace GreenshotPlugin.Core {
|
|||
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>
|
||||
/// Freezes the process belonging to the window
|
||||
/// Warning: Use only if no other way!!
|
||||
/// </summary>
|
||||
private void FreezeWindow() {
|
||||
Process proc = Process.GetProcessById(this.ProcessId.ToInt32());
|
||||
|
||||
if (proc.ProcessName == string.Empty){
|
||||
string processName = proc.ProcessName;
|
||||
if (!CanFreezeOrUnfreeze(processName)) {
|
||||
LOG.DebugFormat("Not freezing {0}", processName);
|
||||
return;
|
||||
}
|
||||
if (proc.ProcessName.ToLower().Contains("greenshot")) {
|
||||
LOG.DebugFormat("Not freezing ourselves, process was: {0}", proc.ProcessName);
|
||||
if (!CanFreezeOrUnfreeze(Text)) {
|
||||
LOG.DebugFormat("Not freezing {0}", processName);
|
||||
return;
|
||||
}
|
||||
// TODO: Check Outlook, Office etc?
|
||||
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);
|
||||
LOG.DebugFormat("Freezing process: {0}", processName);
|
||||
|
||||
foreach (ProcessThread pT in proc.Threads) {
|
||||
IntPtr pOpenThread = Kernel32.OpenThread(ThreadAccess.SUSPEND_RESUME, false, (uint)pT.Id);
|
||||
|
@ -1249,14 +1323,16 @@ namespace GreenshotPlugin.Core {
|
|||
public void UnfreezeWindow() {
|
||||
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;
|
||||
}
|
||||
if (proc.ProcessName.ToLower().Contains("greenshot")) {
|
||||
LOG.DebugFormat("Not unfreezing ourselves, process was: {0}", proc.ProcessName);
|
||||
if (!CanFreezeOrUnfreeze(Text)) {
|
||||
LOG.DebugFormat("Not unfreezing {0}", processName);
|
||||
return;
|
||||
}
|
||||
LOG.DebugFormat("Unfreezing process: {0}", proc.ProcessName);
|
||||
LOG.DebugFormat("Unfreezing process: {0}", processName);
|
||||
|
||||
foreach (ProcessThread pT in proc.Threads) {
|
||||
IntPtr pOpenThread = Kernel32.OpenThread(ThreadAccess.SUSPEND_RESUME, false, (uint)pT.Id);
|
||||
|
|
|
@ -926,4 +926,18 @@ namespace GreenshotPlugin.UnmanagedHelpers {
|
|||
SMTO_ABORTIFHUNG = 0x2,
|
||||
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.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace GreenshotPlugin.UnmanagedHelpers {
|
||||
[Flags]
|
||||
|
@ -48,11 +49,28 @@ namespace GreenshotPlugin.UnmanagedHelpers {
|
|||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool AllocConsole();
|
||||
|
||||
[DllImport("kernel32")]
|
||||
[DllImport("kernel32", SetLastError = true)]
|
||||
public static extern IntPtr OpenThread(ThreadAccess dwDesiredAccess, bool bInheritHandle, uint dwThreadId);
|
||||
[DllImport("kernel32")]
|
||||
[DllImport("kernel32", SetLastError = true)]
|
||||
public static extern uint SuspendThread(IntPtr hThread);
|
||||
[DllImport("kernel32")]
|
||||
[DllImport("kernel32", SetLastError = true)]
|
||||
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