[C#] 纯文本查看 复制代码
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
class P
{
[DllImport("user32")] static extern bool ShowWindow(IntPtr h, int n);
[DllImport("user32")] static extern bool IsWindowVisible(IntPtr h);
[DllImport("user32")] static extern bool EnumWindows(EnumWindowsProc d, IntPtr p);
[DllImport("user32")] static extern uint GetWindowThreadProcessId(IntPtr h, out uint p);
[DllImport("user32")] static extern IntPtr SetWinEventHook(uint a, uint b, IntPtr c, WinEventDelegate d, uint e, uint f, uint g);
[DllImport("user32")] static extern bool UnhookWinEvent(IntPtr h);
[DllImport("user32")] static extern bool PeekMessage(ref MSG m, IntPtr a, uint b, uint c, uint d);
[DllImport("user32")] static extern bool TranslateMessage(ref MSG m);
[DllImport("user32")] static extern IntPtr DispatchMessage(ref MSG m);
[DllImport("kernel32")] static extern uint GetTickCount(); // 替代 Stopwatch
delegate bool EnumWindowsProc(IntPtr h, IntPtr p);
delegate void WinEventDelegate(IntPtr a, uint b, IntPtr c, int d, int e, uint f, uint g);
[StructLayout(LayoutKind.Sequential)]
struct MSG { public IntPtr H; public uint M; public IntPtr W; public IntPtr L; public uint T; public int X, Y; }
const int SW_HIDE = 0;
const uint EVENT_SHOW = 0x8002, WINEVENT_OUTOFCONTEXT = 0, PM_REMOVE = 1;
static WinEventDelegate _hookDel;
static IntPtr _hookHandle = IntPtr.Zero; // 只会有一个 Hook,不需要集合
// 用原生数组替代 Hashtable 和 ArrayList,彻底移除 System.Collections 引用
static int[] _pids = new int[128];
static int _pidCount = 0;
static string[] _names = new string[128];
static int _nameCount = 0;
[ComImport, Guid("00021401-0000-0000-C000-000000000046")]
class ShellLink { }
[ComImport, Guid("0000010b-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IPersistFile
{
void GetClassID(out Guid g);
void IsDirty();
void Load([MarshalAs(UnmanagedType.LPWStr)] string f, uint m);
}
[ComImport, Guid("000214F9-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IShellLinkW
{
void GetPath(IntPtr b, int c, IntPtr p, uint f);
void GetIDList(out IntPtr p);
void SetIDList(IntPtr p);
void GetDescription(IntPtr b, int c);
void SetDescription(string s);
void GetWorkingDirectory(IntPtr b, int c);
void SetWorkingDirectory(string s);
void GetArguments(IntPtr b, int c);
void SetArguments(string s);
void GetHotkey(out ushort k);
void SetHotkey(ushort k);
void GetShowCmd(out int c);
}
[STAThread]
static void Main(string[] args)
{
string path = "";
bool close = false;
int time = 6000;
foreach (string a in args)
{
string t = a.Trim('"');
if (t.ToLower() == "close") close = true;
else if (int.TryParse(t, out int i) && i > 0) time = i;
else path = t;
}
if (string.IsNullOrEmpty(path)) path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "WorkApps");
if (!Directory.Exists(path)) return;
string[] files = Directory.GetFiles(path);
if (files.Length == 0) return;
if (close)
{
foreach (string f in files)
{
string ext = Path.GetExtension(f).ToLower();
string exe = null;
if (ext == ".exe") exe = Path.GetFileName(f);
else if (ext == ".lnk") { int cmd; exe = Path.GetFileName(GetLnkInfo(f, out cmd)); }
if (exe != null)
foreach (Process p in Process.GetProcessesByName(Path.GetFileNameWithoutExtension(exe)))
try { p.Kill(); } catch { }
}
return;
}
foreach (string f in files)
{
string ext = Path.GetExtension(f).ToLower();
if (ext == ".exe")
{
try { Process.Start(new ProcessStartInfo(f) { WorkingDirectory = path }); } catch { }
}
else if (ext == ".lnk")
{
try
{
int showCmd;
string target = GetLnkInfo(f, out showCmd);
if (string.IsNullOrEmpty(target) || Path.GetExtension(target).ToLower() != ".exe") continue;
string exe = Path.GetFileNameWithoutExtension(target).ToLower();
if (showCmd == 7)
{
if (!HasName(exe)) AddName(exe);
if (Process.GetProcessesByName(exe).Length == 0)
{
Process p = Process.Start(new ProcessStartInfo(f) { WorkingDirectory = path, WindowStyle = ProcessWindowStyle.Hidden });
if (p != null && !HasPid(p.Id)) AddPid(p.Id);
}
}
else
{
Process.Start(new ProcessStartInfo(f) { WorkingDirectory = path });
}
}
catch { }
}
}
if (_nameCount > 0)
{
EnumWindows(delegate (IntPtr h, IntPtr l)
{
if (IsWindowVisible(h)) HideIfMatch(h);
return true;
}, IntPtr.Zero);
_hookDel = new WinEventDelegate(delegate (IntPtr hh, uint et, IntPtr h, int idObj, int idChild, uint thread, uint ms)
{
if (idObj == 0 && h != IntPtr.Zero && IsWindowVisible(h)) HideIfMatch(h);
});
_hookHandle = SetWinEventHook(EVENT_SHOW, EVENT_SHOW, IntPtr.Zero, _hookDel, 0, 0, WINEVENT_OUTOFCONTEXT);
if (_hookHandle != IntPtr.Zero)
{
uint start = GetTickCount();
MSG m = new MSG();
while (GetTickCount() - start < time) // 替代 Stopwatch
{
if (PeekMessage(ref m, IntPtr.Zero, 0, 0, PM_REMOVE))
{
TranslateMessage(ref m);
DispatchMessage(ref m);
}
else Thread.Sleep(10);
}
try { UnhookWinEvent(_hookHandle); } catch { }
}
else
{
uint start = GetTickCount();
while (GetTickCount() - start < time)
{
EnumWindows(delegate (IntPtr h, IntPtr l)
{
if (IsWindowVisible(h)) HideIfMatch(h);
return true;
}, IntPtr.Zero);
Thread.Sleep(10);
}
}
}
}
static bool HideIfMatch(IntPtr hWnd)
{
try
{
GetWindowThreadProcessId(hWnd, out uint pid);
int id = (int)pid;
if (HasPid(id)) { ShowWindow(hWnd, SW_HIDE); return true; }
Process p = Process.GetProcessById(id);
string name = p.ProcessName.ToLower();
if (HasName(name))
{
ShowWindow(hWnd, SW_HIDE);
if (!HasPid(id)) AddPid(id);
return true;
}
}
catch { }
return false;
}
// --- 极简数组操作,代替 Hashtable ---
static bool HasPid(int id) { for (int i = 0; i < _pidCount; i++) if (_pids[i] == id) return true; return false; }
static void AddPid(int id) { if (_pidCount < 128) _pids[_pidCount++] = id; }
static bool HasName(string n) { for (int i = 0; i < _nameCount; i++) if (_names[i] == n) return true; return false; }
static void AddName(string n) { if (_nameCount < 128) _names[_nameCount++] = n; }
static string GetLnkInfo(string lnk, out int showCmd)
{
showCmd = 1;
try
{
ShellLink sl = new ShellLink();
IPersistFile pf = (IPersistFile)sl;
pf.Load(lnk, 0);
IShellLinkW sw = (IShellLinkW)sl;
IntPtr buf = Marshal.AllocCoTaskMem(520);
try
{
sw.GetPath(buf, 260, IntPtr.Zero, 0);
string target = Marshal.PtrToStringUni(buf);
sw.GetShowCmd(out showCmd);
return target;
}
finally
{
Marshal.FreeCoTaskMem(buf);
}
}
catch { return null; }
}
}