Skip to content

Commit

Permalink
大量更新
Browse files Browse the repository at this point in the history
1.  用互斥量防止SmartTaskbar和TaskbarSwitcher进程重复启动
2.  使SmartTaskbar和TaskbarSwitcher在同一个作业中,防止系统托盘意外关闭时,自动隐藏任务栏功能依然保持工作
3.  首次启动应用时会弹出程序正在运行消息
4.  安装和卸载程序时能正常的关闭仍在运行的程序和删除相应的设置文件
5.  一些性能的提升
  • Loading branch information
Oliviaophia committed Mar 6, 2018
1 parent 2d13452 commit aafbb77
Show file tree
Hide file tree
Showing 13 changed files with 214 additions and 25 deletions.
78 changes: 78 additions & 0 deletions SmartTaskbar/ChildProcessTracker.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using static SmartTaskbar.SafeNativeMethods;

namespace SmartTaskbar
{
//https://stackoverflow.com/questions/3342941/kill-child-process-when-parent-process-is-killed
static class ChildProcessTracker
{
/// <summary>
/// Add the process to be tracked. If our current process is killed, the child processes
/// that we are tracking will be automatically killed, too. If the child process terminates
/// first, that's fine, too.</summary>
/// <param name="process"></param>
public static void AddProcess(Process process)
{
if (s_jobHandle != IntPtr.Zero)
{
bool success = AssignProcessToJobObject(s_jobHandle, process.Handle);
if (!success)
return;
}
}

static ChildProcessTracker()
{
// This feature requires Windows 8 or later. To support Windows 7 requires
// registry settings to be added if you are using Visual Studio plus an
// app.manifest change.
// https://stackoverflow.com/a/4232259/386091
// https://stackoverflow.com/a/9507862/386091
//if (Environment.OSVersion.Version < new Version(6, 2))
// return;

// The job name is optional (and can be null) but it helps with diagnostics.
// If it's not null, it has to be unique. Use SysInternals' Handle command-line
// utility: handle -a ChildProcessTracker
string jobName = "ChildProcessTracker" + Process.GetCurrentProcess().Id;
s_jobHandle = CreateJobObjectW(IntPtr.Zero, jobName);

var info = new JOBOBJECT_BASIC_LIMIT_INFORMATION
{

// This is the key flag. When our process is killed, Windows will automatically
// close the job handle, and when that happens, we want the child processes to
// be killed, too.
LimitFlags = JOBOBJECTLIMIT.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE
};

var extendedInfo = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION
{
BasicLimitInformation = info
};

int length = Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION));
IntPtr extendedInfoPtr = Marshal.AllocHGlobal(length);
try
{
Marshal.StructureToPtr(extendedInfo, extendedInfoPtr, false);
SetInformationJobObject(s_jobHandle, JobObjectInfoType.ExtendedLimitInformation, extendedInfoPtr, (uint)length);
}
finally
{
Marshal.FreeHGlobal(extendedInfoPtr);
}
}

// Windows will automatically close any open job handles when our process terminates.
// This can be verified by using SysInternals' Handle utility. When the job handle
// is closed, the child processes will be killed.
private static readonly IntPtr s_jobHandle;
}




}
3 changes: 3 additions & 0 deletions SmartTaskbar/Languages/Resource.de-DE.resx
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@
<data name="exit" xml:space="preserve">
<value>Beenden</value>
</data>
<data name="firstrun" xml:space="preserve">
<value>SmartTaskbar wird im Hintergrund ausgeführt</value>
</data>
<data name="hide" xml:space="preserve">
<value>Ausblenden</value>
</data>
Expand Down
3 changes: 3 additions & 0 deletions SmartTaskbar/Languages/Resource.en-US.resx
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@
<data name="exit" xml:space="preserve">
<value>Exit</value>
</data>
<data name="firstrun" xml:space="preserve">
<value>SmartTaskbar is running in the background</value>
</data>
<data name="hide" xml:space="preserve">
<value>Hide</value>
</data>
Expand Down
3 changes: 3 additions & 0 deletions SmartTaskbar/Languages/Resource.zh-CN.resx
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@
<data name="exit" xml:space="preserve">
<value>退出</value>
</data>
<data name="firstrun" xml:space="preserve">
<value>SmartTaskbar正在后台运行</value>
</data>
<data name="hide" xml:space="preserve">
<value>隐藏</value>
</data>
Expand Down
17 changes: 10 additions & 7 deletions SmartTaskbar/Program.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using System;
using System.Diagnostics;
using System.Threading;
using System.Windows.Forms;

namespace SmartTaskbar
Expand All @@ -12,12 +12,15 @@ static class Program
[STAThread]
static void Main()
{
if (Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).Length > 1)
return;
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
new SystemTray();
Application.Run();
using (Mutex mutex = new Mutex(true, Application.ProductName, out bool createNew))
{
if (!createNew)
return;
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
new SystemTray();
Application.Run();
}
}
}
}
99 changes: 98 additions & 1 deletion SmartTaskbar/SafeNativeMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace SmartTaskbar
{
[SuppressUnmanagedCodeSecurity]
class SafeNativeMethods
static class SafeNativeMethods
{
#region SHAppBarMessage
public const uint GetState = 4;
Expand Down Expand Up @@ -61,5 +61,102 @@ public struct TagRECT
public static extern uint SHAppBarMessage(uint dwMessage, ref APPBARDATA pData);

#endregion

#region JobObject

[StructLayout(LayoutKind.Sequential)]
public struct SECURITY_ATTRIBUTES
{

/// DWORD->unsigned int
public uint nLength;

/// LPVOID->void*
public System.IntPtr lpSecurityDescriptor;

/// BOOL->int
[MarshalAs(UnmanagedType.Bool)]
public bool bInheritHandle;
}

/// Return Type: HANDLE->void*
///lpJobAttributes: LPSECURITY_ATTRIBUTES->_SECURITY_ATTRIBUTES*
///lpName: LPCWSTR->WCHAR*
[DllImport("kernel32.dll", EntryPoint = "CreateJobObjectW")]
public static extern IntPtr CreateJobObjectW([In()] IntPtr lpJobAttributes, [In()] [MarshalAs(UnmanagedType.LPWStr)] string lpName);

[Flags]
public enum JOBOBJECTLIMIT : uint
{
JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE = 0x2000
}

public enum JobObjectInfoType
{
AssociateCompletionPortInformation = 7,
BasicLimitInformation = 2,
BasicUIRestrictions = 4,
EndOfJobTimeInformation = 6,
ExtendedLimitInformation = 9,
SecurityLimitInformation = 5,
GroupInformation = 11
}
/// Return Type: BOOL->int
///hJob: HANDLE->void*
///JobObjectInformationClass: JOBOBJECTINFOCLASS->_JOBOBJECTINFOCLASS
///lpJobObjectInformation: LPVOID->void*
///cbJobObjectInformationLength: DWORD->unsigned int
[DllImport("kernel32.dll", EntryPoint = "SetInformationJobObject")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetInformationJobObject([In()] IntPtr hJob, JobObjectInfoType JobObjectInformationClass,
[In()] IntPtr lpJobObjectInformation, uint cbJobObjectInformationLength);


/// Return Type: BOOL->int
///hJob: HANDLE->void*
///hProcess: HANDLE->void*
[DllImport("kernel32.dll", EntryPoint = "AssignProcessToJobObject")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool AssignProcessToJobObject([In()] IntPtr hJob, [In()] IntPtr hProcess);

[StructLayout(LayoutKind.Sequential)]
public struct JOBOBJECT_BASIC_LIMIT_INFORMATION
{
public Int64 PerProcessUserTimeLimit;
public Int64 PerJobUserTimeLimit;
public JOBOBJECTLIMIT LimitFlags;
public UIntPtr MinimumWorkingSetSize;
public UIntPtr MaximumWorkingSetSize;
public UInt32 ActiveProcessLimit;
public Int64 Affinity;
public UInt32 PriorityClass;
public UInt32 SchedulingClass;
}




[StructLayout(LayoutKind.Sequential)]
public struct IO_COUNTERS
{
public UInt64 ReadOperationCount;
public UInt64 WriteOperationCount;
public UInt64 OtherOperationCount;
public UInt64 ReadTransferCount;
public UInt64 WriteTransferCount;
public UInt64 OtherTransferCount;
}

[StructLayout(LayoutKind.Sequential)]
public struct JOBOBJECT_EXTENDED_LIMIT_INFORMATION
{
public JOBOBJECT_BASIC_LIMIT_INFORMATION BasicLimitInformation;
public IO_COUNTERS IoInfo;
public UIntPtr ProcessMemoryLimit;
public UIntPtr JobMemoryLimit;
public UIntPtr PeakProcessMemoryUsed;
public UIntPtr PeakJobMemoryUsed;
}
#endregion
}
}
1 change: 1 addition & 0 deletions SmartTaskbar/SmartTaskbar.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ChildProcessTracker.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ResourceCulture.cs" />
Expand Down
1 change: 1 addition & 0 deletions SmartTaskbar/Style.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace SmartTaskbar
{
//https://stackoverflow.com/questions/32786250/windows-10-styled-contextmenustrip
public class Win10ColorTable : ProfessionalColorTable
{
public override Color MenuItemBorder => Color.WhiteSmoke;
Expand Down
15 changes: 13 additions & 2 deletions SmartTaskbar/SystemTray.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ class SystemTray

public SystemTray()
{
switcher = new TaskbarSwitcher();
ResourceCulture resource = new ResourceCulture();
System.Drawing.Font font = new System.Drawing.Font("Segoe UI", 9F);
about = new ToolStripMenuItem
Expand Down Expand Up @@ -67,11 +66,23 @@ public SystemTray()
{
ContextMenuStrip = contextMenuStrip,
Icon = Resource_Icon.logo_32,
Text = "SmartTaskbar",
Text = Application.ProductName,
Visible = true
};
notifyIcon.Click += NotifyIcon_Click;
notifyIcon.MouseDoubleClick += NotifyIcon_MouseDoubleClick;
if (Settings.Default.SwitcherVersion == 0)
{
Settings.Default.SwitcherVersion = Environment.OSVersion.Version.Major.ToString() == "10" ? 1 : 3;
if (Environment.Is64BitOperatingSystem)
++Settings.Default.SwitcherVersion;
Settings.Default.Save();
notifyIcon.BalloonTipTitle = Application.ProductName;
notifyIcon.BalloonTipText = resource.GetString("firstrun");
notifyIcon.BalloonTipIcon = ToolTipIcon.Info;
notifyIcon.ShowBalloonTip(5);
}
switcher = new TaskbarSwitcher();
switch (Settings.Default.TaskbarState)
{
case "auto":
Expand Down
19 changes: 4 additions & 15 deletions SmartTaskbar/TaskbarSwitcher.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Diagnostics;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using static SmartTaskbar.SafeNativeMethods;
Expand All @@ -16,13 +15,6 @@ class TaskbarSwitcher
public TaskbarSwitcher()
{
string folder = "Switcher";
if (Settings.Default.SwitcherVersion == 0)
{
Settings.Default.SwitcherVersion = Environment.OSVersion.Version.Major.ToString() == "10" ? 1 : 3;
if (Environment.Is64BitOperatingSystem)
++Settings.Default.SwitcherVersion;
Settings.Default.Save();
}
switch (Settings.Default.SwitcherVersion)
{
case 1:
Expand Down Expand Up @@ -65,6 +57,7 @@ public void Start()
{
isStop = false;
process.Start();
ChildProcessTracker.AddProcess(process);
}

public void Resume()
Expand All @@ -78,12 +71,8 @@ public void Stop()
if (isStop)
return;
isStop = true;
try
{
process.Kill();
process.WaitForExit();
}
catch { }
process.Kill();
process.WaitForExit();
}
}
}
Binary file modified TaskbarSwitcher/TaskbarSwitcher.cpp
Binary file not shown.
Binary file modified TaskbarSwitcher/stdafx.h
Binary file not shown.
Binary file modified TaskbarSwitcherWin10/TaskbarSwitcherWin10.cpp
Binary file not shown.

0 comments on commit aafbb77

Please sign in to comment.