Code quality changes for stability and reduced memory usage.

This commit is contained in:
RKrom 2014-06-13 12:18:59 +02:00
parent eb042dca58
commit 08216b09c0
21 changed files with 342 additions and 316 deletions

View file

@ -60,7 +60,7 @@ namespace Greenshot.Drawing {
} }
} }
public virtual void Dispose() { public void Dispose() {
Dispose(true); Dispose(true);
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
} }

View file

@ -133,7 +133,7 @@ namespace Greenshot.Drawing {
/// <summary> /// <summary>
/// Make sure this element is no longer referenced from the surface /// Make sure this element is no longer referenced from the surface
/// </summary> /// </summary>
public override void Dispose() { public new void Dispose() {
((Surface)Parent).RemoveStepLabel(this); ((Surface)Parent).RemoveStepLabel(this);
base.Dispose(); base.Dispose();
} }

View file

@ -317,7 +317,9 @@ namespace Greenshot {
case Keys.L: case Keys.L:
try { try {
if (File.Exists(MainForm.LogFileLocation)) { if (File.Exists(MainForm.LogFileLocation)) {
Process.Start("\"" + MainForm.LogFileLocation + "\""); using (Process.Start("\"" + MainForm.LogFileLocation + "\"")) {
// nothing to do, just using dispose to cleanup
}
} else { } else {
MessageBox.Show("Greenshot can't find the logfile, it should have been here: " + MainForm.LogFileLocation); MessageBox.Show("Greenshot can't find the logfile, it should have been here: " + MainForm.LogFileLocation);
} }
@ -327,7 +329,8 @@ namespace Greenshot {
break; break;
case Keys.I: case Keys.I:
try { try {
Process.Start("\"" + IniConfig.ConfigLocation + "\""); using (Process.Start("\"" + IniConfig.ConfigLocation + "\"")) {
}
} catch (Exception) { } catch (Exception) {
MessageBox.Show("Couldn't open the greenshot.ini, it's located here: " + IniConfig.ConfigLocation, "Error opening greeenshot.ini", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); MessageBox.Show("Couldn't open the greenshot.ini, it's located here: " + IniConfig.ConfigLocation, "Error opening greeenshot.ini", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
} }

View file

@ -925,10 +925,11 @@ namespace Greenshot {
ProcessStartInfo psi = new ProcessStartInfo("explorer"); ProcessStartInfo psi = new ProcessStartInfo("explorer");
psi.Arguments = Path.GetDirectoryName(surface.LastSaveFullPath); psi.Arguments = Path.GetDirectoryName(surface.LastSaveFullPath);
psi.UseShellExecute = false; psi.UseShellExecute = false;
Process p = new Process(); using (Process p = new Process()) {
p.StartInfo = psi; p.StartInfo = psi;
p.Start(); p.Start();
} }
}
#endregion #endregion
private void bindFieldControls() { private void bindFieldControls() {

View file

@ -239,18 +239,25 @@ namespace Greenshot {
StringBuilder instanceInfo = new StringBuilder(); StringBuilder instanceInfo = new StringBuilder();
bool matchedThisProcess = false; bool matchedThisProcess = false;
int index = 1; int index = 1;
int currentProcessId;
using (Process currentProcess = Process.GetCurrentProcess()) {
currentProcessId = currentProcess.Id;
}
foreach (Process greenshotProcess in Process.GetProcessesByName("greenshot")) { foreach (Process greenshotProcess in Process.GetProcessesByName("greenshot")) {
try { try {
instanceInfo.Append(index++ + ": ").AppendLine(Kernel32.GetProcessPath(new IntPtr(greenshotProcess.Id))); instanceInfo.Append(index++ + ": ").AppendLine(Kernel32.GetProcessPath(greenshotProcess.Id));
if (Process.GetCurrentProcess().Id == greenshotProcess.Id) { if (currentProcessId == greenshotProcess.Id) {
matchedThisProcess = true; matchedThisProcess = true;
} }
} catch (Exception ex) { } catch (Exception ex) {
LOG.Debug(ex); LOG.Debug(ex);
} }
greenshotProcess.Dispose();
} }
if (!matchedThisProcess) { if (!matchedThisProcess) {
instanceInfo.Append(index + ": ").AppendLine(Kernel32.GetProcessPath(new IntPtr(Process.GetCurrentProcess().Id))); using (Process currentProcess = Process.GetCurrentProcess()) {
instanceInfo.Append(index + ": ").AppendLine(Kernel32.GetProcessPath(currentProcess.Id));
}
} }
MessageBox.Show(Language.GetString(LangKey.error_multipleinstances) + "\r\n" + instanceInfo, Language.GetString(LangKey.error)); MessageBox.Show(Language.GetString(LangKey.error_multipleinstances) + "\r\n" + instanceInfo, Language.GetString(LangKey.error));
} }
@ -1249,7 +1256,8 @@ namespace Greenshot {
if (path != null) { if (path != null) {
try { try {
Process.Start(path); using (Process process = Process.Start(path)) {
}
} catch (Exception ex) { } catch (Exception ex) {
// Make sure we show what we tried to open in the exception // Make sure we show what we tried to open in the exception
ex.Data.Add("path", path); ex.Data.Add("path", path);
@ -1382,7 +1390,9 @@ namespace Greenshot {
private void BackgroundWorkerTimerTick(object sender, EventArgs e) { private void BackgroundWorkerTimerTick(object sender, EventArgs e) {
if (_conf.MinimizeWorkingSetSize) { if (_conf.MinimizeWorkingSetSize) {
LOG.Info("Calling EmptyWorkingSet"); LOG.Info("Calling EmptyWorkingSet");
PsAPI.EmptyWorkingSet(Process.GetCurrentProcess().Handle); using (Process currentProcess = Process.GetCurrentProcess()) {
PsAPI.EmptyWorkingSet(currentProcess.Handle);
}
} }
if (UpdateHelper.IsUpdateCheckNeeded()) { if (UpdateHelper.IsUpdateCheckNeeded()) {
LOG.Debug("BackgroundWorkerTimerTick checking for update"); LOG.Debug("BackgroundWorkerTimerTick checking for update");

View file

@ -596,9 +596,10 @@ namespace Greenshot.Helpers {
ProcessStartInfo psi = new ProcessStartInfo("explorer.exe"); ProcessStartInfo psi = new ProcessStartInfo("explorer.exe");
psi.Arguments = Path.GetDirectoryName(surface.LastSaveFullPath); psi.Arguments = Path.GetDirectoryName(surface.LastSaveFullPath);
psi.UseShellExecute = false; psi.UseShellExecute = false;
Process p = new Process(); using (Process p = new Process()) {
p.StartInfo = psi; p.StartInfo = psi;
p.Start(); p.Start();
}
} catch (Exception ex) { } catch (Exception ex) {
errorMessage = ex.Message; errorMessage = ex.Message;
} }
@ -611,9 +612,10 @@ namespace Greenshot.Helpers {
ProcessStartInfo psi = new ProcessStartInfo(explorerPath); ProcessStartInfo psi = new ProcessStartInfo(explorerPath);
psi.Arguments = Path.GetDirectoryName(surface.LastSaveFullPath); psi.Arguments = Path.GetDirectoryName(surface.LastSaveFullPath);
psi.UseShellExecute = false; psi.UseShellExecute = false;
Process p = new Process(); using (Process p = new Process()) {
p.StartInfo = psi; p.StartInfo = psi;
p.Start(); p.Start();
}
errorMessage = null; errorMessage = null;
} }
} catch { } catch {
@ -783,7 +785,7 @@ namespace Greenshot.Helpers {
// When Vista & DWM (Aero) enabled // When Vista & DWM (Aero) enabled
bool dwmEnabled = DWM.isDWMEnabled(); bool dwmEnabled = DWM.isDWMEnabled();
// get process name to be able to exclude certain processes from certain capture modes // get process name to be able to exclude certain processes from certain capture modes
Process process = windowToCapture.Process; using (Process process = windowToCapture.Process) {
bool isAutoMode = windowCaptureMode == WindowCaptureMode.Auto; bool isAutoMode = windowCaptureMode == WindowCaptureMode.Auto;
// For WindowCaptureMode.Auto we check: // For WindowCaptureMode.Auto we check:
// 1) Is window IE, use IE Capture // 1) Is window IE, use IE Capture
@ -930,6 +932,7 @@ namespace Greenshot.Helpers {
break; break;
} }
} }
}
if (captureForWindow != null) { if (captureForWindow != null) {
if (windowToCapture != null) { if (windowToCapture != null) {

View file

@ -191,7 +191,7 @@ namespace Greenshot.Helpers {
/// Contains data and other information associated with data /// Contains data and other information associated with data
/// which has been sent from another application. /// which has been sent from another application.
/// </summary> /// </summary>
public class CopyDataReceivedEventArgs { public class CopyDataReceivedEventArgs : EventArgs {
private string channelName = ""; private string channelName = "";
private object data = null; private object data = null;
private DateTime sent; private DateTime sent;
@ -365,12 +365,12 @@ namespace Greenshot.Helpers {
[DllImport("user32", CharSet=CharSet.Unicode, SetLastError = true)] [DllImport("user32", CharSet=CharSet.Unicode, SetLastError = true)]
private extern static IntPtr GetProp(IntPtr hwnd, string lpString); private extern static IntPtr GetProp(IntPtr hwnd, string lpString);
[DllImport("user32", CharSet = CharSet.Unicode, SetLastError = true)] [DllImport("user32", CharSet = CharSet.Unicode, SetLastError = true)]
private extern static IntPtr SetProp(IntPtr hwnd, string lpString, int hData); private extern static bool SetProp(IntPtr hwnd, string lpString, IntPtr hData);
[DllImport("user32", CharSet = CharSet.Unicode, SetLastError = true)] [DllImport("user32", CharSet = CharSet.Unicode, SetLastError = true)]
private extern static IntPtr RemoveProp(IntPtr hwnd, string lpString); private extern static IntPtr RemoveProp(IntPtr hwnd, string lpString);
[DllImport("user32", CharSet = CharSet.Unicode, SetLastError = true)] [DllImport("user32", CharSet = CharSet.Unicode, SetLastError = true)]
private extern static IntPtr SendMessage(IntPtr hwnd, int wMsg, int wParam, ref COPYDATASTRUCT lParam); private extern static IntPtr SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, ref COPYDATASTRUCT lParam);
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
private struct COPYDATASTRUCT { private struct COPYDATASTRUCT {
@ -448,7 +448,7 @@ namespace Greenshot.Helpers {
cds.cbData = dataSize; cds.cbData = dataSize;
cds.dwData = IntPtr.Zero; cds.dwData = IntPtr.Zero;
cds.lpData = ptrData; cds.lpData = ptrData;
SendMessage(window.Handle, WM_COPYDATA, (int)owner.Handle, ref cds); SendMessage(window.Handle, WM_COPYDATA, owner.Handle, ref cds);
recipients += (Marshal.GetLastWin32Error() == 0 ? 1 : 0); recipients += (Marshal.GetLastWin32Error() == 0 ? 1 : 0);
} }
} }
@ -464,7 +464,7 @@ namespace Greenshot.Helpers {
private void addChannel() { private void addChannel() {
// Tag this window with property "channelName" // Tag this window with property "channelName"
SetProp(owner.Handle, channelName, (int)owner.Handle); SetProp(owner.Handle, channelName, owner.Handle);
} }
private void removeChannel() { private void removeChannel() {
@ -515,7 +515,7 @@ namespace Greenshot.Helpers {
} }
~CopyDataChannel() { ~CopyDataChannel() {
Dispose(); Dispose(false);
} }
} }

View file

@ -504,7 +504,7 @@ namespace Greenshot.Helpers {
public IntPtr EntryID = IntPtr.Zero; public IntPtr EntryID = IntPtr.Zero;
} }
[DllImport("MAPI32.DLL", SetLastError = true)] [DllImport("MAPI32.DLL", SetLastError = true, CharSet=CharSet.Unicode)]
public static extern int MAPISendMail(IntPtr session, IntPtr hwnd, MapiMessage message, int flg, int rsv); public static extern int MAPISendMail(IntPtr session, IntPtr hwnd, MapiMessage message, int flg, int rsv);
#endregion Structs #endregion Structs

View file

@ -128,7 +128,7 @@ namespace ExternalCommand {
string arguments = config.arguments[commando]; string arguments = config.arguments[commando];
output = null; output = null;
if (commandline != null && commandline.Length > 0) { if (commandline != null && commandline.Length > 0) {
Process p = new Process(); using (Process p = new Process()) {
p.StartInfo.FileName = commandline; p.StartInfo.FileName = commandline;
p.StartInfo.Arguments = String.Format(arguments, fullPath); p.StartInfo.Arguments = String.Format(arguments, fullPath);
p.StartInfo.UseShellExecute = false; p.StartInfo.UseShellExecute = false;
@ -146,6 +146,7 @@ namespace ExternalCommand {
LOG.Info("Finished : " + p.StartInfo.FileName + " " + p.StartInfo.Arguments); LOG.Info("Finished : " + p.StartInfo.FileName + " " + p.StartInfo.Arguments);
return p.ExitCode; return p.ExitCode;
} }
}
return -1; return -1;
} }
} }

View file

@ -182,11 +182,12 @@ namespace GreenshotOCR {
processStartInfo.CreateNoWindow = true; processStartInfo.CreateNoWindow = true;
processStartInfo.RedirectStandardOutput = true; processStartInfo.RedirectStandardOutput = true;
processStartInfo.UseShellExecute = false; processStartInfo.UseShellExecute = false;
Process process = Process.Start(processStartInfo); using (Process process = Process.Start(processStartInfo)) {
process.WaitForExit(30*1000); process.WaitForExit(30 * 1000);
if (process.ExitCode == 0) { if (process.ExitCode == 0) {
text = process.StandardOutput.ReadToEnd(); text = process.StandardOutput.ReadToEnd();
} }
}
} catch (Exception e) { } catch (Exception e) {
LOG.Error("Error while calling Microsoft Office Document Imaging (MODI) to OCR: ", e); LOG.Error("Error while calling Microsoft Office Document Imaging (MODI) to OCR: ", e);
} finally { } finally {
@ -215,10 +216,10 @@ namespace GreenshotOCR {
private bool HasMODI() { private bool HasMODI() {
try { try {
Process process = Process.Start(OCR_COMMAND, "-c"); using (Process process = Process.Start(OCR_COMMAND, "-c")) {
process.WaitForExit(); process.WaitForExit();
int errorCode = process.ExitCode; return process.ExitCode == 0;
return errorCode == 0; }
} catch(Exception e) { } catch(Exception e) {
LOG.DebugFormat("Error trying to initiate MODI: {0}", e.Message); LOG.DebugFormat("Error trying to initiate MODI: {0}", e.Message);
} }

View file

@ -100,10 +100,10 @@ EndSelection:<<<<<<<4
try { try {
IntPtr hWnd = User32.GetClipboardOwner(); IntPtr hWnd = User32.GetClipboardOwner();
if (hWnd != IntPtr.Zero) { if (hWnd != IntPtr.Zero) {
IntPtr pid = IntPtr.Zero; int pid;
IntPtr tid = User32.GetWindowThreadProcessId( hWnd, out pid); User32.GetWindowThreadProcessId( hWnd, out pid);
Process me = Process.GetCurrentProcess(); using (Process me = Process.GetCurrentProcess())
Process ownerProcess = Process.GetProcessById( pid.ToInt32() ); 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
@ -115,6 +115,7 @@ EndSelection:<<<<<<<4
} }
} }
} }
}
} 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);
} }

View file

@ -44,13 +44,13 @@ namespace GreenshotPlugin.Core {
using (MemoryStream ms = new MemoryStream()) { using (MemoryStream ms = new MemoryStream()) {
byte[] rgbIV = Encoding.ASCII.GetBytes(RGBIV); byte[] rgbIV = Encoding.ASCII.GetBytes(RGBIV);
byte[] key = Encoding.ASCII.GetBytes(KEY); byte[] key = Encoding.ASCII.GetBytes(KEY);
CryptoStream cs = new CryptoStream(ms, rijn.CreateEncryptor(key, rgbIV), CryptoStreamMode.Write); using (CryptoStream cs = new CryptoStream(ms, rijn.CreateEncryptor(key, rgbIV), CryptoStreamMode.Write)) {
cs.Write(clearTextBytes, 0, clearTextBytes.Length); cs.Write(clearTextBytes, 0, clearTextBytes.Length);
cs.FlushFinalBlock();
cs.Close();
returnValue = Convert.ToBase64String(ms.ToArray()); returnValue = Convert.ToBase64String(ms.ToArray());
} }
}
} catch (Exception ex) { } catch (Exception ex) {
LOG.ErrorFormat("Error encrypting, error: ", ex.Message); LOG.ErrorFormat("Error encrypting, error: ", ex.Message);
} }
@ -73,14 +73,13 @@ namespace GreenshotPlugin.Core {
byte[] rgbIV = Encoding.ASCII.GetBytes(RGBIV); byte[] rgbIV = Encoding.ASCII.GetBytes(RGBIV);
byte[] key = Encoding.ASCII.GetBytes(KEY); byte[] key = Encoding.ASCII.GetBytes(KEY);
CryptoStream cs = new CryptoStream(ms, rijn.CreateDecryptor(key, rgbIV), using (CryptoStream cs = new CryptoStream(ms, rijn.CreateDecryptor(key, rgbIV), CryptoStreamMode.Write)) {
CryptoStreamMode.Write);
cs.Write(encryptedTextBytes, 0, encryptedTextBytes.Length); cs.Write(encryptedTextBytes, 0, encryptedTextBytes.Length);
cs.FlushFinalBlock();
cs.Close();
returnValue = Encoding.ASCII.GetString(ms.ToArray()); returnValue = Encoding.ASCII.GetString(ms.ToArray());
} }
}
} catch (Exception ex) { } catch (Exception ex) {
LOG.ErrorFormat("Error decrypting {0}, error: ", EncryptedText, ex.Message); LOG.ErrorFormat("Error decrypting {0}, error: ", EncryptedText, ex.Message);
} }

View file

@ -250,7 +250,7 @@ namespace GreenshotPlugin.Core {
processStartInfo.RedirectStandardOutput = true; processStartInfo.RedirectStandardOutput = true;
processStartInfo.RedirectStandardError = true; processStartInfo.RedirectStandardError = true;
processStartInfo.UseShellExecute = false; processStartInfo.UseShellExecute = false;
Process process = Process.Start(processStartInfo); using (Process process = Process.Start(processStartInfo)) {
if (process != null) { if (process != null) {
process.WaitForExit(); process.WaitForExit();
if (process.ExitCode == 0) { if (process.ExitCode == 0) {
@ -266,6 +266,7 @@ namespace GreenshotPlugin.Core {
LOG.ErrorFormat("Output: {0}", process.StandardOutput.ReadToEnd()); LOG.ErrorFormat("Output: {0}", process.StandardOutput.ReadToEnd());
LOG.ErrorFormat("Error: {0}", process.StandardError.ReadToEnd()); LOG.ErrorFormat("Error: {0}", process.StandardError.ReadToEnd());
} }
}
} catch (Exception e) { } catch (Exception e) {
LOG.Error("Error while processing PNG image: ", e); LOG.Error("Error while processing PNG image: ", e);
} finally { } finally {

View file

@ -427,14 +427,14 @@ namespace GreenshotPlugin.Core {
foreach (LanguageFile deleteFile in deleteList) { foreach (LanguageFile deleteFile in deleteList) {
currentFiles.Remove(deleteFile); currentFiles.Remove(deleteFile);
} }
LOG.InfoFormat("Added language {0} from: {1}", languageFile.Description, languageFile.Filepath); LOG.InfoFormat("Added language definition {0} from: {1}", languageFile.Description, languageFile.Filepath);
currentFiles.Add(languageFile); currentFiles.Add(languageFile);
} }
} else { } else {
currentFiles = new List<LanguageFile>(); currentFiles = new List<LanguageFile>();
currentFiles.Add(languageFile); currentFiles.Add(languageFile);
languageFiles.Add(languageFile.Ietf, currentFiles); languageFiles.Add(languageFile.Ietf, currentFiles);
LOG.InfoFormat("Added language {0} from: {1}", languageFile.Description, languageFile.Filepath); LOG.InfoFormat("Added language definition {0} from: {1}", languageFile.Description, languageFile.Filepath);
} }
} }
} catch (DirectoryNotFoundException) { } catch (DirectoryNotFoundException) {

View file

@ -91,7 +91,7 @@ namespace GreenshotPlugin.Core {
public WindowsEnumerator GetWindows(IntPtr hWndParent, string classname) { public WindowsEnumerator GetWindows(IntPtr hWndParent, string classname) {
items = new List<WindowDetails>(); items = new List<WindowDetails>();
List<WindowDetails> windows = new List<WindowDetails>(); List<WindowDetails> windows = new List<WindowDetails>();
User32.EnumChildWindows(hWndParent, new EnumWindowsProc(WindowEnum), 0); User32.EnumChildWindows(hWndParent, new EnumWindowsProc(WindowEnum), IntPtr.Zero);
bool hasParent = !IntPtr.Zero.Equals(hWndParent); bool hasParent = !IntPtr.Zero.Equals(hWndParent);
string parentText = null; string parentText = null;
@ -161,7 +161,6 @@ namespace GreenshotPlugin.Core {
/// Provides details about a Window returned by the /// Provides details about a Window returned by the
/// enumeration /// enumeration
/// </summary> /// </summary>
[SuppressMessage("Microsoft.Design", "CA1049:TypesThatOwnNativeResourcesShouldBeDisposable")]
public class WindowDetails : IEquatable<WindowDetails>{ public class WindowDetails : IEquatable<WindowDetails>{
private const string METRO_WINDOWS_CLASS = "Windows.UI.Core.CoreWindow"; private const string METRO_WINDOWS_CLASS = "Windows.UI.Core.CoreWindow";
private const string METRO_APPLAUNCHER_CLASS = "ImmersiveLauncher"; private const string METRO_APPLAUNCHER_CLASS = "ImmersiveLauncher";
@ -281,7 +280,7 @@ namespace GreenshotPlugin.Core {
return string.Empty; return string.Empty;
} }
// Get the process id // Get the process id
IntPtr processid; int processid;
User32.GetWindowThreadProcessId(Handle, out processid); User32.GetWindowThreadProcessId(Handle, out processid);
return Kernel32.GetProcessPath(processid); return Kernel32.GetProcessPath(processid);
} }
@ -731,9 +730,9 @@ namespace GreenshotPlugin.Core {
} }
} }
public IntPtr ProcessId { public int ProcessId {
get { get {
IntPtr processId; int processId;
User32.GetWindowThreadProcessId(Handle, out processId); User32.GetWindowThreadProcessId(Handle, out processId);
return processId; return processId;
} }
@ -742,9 +741,9 @@ namespace GreenshotPlugin.Core {
public Process Process { public Process Process {
get { get {
try { try {
IntPtr processId; int processId;
User32.GetWindowThreadProcessId(Handle, out processId); User32.GetWindowThreadProcessId(Handle, out processId);
Process process = Process.GetProcessById(processId.ToInt32()); Process process = Process.GetProcessById(processId);
if (process != null) { if (process != null) {
return process; return process;
} }
@ -866,7 +865,7 @@ namespace GreenshotPlugin.Core {
return (WindowStyleFlags)User32.GetWindowLongWrapper(hWnd, (int)WindowLongIndex.GWL_STYLE); return (WindowStyleFlags)User32.GetWindowLongWrapper(hWnd, (int)WindowLongIndex.GWL_STYLE);
} }
set { set {
User32.SetWindowLongWrapper(hWnd, (int)WindowLongIndex.GWL_STYLE, (uint)value); User32.SetWindowLongWrapper(hWnd, (int)WindowLongIndex.GWL_STYLE, new IntPtr((uint)value));
} }
} }
@ -892,7 +891,7 @@ namespace GreenshotPlugin.Core {
return (ExtendedWindowStyleFlags)User32.GetWindowLongWrapper(hWnd, (int)WindowLongIndex.GWL_EXSTYLE); return (ExtendedWindowStyleFlags)User32.GetWindowLongWrapper(hWnd, (int)WindowLongIndex.GWL_EXSTYLE);
} }
set { set {
User32.SetWindowLongWrapper(hWnd, (int)WindowLongIndex.GWL_EXSTYLE, (uint)value); User32.SetWindowLongWrapper(hWnd, (int)WindowLongIndex.GWL_EXSTYLE, new IntPtr((uint)value));
} }
} }
@ -992,12 +991,14 @@ namespace GreenshotPlugin.Core {
// check if the capture fits // check if the capture fits
if (!doesCaptureFit) { if (!doesCaptureFit) {
// if GDI is allowed.. (a screenshot won't be better than we comes if we continue) // if GDI is allowed.. (a screenshot won't be better than we comes if we continue)
if (!isMetroApp && WindowCapture.isGDIAllowed(Process)) { using (Process thisWindowProcess = Process) {
if (!isMetroApp && WindowCapture.isGDIAllowed(thisWindowProcess)) {
// we return null which causes the capturing code to try another method. // we return null which causes the capturing code to try another method.
return null; return null;
} }
} }
} }
}
// Prepare the displaying of the Thumbnail // Prepare the displaying of the Thumbnail
DWM_THUMBNAIL_PROPERTIES props = new DWM_THUMBNAIL_PROPERTIES(); DWM_THUMBNAIL_PROPERTIES props = new DWM_THUMBNAIL_PROPERTIES();
@ -1292,7 +1293,8 @@ namespace GreenshotPlugin.Core {
/// Warning: Use only if no other way!! /// Warning: Use only if no other way!!
/// </summary> /// </summary>
private bool FreezeWindow() { private bool FreezeWindow() {
Process proc = Process.GetProcessById(ProcessId.ToInt32()); bool frozen = false;
using (Process proc = Process.GetProcessById(ProcessId)) {
string processName = proc.ProcessName; string processName = proc.ProcessName;
if (!CanFreezeOrUnfreeze(processName)) { if (!CanFreezeOrUnfreeze(processName)) {
LOG.DebugFormat("Not freezing {0}", processName); LOG.DebugFormat("Not freezing {0}", processName);
@ -1304,7 +1306,6 @@ namespace GreenshotPlugin.Core {
} }
LOG.DebugFormat("Freezing process: {0}", processName); LOG.DebugFormat("Freezing process: {0}", processName);
bool frozen = false;
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);
@ -1314,6 +1315,8 @@ namespace GreenshotPlugin.Core {
} }
frozen = true; frozen = true;
Kernel32.SuspendThread(pOpenThread); Kernel32.SuspendThread(pOpenThread);
pT.Dispose();
}
} }
return frozen; return frozen;
} }
@ -1322,8 +1325,7 @@ namespace GreenshotPlugin.Core {
/// Unfreeze the process belonging to the window /// Unfreeze the process belonging to the window
/// </summary> /// </summary>
public void UnfreezeWindow() { public void UnfreezeWindow() {
Process proc = Process.GetProcessById(ProcessId.ToInt32()); using (Process proc = Process.GetProcessById(ProcessId)) {
string processName = proc.ProcessName; string processName = proc.ProcessName;
if (!CanFreezeOrUnfreeze(processName)) { if (!CanFreezeOrUnfreeze(processName)) {
LOG.DebugFormat("Not unfreezing {0}", processName); LOG.DebugFormat("Not unfreezing {0}", processName);
@ -1345,6 +1347,7 @@ namespace GreenshotPlugin.Core {
Kernel32.ResumeThread(pOpenThread); Kernel32.ResumeThread(pOpenThread);
} }
} }
}
/// <summary> /// <summary>
/// Return an Image representating the Window! /// Return an Image representating the Window!
@ -1363,15 +1366,12 @@ namespace GreenshotPlugin.Core {
} }
returnImage = new Bitmap(windowRect.Width, windowRect.Height, pixelFormat); returnImage = new Bitmap(windowRect.Width, windowRect.Height, pixelFormat);
using (Graphics graphics = Graphics.FromImage(returnImage)) { using (Graphics graphics = Graphics.FromImage(returnImage)) {
IntPtr hDCDest = graphics.GetHdc(); using (SafeDeviceContextHandle graphicsDC = graphics.getSafeDeviceContext()) {
try { bool printSucceeded = User32.PrintWindow(Handle, graphicsDC.DangerousGetHandle(), 0x0);
bool printSucceeded = User32.PrintWindow(Handle, hDCDest, 0x0);
if (!printSucceeded) { if (!printSucceeded) {
// something went wrong, most likely a "0x80004005" (Acess Denied) when using UAC // something went wrong, most likely a "0x80004005" (Acess Denied) when using UAC
exceptionOccured = User32.CreateWin32Exception("PrintWindow"); exceptionOccured = User32.CreateWin32Exception("PrintWindow");
} }
} finally {
graphics.ReleaseHdc(hDCDest);
} }
// Apply the region "transparency" // Apply the region "transparency"
@ -1439,7 +1439,9 @@ namespace GreenshotPlugin.Core {
get { get {
try { try {
if (!isMetroApp) { if (!isMetroApp) {
return "Greenshot".Equals(Process.MainModule.FileVersionInfo.ProductName); using (Process thisWindowProcess = Process) {
return "Greenshot".Equals(thisWindowProcess.MainModule.FileVersionInfo.ProductName);
}
} }
} catch (Exception ex) { } catch (Exception ex) {
LOG.Warn(ex); LOG.Warn(ex);
@ -1622,7 +1624,7 @@ namespace GreenshotPlugin.Core {
/// <param name="windowToLinkTo"></param> /// <param name="windowToLinkTo"></param>
/// <returns></returns> /// <returns></returns>
public static WindowDetails GetLinkedWindow(WindowDetails windowToLinkTo) { public static WindowDetails GetLinkedWindow(WindowDetails windowToLinkTo) {
IntPtr processIdSelectedWindow = windowToLinkTo.ProcessId; int processIdSelectedWindow = windowToLinkTo.ProcessId;
foreach(WindowDetails window in GetAllWindows()) { foreach(WindowDetails window in GetAllWindows()) {
// Ignore windows without title // Ignore windows without title
if (window.Text.Length == 0) { if (window.Text.Length == 0) {

View file

@ -71,10 +71,10 @@ namespace Greenshot.Plugin {
} }
} }
public delegate void SurfaceSizeChangeEventHandler(object sender, EventArgs eventArgs); public delegate void SurfaceSizeChangeEventHandler(object sender, EventArgs e);
public delegate void SurfaceMessageEventHandler(object sender, SurfaceMessageEventArgs eventArgs); public delegate void SurfaceMessageEventHandler(object sender, SurfaceMessageEventArgs e);
public delegate void SurfaceElementEventHandler(object sender, SurfaceElementEventArgs eventArgs); public delegate void SurfaceElementEventHandler(object sender, SurfaceElementEventArgs e);
public delegate void SurfaceDrawingModeEventHandler(object sender, SurfaceDrawingModeEventArgs eventArgs); public delegate void SurfaceDrawingModeEventHandler(object sender, SurfaceDrawingModeEventArgs e);
public enum DrawingModes { public enum DrawingModes {
None, None,
Rect, Rect,

View file

@ -56,12 +56,12 @@ namespace GreenshotPlugin.UnmanagedHelpers {
[DllImport("kernel32", SetLastError = true)] [DllImport("kernel32", SetLastError = true)]
public static extern int ResumeThread(IntPtr hThread); public static extern int ResumeThread(IntPtr hThread);
[DllImport("kernel32", SetLastError = true)] [DllImport("kernel32", SetLastError = true)]
public static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, bool bInheritHandle, IntPtr dwProcessId); public static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, bool bInheritHandle, int dwProcessId);
[DllImport("kernel32", SetLastError = true)] [DllImport("kernel32", SetLastError = true, CharSet=CharSet.Unicode)]
public static extern bool QueryFullProcessImageName(IntPtr hProcess, uint dwFlags, StringBuilder lpExeName, ref uint lpdwSize); public static extern bool QueryFullProcessImageName(IntPtr hProcess, uint dwFlags, StringBuilder lpExeName, ref uint lpdwSize);
[DllImport("kernel32", SetLastError = true)] [DllImport("kernel32", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern uint QueryDosDevice(string lpDeviceName, StringBuilder lpTargetPath, uint uuchMax); public static extern uint QueryDosDevice(string lpDeviceName, StringBuilder lpTargetPath, uint uuchMax);
[DllImport("kernel32", SetLastError = true)] [DllImport("kernel32", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern IntPtr GetModuleHandle(string lpModuleName); public static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport("kernel32", SetLastError = true)] [DllImport("kernel32", SetLastError = true)]
public static extern bool CloseHandle(IntPtr hObject); public static extern bool CloseHandle(IntPtr hObject);
@ -71,7 +71,7 @@ namespace GreenshotPlugin.UnmanagedHelpers {
/// </summary> /// </summary>
/// <param name="processid"></param> /// <param name="processid"></param>
/// <returns></returns> /// <returns></returns>
public static string GetProcessPath(IntPtr processid) { public static string GetProcessPath(int processid) {
StringBuilder _PathBuffer = new StringBuilder(512); StringBuilder _PathBuffer = new StringBuilder(512);
// Try the GetModuleFileName method first since it's the fastest. // 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. // May return ACCESS_DENIED (due to VM_READ flag) if the process is not owned by the current user.

View file

@ -27,9 +27,9 @@ namespace GreenshotPlugin.UnmanagedHelpers {
/// Description of PsAPI. /// Description of PsAPI.
/// </summary> /// </summary>
public class PsAPI { public class PsAPI {
[DllImport("psapi", SetLastError = true)] [DllImport("psapi", SetLastError = true, CharSet=CharSet.Unicode)]
public static extern uint GetModuleFileNameEx(IntPtr hProcess, IntPtr hModule, StringBuilder lpFilename, uint nSize); public static extern uint GetModuleFileNameEx(IntPtr hProcess, IntPtr hModule, StringBuilder lpFilename, uint nSize);
[DllImport("psapi", SetLastError = true)] [DllImport("psapi", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern uint GetProcessImageFileName(IntPtr hProcess, StringBuilder lpImageFileName, uint nSize); public static extern uint GetProcessImageFileName(IntPtr hProcess, StringBuilder lpImageFileName, uint nSize);
[DllImport("psapi")] [DllImport("psapi")]
public static extern int EmptyWorkingSet(IntPtr hwProc); public static extern int EmptyWorkingSet(IntPtr hwProc);

View file

@ -29,9 +29,9 @@ namespace GreenshotPlugin.UnmanagedHelpers {
/// Description of Shell32. /// Description of Shell32.
/// </summary> /// </summary>
public static class Shell32 { public static class Shell32 {
[DllImport("shell32")] [DllImport("shell32", CharSet = CharSet.Unicode)]
public static extern int ExtractIconEx(string sFile, int iIndex, out IntPtr piLargeVersion, out IntPtr piSmallVersion, int amountIcons); public static extern int ExtractIconEx(string sFile, int iIndex, out IntPtr piLargeVersion, out IntPtr piSmallVersion, int amountIcons);
[DllImport("shell32", CharSet = CharSet.Auto)] [DllImport("shell32", CharSet = CharSet.Unicode)]
internal static extern IntPtr ExtractAssociatedIcon(HandleRef hInst, StringBuilder iconPath, ref int index); internal static extern IntPtr ExtractAssociatedIcon(HandleRef hInst, StringBuilder iconPath, ref int index);
/// <summary> /// <summary>

View file

@ -60,7 +60,7 @@ namespace GreenshotPlugin.UnmanagedHelpers {
[return: MarshalAs(UnmanagedType.Bool)] [return: MarshalAs(UnmanagedType.Bool)]
public extern static bool IsWindowVisible(IntPtr hWnd); public extern static bool IsWindowVisible(IntPtr hWnd);
[DllImport("user32", SetLastError = true)] [DllImport("user32", SetLastError = true)]
public static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd, out IntPtr processId); public static extern int GetWindowThreadProcessId(IntPtr hWnd, out int processId);
[DllImport("user32", SetLastError = true)] [DllImport("user32", SetLastError = true)]
public static extern IntPtr GetParent(IntPtr hWnd); public static extern IntPtr GetParent(IntPtr hWnd);
[DllImport("user32", SetLastError = true)] [DllImport("user32", SetLastError = true)]
@ -100,8 +100,8 @@ namespace GreenshotPlugin.UnmanagedHelpers {
[DllImport("user32", CharSet = CharSet.Unicode, SetLastError = true)] [DllImport("user32", CharSet = CharSet.Unicode, SetLastError = true)]
public extern static int GetClassName (IntPtr hWnd, StringBuilder lpClassName, int nMaxCount); public extern static int GetClassName (IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
[DllImport("user32", SetLastError = true)] [DllImport("user32", SetLastError = true)]
public static extern IntPtr GetClassLong(IntPtr hWnd, int nIndex); public static extern uint GetClassLong(IntPtr hWnd, int nIndex);
[DllImport("user32", SetLastError = true)] [DllImport("user32", SetLastError = true, EntryPoint = "GetClassLongPtr")]
public static extern IntPtr GetClassLongPtr(IntPtr hWnd, int nIndex); public static extern IntPtr GetClassLongPtr(IntPtr hWnd, int nIndex);
[DllImport("user32", SetLastError = true)] [DllImport("user32", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)] [return: MarshalAs(UnmanagedType.Bool)]
@ -110,14 +110,14 @@ namespace GreenshotPlugin.UnmanagedHelpers {
public extern static IntPtr SendMessage(IntPtr hWnd, uint wMsg, IntPtr wParam, IntPtr lParam); public extern static IntPtr SendMessage(IntPtr hWnd, uint wMsg, IntPtr wParam, IntPtr lParam);
[DllImport("user32", SetLastError = true)] [DllImport("user32", SetLastError = true)]
public extern static IntPtr SendMessage(IntPtr hWnd, uint wMsg, IntPtr wParam, [MarshalAs(UnmanagedType.LPWStr)] string lParam); public extern static IntPtr SendMessage(IntPtr hWnd, uint wMsg, IntPtr wParam, [MarshalAs(UnmanagedType.LPWStr)] string lParam);
[DllImport("user32", SetLastError = true, EntryPoint = "GetWindowLong")]
public extern static int GetWindowLong(IntPtr hwnd, int index);
[DllImport("user32", SetLastError = true, EntryPoint = "GetWindowLongPtr")]
public extern static IntPtr GetWindowLongPtr(IntPtr hwnd, int nIndex);
[DllImport("user32", SetLastError = true)] [DllImport("user32", SetLastError = true)]
public extern static uint GetWindowLong(IntPtr hwnd, int index); public static extern int SetWindowLong(IntPtr hWnd, int index, int styleFlags);
[DllImport("user32", SetLastError = true)] [DllImport("user32", SetLastError = true)]
public extern static uint GetWindowLongPtr(IntPtr hwnd, int nIndex); public static extern IntPtr SetWindowLongPtr(IntPtr hWnd, int index, IntPtr styleFlags);
[DllImport("user32", SetLastError = true)]
public static extern int SetWindowLong(IntPtr hWnd, int index, uint styleFlags);
[DllImport("user32", SetLastError = true)]
public static extern int SetWindowLongPtr(IntPtr hWnd, int index, uint styleFlags);
[DllImport("user32", SetLastError = true)] [DllImport("user32", SetLastError = true)]
public static extern IntPtr MonitorFromWindow(IntPtr hwnd, uint dwFlags); public static extern IntPtr MonitorFromWindow(IntPtr hwnd, uint dwFlags);
[DllImport("user32", SetLastError = true)] [DllImport("user32", SetLastError = true)]
@ -126,9 +126,9 @@ namespace GreenshotPlugin.UnmanagedHelpers {
[return: MarshalAs(UnmanagedType.Bool)] [return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetWindowInfo(IntPtr hwnd, ref WindowInfo pwi); public static extern bool GetWindowInfo(IntPtr hwnd, ref WindowInfo pwi);
[DllImport("user32", SetLastError = true)] [DllImport("user32", SetLastError = true)]
public extern static int EnumWindows(EnumWindowsProc lpEnumFunc, int lParam); public extern static int EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
[DllImport("user32", SetLastError = true)] [DllImport("user32", SetLastError = true)]
public extern static int EnumChildWindows(IntPtr hWndParent, EnumWindowsProc lpEnumFunc, int lParam); public extern static int EnumChildWindows(IntPtr hWndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam);
[DllImport("user32", SetLastError = true)] [DllImport("user32", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)] [return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetScrollInfo(IntPtr hwnd, int fnBar, ref SCROLLINFO lpsi); public static extern bool GetScrollInfo(IntPtr hwnd, int fnBar, ref SCROLLINFO lpsi);
@ -151,7 +151,7 @@ namespace GreenshotPlugin.UnmanagedHelpers {
public static extern IntPtr GetDC(IntPtr hwnd); public static extern IntPtr GetDC(IntPtr hwnd);
[DllImport("user32", SetLastError = true)] [DllImport("user32", SetLastError = true)]
public static extern void ReleaseDC(IntPtr dc); public static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDC);
[DllImport("user32", SetLastError = true)] [DllImport("user32", SetLastError = true)]
public static extern IntPtr GetClipboardOwner(); public static extern IntPtr GetClipboardOwner();
@ -167,9 +167,9 @@ namespace GreenshotPlugin.UnmanagedHelpers {
public static extern IntPtr SetWinEventHook(WinEvent eventMin, WinEvent eventMax, IntPtr hmodWinEventProc, WinEventDelegate lpfnWinEventProc, int idProcess, int idThread, WinEventHookFlags dwFlags); public static extern IntPtr SetWinEventHook(WinEvent eventMin, WinEvent eventMax, IntPtr hmodWinEventProc, WinEventDelegate lpfnWinEventProc, int idProcess, int idThread, WinEventHookFlags dwFlags);
// Added for finding Metro apps, Greenshot 1.1 // Added for finding Metro apps, Greenshot 1.1
[DllImport("user32", SetLastError = true)] [DllImport("user32", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32", SetLastError = true)] [DllImport("user32", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
/// uiFlags: 0 - Count of GDI objects /// uiFlags: 0 - Count of GDI objects
@ -181,7 +181,7 @@ namespace GreenshotPlugin.UnmanagedHelpers {
/// ///
[DllImport("user32", SetLastError = true)] [DllImport("user32", SetLastError = true)]
public static extern uint GetGuiResources(IntPtr hProcess, uint uiFlags); public static extern uint GetGuiResources(IntPtr hProcess, uint uiFlags);
[DllImport("user32", EntryPoint = "RegisterWindowMessageA", SetLastError = true)] [DllImport("user32", EntryPoint = "RegisterWindowMessageA", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern uint RegisterWindowMessage(string lpString); public static extern uint RegisterWindowMessage(string lpString);
[DllImport("user32", SetLastError=true, CharSet=CharSet.Auto)] [DllImport("user32", SetLastError=true, CharSet=CharSet.Auto)]
public static extern IntPtr SendMessageTimeout(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam, SendMessageTimeoutFlags fuFlags, uint uTimeout, out UIntPtr lpdwResult); public static extern IntPtr SendMessageTimeout(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam, SendMessageTimeoutFlags fuFlags, uint uTimeout, out UIntPtr lpdwResult);
@ -223,7 +223,7 @@ namespace GreenshotPlugin.UnmanagedHelpers {
if (IntPtr.Size > 4) { if (IntPtr.Size > 4) {
return GetClassLongPtr(hWnd, nIndex); return GetClassLongPtr(hWnd, nIndex);
} else { } else {
return GetClassLong(hWnd, nIndex); return new IntPtr(GetClassLong(hWnd, nIndex));
} }
} }
@ -233,9 +233,9 @@ namespace GreenshotPlugin.UnmanagedHelpers {
/// <param name="hwnd"></param> /// <param name="hwnd"></param>
/// <param name="nIndex"></param> /// <param name="nIndex"></param>
/// <returns></returns> /// <returns></returns>
public static uint GetWindowLongWrapper(IntPtr hwnd, int nIndex) { public static long GetWindowLongWrapper(IntPtr hwnd, int nIndex) {
if (IntPtr.Size == 8) { if (IntPtr.Size == 8) {
return GetWindowLongPtr(hwnd, nIndex); return GetWindowLongPtr(hwnd, nIndex).ToInt64();
} else { } else {
return GetWindowLong(hwnd, nIndex); return GetWindowLong(hwnd, nIndex);
} }
@ -247,20 +247,24 @@ namespace GreenshotPlugin.UnmanagedHelpers {
/// <param name="hwnd"></param> /// <param name="hwnd"></param>
/// <param name="nIndex"></param> /// <param name="nIndex"></param>
/// <param name="styleFlags"></param> /// <param name="styleFlags"></param>
public static void SetWindowLongWrapper(IntPtr hwnd, int nIndex, uint styleFlags) { public static void SetWindowLongWrapper(IntPtr hwnd, int nIndex, IntPtr styleFlags) {
if (IntPtr.Size == 8) { if (IntPtr.Size == 8) {
SetWindowLongPtr(hwnd, nIndex, styleFlags); SetWindowLongPtr(hwnd, nIndex, styleFlags);
} else { } else {
SetWindowLong(hwnd, nIndex, styleFlags); SetWindowLong(hwnd, nIndex, styleFlags.ToInt32());
} }
} }
public static uint GetGuiResourcesGDICount() { public static uint GetGuiResourcesGDICount() {
return GetGuiResources(Process.GetCurrentProcess().Handle, 0); using (Process currentProcess = Process.GetCurrentProcess()) {
return GetGuiResources(currentProcess.Handle, 0);
}
} }
public static uint GetGuiResourcesUserCount() { public static uint GetGuiResourcesUserCount() {
return GetGuiResources(Process.GetCurrentProcess().Handle, 1); using (Process currentProcess = Process.GetCurrentProcess()) {
return GetGuiResources(currentProcess.Handle, 1);
}
} }
/// <summary> /// <summary>

View file

@ -92,7 +92,7 @@ namespace GreenshotPlugin.UnmanagedHelpers {
} }
public static class Win32 { public static class Win32 {
[DllImport("kernel32.dll")] [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
static extern uint FormatMessage(uint dwFlags, IntPtr lpSource, uint dwMessageId, uint dwLanguageId, [Out] StringBuilder lpBuffer, int nSize, IntPtr Arguments); static extern uint FormatMessage(uint dwFlags, IntPtr lpSource, uint dwMessageId, uint dwLanguageId, [Out] StringBuilder lpBuffer, int nSize, IntPtr Arguments);
[DllImport("kernel32.dll")] [DllImport("kernel32.dll")]