mirror of
				https://github.com/snltty/linker.git
				synced 2025-10-31 04:26:45 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			194 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			194 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using cmonitor.libs;
 | |
| using System.Diagnostics;
 | |
| using System.Runtime.InteropServices;
 | |
| using System.ServiceProcess;
 | |
| using System.Text;
 | |
| 
 | |
| namespace cmonitor.sas.service
 | |
| {
 | |
|     partial class CmonitorSasService : ServiceBase
 | |
|     {
 | |
|         private readonly string[] args;
 | |
|         public CmonitorSasService(string[] args)
 | |
|         {
 | |
|             this.args = args;
 | |
|             InitializeComponent();
 | |
|         }
 | |
| 
 | |
| 
 | |
|         string shareMkey = "cmonitor/share";
 | |
|         int shareMLength = 10;
 | |
|         int shareItemMLength = 1024;
 | |
|         int shareIndex = 4;
 | |
|         string mainArgs = string.Empty;
 | |
|         string mainExeName = "cmonitor";
 | |
|         byte[] keyBytes = Encoding.UTF8.GetBytes("cmonitor.sas.service");
 | |
|         ShareMemory shareMemory;
 | |
| 
 | |
|         CancellationTokenSource cancellationTokenSource;
 | |
| 
 | |
|         [DllImport("sas.dll")]
 | |
|         public static extern void SendSAS(bool asUser);
 | |
| 
 | |
|         protected override void OnStart(string[] _args)
 | |
|         {
 | |
|             try
 | |
|             {
 | |
|                 if (args != null && args.Length > 0)
 | |
|                 {
 | |
|                     shareMkey = args[0];
 | |
|                     shareMLength = int.Parse(args[1]);
 | |
|                     shareItemMLength = int.Parse(args[2]);
 | |
|                     shareIndex = int.Parse(args[3]);
 | |
|                     if (args.Length >= 5)
 | |
|                     {
 | |
|                         mainArgs = args[4];
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 shareMemory = new ShareMemory(shareMkey, shareMLength, shareItemMLength);
 | |
|                 shareMemory.InitGlobal();
 | |
|                 CheckMemory();
 | |
|             }
 | |
|             catch (Exception)
 | |
|             {
 | |
|             }
 | |
|             CheckMainProcess();
 | |
|         }
 | |
|         protected override void OnStop()
 | |
|         {
 | |
|             WriteAllCloseState();
 | |
|             WaitClose();
 | |
|             cancellationTokenSource?.Cancel();
 | |
|         }
 | |
|         private void WaitClose()
 | |
|         {
 | |
|             while (Process.GetProcessesByName(mainExeName).Any())
 | |
|             {
 | |
|                 WriteAllCloseState();
 | |
|                 Thread.Sleep(1000);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private void CheckMemory()
 | |
|         {
 | |
|             cancellationTokenSource = new CancellationTokenSource();
 | |
|             Task.Factory.StartNew((a) =>
 | |
|             {
 | |
|                 CancellationTokenSource tks = a as CancellationTokenSource;
 | |
|                 while (tks.IsCancellationRequested == false)
 | |
|                 {
 | |
|                     try
 | |
|                     {
 | |
|                         string value = shareMemory.ReadValueString(shareIndex);
 | |
|                         if (value == "ctrl+alt+delete")
 | |
|                         {
 | |
|                             try
 | |
|                             {
 | |
|                                 SendSAS(false);
 | |
|                             }
 | |
|                             catch (Exception)
 | |
|                             {
 | |
|                             }
 | |
|                             shareMemory.Update(shareIndex, keyBytes, Array.Empty<byte>());
 | |
|                         }
 | |
|                     }
 | |
|                     finally
 | |
|                     {
 | |
|                     }
 | |
| 
 | |
|                     Thread.Sleep(10);
 | |
|                 }
 | |
|             }, cancellationTokenSource, TaskCreationOptions.LongRunning);
 | |
|         }
 | |
| 
 | |
|         private void WriteAllCloseState()
 | |
|         {
 | |
|             for (int i = 0; i < shareMLength; i++)
 | |
|             {
 | |
|                 shareMemory.AddAttribute(i,  ShareMemoryAttribute.Closed);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         Process proc;
 | |
|         private void CheckMainProcess()
 | |
|         {
 | |
|             if (string.IsNullOrWhiteSpace(mainArgs))
 | |
|             {
 | |
|                 return;
 | |
|             }
 | |
|             Task.Factory.StartNew(() =>
 | |
|             {
 | |
|                 while (true)
 | |
|                 {
 | |
|                     try
 | |
|                     {
 | |
|                         if (Process.GetProcessesByName(mainExeName).Any() == false)
 | |
|                         {
 | |
|                             KillExe();
 | |
|                             OpenExe();
 | |
|                         }
 | |
|                     }
 | |
|                     catch (Exception)
 | |
|                     {
 | |
|                     }
 | |
|                     Thread.Sleep(30000);
 | |
|                 }
 | |
|             }, TaskCreationOptions.LongRunning);
 | |
|         }
 | |
|         private bool OpenExe()
 | |
|         {
 | |
|             try
 | |
|             {
 | |
|                 string filename = Process.GetCurrentProcess().MainModule.FileName;
 | |
|                 string dir = Path.GetDirectoryName(filename);
 | |
|                 string file = Path.Combine(dir, $"{mainExeName}.exe");
 | |
|                 ProcessStartInfo processStartInfo = new ProcessStartInfo()
 | |
|                 {
 | |
|                     WorkingDirectory = dir,
 | |
|                     FileName = file,
 | |
|                     CreateNoWindow = false,
 | |
|                     ErrorDialog = false,
 | |
|                     UseShellExecute = true,
 | |
|                     WindowStyle = ProcessWindowStyle.Hidden,
 | |
|                     Arguments = string.Join(" ", this.args),
 | |
|                     Verb = "runas",
 | |
|                 };
 | |
|                 proc = Process.Start(processStartInfo);
 | |
| 
 | |
|                 return true;
 | |
|             }
 | |
|             catch (Exception)
 | |
|             {
 | |
|                 try
 | |
|                 {
 | |
|                     proc.Kill();
 | |
|                     proc.Dispose();
 | |
|                 }
 | |
|                 catch (Exception)
 | |
|                 {
 | |
|                 }
 | |
|                 proc = null;
 | |
|             }
 | |
|             return false;
 | |
|         }
 | |
|         private void KillExe()
 | |
|         {
 | |
|             try
 | |
|             {
 | |
|                 proc?.Close();
 | |
|                 proc?.Dispose();
 | |
| 
 | |
|             }
 | |
|             catch (Exception)
 | |
|             {
 | |
|             }
 | |
|             finally
 | |
|             {
 | |
|                 proc = null;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|     }
 | |
| }
 | 
