/// <summary> /// Broadcast a message that the service has started. /// </summary> /// <param name = "args"></param> protected override void OnStart(string[] args) { isTraceEnabled = true; client = new XDMessagingClient().WithAmazonSettings(RegionEndPoint.EUWest1); listener = client.Listeners.GetListenerForMode(XDTransportMode.Compatibility); listener.MessageReceived += OnMessageReceived; listener.RegisterChannel("BinaryChannel1"); listener.RegisterChannel("BinaryChannel2"); //only the following mode is supported in windows services broadcast = client.Broadcasters.GetBroadcasterForMode(XDTransportMode.Compatibility); broadcast.SendToChannel("Status", "Test Service has started: Send STOP on Channel 1/2 to halt timer. Send START to Channel 1/2 to restart."); cancelToken = new CancellationTokenSource(); Task.Factory.StartNew(() => { while (!cancelToken.IsCancellationRequested) { if (isTraceEnabled) { broadcast.SendToChannel("Status", "The time is: " + DateTime.Now.ToString("f")); Thread.Sleep(5000); } } }); }
/// <summary> /// Broadcast a message that the service has stopped. /// </summary> protected override void OnStop() { broadcast.SendToChannel("Status", "Test Service has stopped"); cancelToken.Cancel(); cancelToken = null; listener.Dispose(); }
public void SendToChannel(string channel, string message) { Task.Factory.StartNew(() => { var networkMessage = new NetworkRelayMessage(Environment.MachineName, originalTransportMode, channel, message); networkBroadcaster.SendToChannel(networkChannel, networkMessage); // ReSharper disable once UnusedVariable }).ContinueWith(t => { var e = t.Exception; }, TaskContinuationOptions.OnlyOnFaulted); }
/// <summary> /// Packs given files into a single executable file /// </summary> /// <param name="unpackerExePath">Path to Unpacker.exe</param> /// <param name="pathToPackedApp">Path where packed .exe will be created</param> /// <param name="pathToFolderWithApp">Path to the directory that contains application files that will be packed</param> /// <param name="localPathToMainExe">Relative path to the executable file that will be launched when the packed app is launched</param> /// <param name="filesToPack">List of relative paths to all files of the app that is being packed</param> private static void PackApp(string unpackerExePath, string pathToPackedApp, string pathToFolderWithApp, string localPathToMainExe, List <string> filesToPack, bool isSelfRepackable, bool isRepacking) { using (var packedExe = new BinaryWriter(File.Open(pathToPackedApp, FileMode.Create, FileAccess.Write))) { // Write wrapper app (unpacker.exe) // and the key-word mark that will help to separate wrapper app bytes from data bytes packedExe.Write(File.ReadAllBytes(unpackerExePath)); // byte[] packedExe.Write(Encoding.UTF8.GetBytes("<SerGreen>")); // byte[] // Write self-repackable flag packedExe.Write(isSelfRepackable); // bool // If self-repackable, then write packer.exe if (isSelfRepackable) { byte[] packerData = File.ReadAllBytes(System.Reflection.Assembly.GetEntryAssembly().Location); packedExe.Write(packerData.Length); // int packedExe.Write(packerData); // byte[] } // If ProgressBarSplash.exe is present in the same forder, then add it to the package string splashPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ProgressBarSplash.exe"); bool splashExeExists = File.Exists(splashPath); packedExe.Write(splashExeExists); // bool if (splashExeExists) { byte[] splashData = File.ReadAllBytes(splashPath); packedExe.Write(splashData.Length); // int packedExe.Write(splashData); // byte[] } // Write relative path to the main executable of the packed app packedExe.Write(localPathToMainExe); // string Process splashProgressBarProc = null; // Append all packed files to the end of the wrapper app .exe file for (int i = 0; i < filesToPack.Count; i++) { // If repacking is going on for too long, show the splash progress bar if (isRepacking && splashProgressBarProc == null && timer.ElapsedMilliseconds > SPLASH_POPUP_DELAY) { timer.Stop(); if (splashExeExists) { splashProgressBarProc = Process.Start(splashPath, "-packing"); } } // Report progress to Appacker broadcaster.SendToChannel("AppackerProgress", $"{i} {filesToPack.Count}"); byte[] data = File.ReadAllBytes(Path.Combine(pathToFolderWithApp, filesToPack[i])); packedExe.Write(filesToPack[i]); // string packedExe.Write(data.Length); // int packedExe.Write(data); // byte[] } splashProgressBarProc?.Kill(); } }
private void OnNetworkMessageReceived(object sender, XDMessageEventArgs e) { if (disposed || !e.DataGram.IsValid) { return; } TypedDataGram <NetworkRelayMessage> dataGram = e.DataGram; if (dataGram != null && dataGram.IsValid && dataGram.Message.MachineName != Environment.MachineName) { // rebroadcast locally Task.Factory.StartNew( () => nativeBroadcast.SendToChannel(dataGram.Message.Channel, dataGram.Message.Message)); } }
private const int SPLASH_POPUP_DELAY = 1000; // ms //string unpackerExePath, string pathToPackedApp, string localPathToMainExe, string pathToFolderWithApp static int Main(string[] args) { #if DEBUG Console.WriteLine("Packer.exe is running in Debug"); Console.WriteLine("Attach to process now and press Enter..."); Console.ReadLine(); Console.WriteLine("Resuming"); #endif string unpackerExePath, pathToPackedApp, localPathToMainExe, pathToFolderWithApp; bool isSelfRepackable, isRepacking, openUnpackedDir; bool isNoGui = false; // determines the type of XDMessaging mode int unpackDirectory; // Temp = 0, Desktop = 1, SameAsPackedExe = 2 or AskAtLaunch = 3 try { #region == Arguments check and assignment == if (args.Length < 4) { Console.WriteLine("Arguments are missing. Usage:"); Console.WriteLine(USAGE); return(1); } // UPD: i should have used arguments parser library... Mistakes were made and i don't want to refactor them now .__. // UPD2: what a shitty code. I hate myself. unpackerExePath = args[0]; pathToPackedApp = args[1]; localPathToMainExe = args[2]; pathToFolderWithApp = args[3]; isSelfRepackable = false; if (args.Length > 4) { bool.TryParse(args[4], out isSelfRepackable); } if (args.Length > 5) { bool.TryParse(args[5], out isNoGui); } openUnpackedDir = false; if (args.Length > 6) { bool.TryParse(args[6], out openUnpackedDir); } unpackDirectory = 0; if (args.Length > 7) { int.TryParse(args[7], out unpackDirectory); if (unpackDirectory < 0 || unpackDirectory > 3) { unpackDirectory = 0; } } isRepacking = false; if (args.Length > 8 && (args[8] == "-repack" || args[8] == "repack")) { isRepacking = true; } // Create XDMessagingClient broadcaster to report progress // Creating it here so the broadcaster is initialized before any possible return => finally XDMessagingClient client = new XDMessagingClient(); // For command line launch use Compatibility mode, for GUI use HighPerformanceUI broadcaster = client.Broadcasters.GetBroadcasterForMode(isNoGui ? XDTransportMode.Compatibility : XDTransportMode.HighPerformanceUI); if (!File.Exists(unpackerExePath)) { Console.WriteLine("Unpacker.exe is missing."); return(2); } if (!Directory.Exists(pathToFolderWithApp)) { Console.WriteLine("Specified directory with application does not exist."); return(3); } if (!File.Exists(Path.Combine(pathToFolderWithApp, localPathToMainExe))) { Console.WriteLine("Main executable does not exist in app directory."); return(4); } // Check if the provided path where we gonna save packed exe is valid FileStream testFile = null; try { testFile = File.Create(pathToPackedApp + ".temp", 1, FileOptions.DeleteOnClose); } catch (Exception) { Console.WriteLine("Invalid path to packed executable."); return(5); } finally { testFile?.Close(); } #endregion // Get all files in the application folder (incl. sub-folders) List <string> filesToPack = GetFilesRecursively(pathToFolderWithApp); // Transform absolute paths into relative ones for (int i = 0; i < filesToPack.Count; i++) { filesToPack[i] = filesToPack[i].Replace(pathToFolderWithApp, string.Empty).TrimStart('\\'); } // If it's self-repacking process, then we should wait until packed app frees its .exe file if (isRepacking) { if (WaitForFileAccess(pathToPackedApp, WAIT_FOR_FILE_ACCESS_TIMEOUT) == false) { Console.WriteLine($"Can't access file {pathToPackedApp}"); return(6); } } timer.Start(); // Do the packing try { PackApp(unpackerExePath, pathToPackedApp, pathToFolderWithApp, localPathToMainExe, filesToPack, isSelfRepackable, isRepacking, openUnpackedDir, unpackDirectory); } catch (UnauthorizedAccessException) { Console.WriteLine($"Unauthorized access to {pathToPackedApp}"); return(6); } catch (Exception) { Console.WriteLine($"Oops! Something went wrong"); return(-1); } // If it was repack call, then packer.exe is the one who should remove the temp dir with the app after packing // Problem: packer.exe can't delete itself // Solution: launch just repacked app and tell it to kill this packer.exe if (isRepacking) { if (Directory.Exists(pathToFolderWithApp)) { Directory.Delete(pathToFolderWithApp, true); } Process.Start(pathToPackedApp, $@"-killme ""{System.Reflection.Assembly.GetEntryAssembly().Location}"""); } return(0); } finally { broadcaster.SendToChannel("AppackerProgress", "Done"); } }
private const int SPLASH_POPUP_DELAY = 1000; // ms static void Main(string[] args) { #if DEBUG Console.WriteLine("Unpacker is running in Debug"); Console.WriteLine("Attach to process now and press Enter..."); Console.ReadLine(); Console.WriteLine("Resuming"); #endif // After self-repacking, packer.exe can't delete itself from the temp dir, so it calls repacked app to kill it // Command is "unpacker.exe -killme <path to packer.exe>" // The whole folder where packer.exe is gets deleted (cuz there should also be temp unpacker.exe from repacking process) if (args.Length > 0 && (args[0] == "-killme" || args[0] == "killme")) { if (args.Length > 1) { if (WaitForFileAccess(args[1], WAIT_FOR_FILE_ACCESS_TIMEOUT) == true) { DeleteDirectory(Path.GetDirectoryName(args[1])); } } // Don't unpack anything. Just close the app now return; } // Subscribe for exit event to delete tempDir AppDomain.CurrentDomain.ProcessExit += new EventHandler(Unpacker_ProcessExit); // Create temp directory to store unpacked files while (tempDir == null || Directory.Exists(tempDir)) { tempDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); } Directory.CreateDirectory(tempDir); // Open self exe file as byte stream and unpack data that is appended to the end of exe string selfExePath = System.Reflection.Assembly.GetEntryAssembly().Location; using (var me = new BinaryReader(File.OpenRead(selfExePath))) { // Find the end of the actual unpacker.exe byte[] pattern = Encoding.UTF8.GetBytes("<SerGreen>"); long pos = FindPatternPosition(me.BaseStream, pattern); me.BaseStream.Seek(pos + pattern.Length, SeekOrigin.Begin); // Create temp directory to store tools while (repackerTempDir == null || Directory.Exists(repackerTempDir)) { repackerTempDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); } Directory.CreateDirectory(repackerTempDir); // Start extracting appended data isSelfRepackable = me.ReadBoolean(); if (isSelfRepackable) { // For repacking we also need the unpacker.exe itself // So return to the beginning of the file and save the unpacker.exe part me.BaseStream.Seek(0, SeekOrigin.Begin); File.WriteAllBytes(Path.Combine(repackerTempDir, "unpacker.exe"), me.ReadBytes((int)pos)); // Skip <SerGreen> keyword and 1 byte of isSelfRepackable flag me.ReadBytes(pattern.Length + 1); // Save the packer.exe int packerDataLength = me.ReadInt32(); File.WriteAllBytes(Path.Combine(repackerTempDir, "packer.exe"), me.ReadBytes(packerDataLength)); } // Extract splash screen tool if present isProgressBarSplashExePresent = me.ReadBoolean(); if (isProgressBarSplashExePresent) { int splashDataLength = me.ReadInt32(); File.WriteAllBytes(Path.Combine(repackerTempDir, "ProgressBarSplash.exe"), me.ReadBytes(splashDataLength)); } pathToMainExe = me.ReadString(); timer.Start(); Process splashProgressBarProc = null; // Keep extracting files until the end of the stream while (me.BaseStream.Position < me.BaseStream.Length) { // If unpacking process takes too long, display splash screen with progress bar if (isProgressBarSplashExePresent && broadcaster == null && timer.ElapsedMilliseconds > SPLASH_POPUP_DELAY) { // Create XDMessagingClient broadcaster to report progress XDMessagingClient client = new XDMessagingClient(); broadcaster = client.Broadcasters.GetBroadcasterForMode(XDTransportMode.HighPerformanceUI); splashProgressBarProc = Process.Start(Path.Combine(repackerTempDir, "ProgressBarSplash.exe"), "-unpacking"); timer.Stop(); } // Report progress to the Splash screen with progress bar broadcaster?.SendToChannel("AppackerProgress", $"{me.BaseStream.Position} {me.BaseStream.Length}"); targetAppFilesCount++; string path = me.ReadString(); int length = me.ReadInt32(); byte[] data = me.ReadBytes(length); // Create subdirectory if necessary string dir = Path.GetDirectoryName(path); if (!string.IsNullOrWhiteSpace(dir) && !Directory.Exists(Path.Combine(tempDir, dir))) { Directory.CreateDirectory(Path.Combine(tempDir, dir)); } File.WriteAllBytes(Path.Combine(tempDir, path), data); } unpackingDoneTimestamp = DateTime.Now; splashProgressBarProc?.Kill(); } // Launch unpacked app ProcessStartInfo procInfo = new ProcessStartInfo(Path.Combine(tempDir, pathToMainExe)); procInfo.WorkingDirectory = tempDir; Process proc = Process.Start(procInfo); // Wait until app exits to delete its files from temp directory proc.WaitForExit(); }
public void StopMonitor() { broadcaster.SendToChannel("ExplorerObserverCommand", "shutdown"); }
static void Main(string[] args) { #if DEBUG Console.WriteLine("Unpacker is running in Debug"); Console.WriteLine("Attach to process now and press Enter..."); Console.ReadLine(); Console.WriteLine("Resuming"); #endif // Hide console window if stdout is not redirected // If it is => keep window and later redirect I/O of the unpacked app too bool stdoutRedirected = Console.IsOutputRedirected; if (!stdoutRedirected) #if DEBUG { Console.WriteLine($"Output redirected: {stdoutRedirected}"); } Console.WriteLine("I'm hidden"); #else { ShowWindow(GetConsoleWindow(), SW_HIDE); } #endif // After self-repacking, packer.exe can't delete itself from the temp dir, so it calls repacked app to kill it // Command is "unpacker.exe -killme <path to packer.exe>" // The whole folder where packer.exe is gets deleted (cuz there should also be temp unpacker.exe from repacking process) if (args.Length > 0 && (args[0] == "-killme" || args[0] == "killme")) { if (args.Length > 1) { if (WaitForFileAccess(args[1], WAIT_FOR_FILE_ACCESS_TIMEOUT) == true) { DeleteDirectory(Path.GetDirectoryName(args[1])); } } // Don't unpack anything. Just close the app now return; } // Subscribe for exit event to delete tempDir AppDomain.CurrentDomain.ProcessExit += new EventHandler(Unpacker_ProcessExit); // Open self exe file as byte stream and unpack data that is appended to the end of exe string selfExePath = System.Reflection.Assembly.GetEntryAssembly().Location; using (var me = new BinaryReader(File.OpenRead(selfExePath))) { // Find the end of the actual unpacker.exe byte[] pattern = Encoding.UTF8.GetBytes("<SerGreen>"); long pos = FindPatternPosition(me.BaseStream, pattern); me.BaseStream.Seek(pos + pattern.Length, SeekOrigin.Begin); // Create temp directory to store tools while (repackerTempDir == null || Directory.Exists(repackerTempDir)) { repackerTempDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); } Directory.CreateDirectory(repackerTempDir); // Start extracting appended data isSelfRepackable = me.ReadBoolean(); if (isSelfRepackable) { // For repacking we also need the unpacker.exe itself // So return to the beginning of the file and save the unpacker.exe part me.BaseStream.Seek(0, SeekOrigin.Begin); File.WriteAllBytes(Path.Combine(repackerTempDir, "unpacker.exe"), me.ReadBytes((int)pos)); // Skip <SerGreen> keyword and 1 byte of isSelfRepackable flag me.ReadBytes(pattern.Length + 1); // Save the packer.exe int packerDataLength = me.ReadInt32(); File.WriteAllBytes(Path.Combine(repackerTempDir, "packer.exe"), me.ReadBytes(packerDataLength)); } // Extract splash screen tool if present isProgressBarSplashExePresent = me.ReadBoolean(); if (isProgressBarSplashExePresent) { int splashDataLength = me.ReadInt32(); File.WriteAllBytes(Path.Combine(repackerTempDir, "ProgressBarSplash.exe"), me.ReadBytes(splashDataLength)); } // Unpack directory loading openUnpackedDir = me.ReadBoolean(); unpackingDirectoryType = me.ReadInt32(); // Decode actual path // Desktop if (unpackingDirectoryType == 1) { unpackingDirectoryPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); } // Directory where this exe is located else if (unpackingDirectoryType == 2) { unpackingDirectoryPath = AppDomain.CurrentDomain.BaseDirectory; } // Ask user for a folder else if (unpackingDirectoryType == 3) { FolderBrowserDialog fbd = new FolderBrowserDialog { Description = "Select a folder in which to extract files" }; if (fbd.ShowDialog() == DialogResult.OK) { unpackingDirectoryPath = fbd.SelectedPath; } else { unpackingDirectoryPath = Path.GetTempPath(); } } // Default is %TEMP% else { unpackingDirectoryPath = Path.GetTempPath(); } // Create temp directory to store unpacked files while (tempDir == null || Directory.Exists(tempDir)) { tempDir = Path.Combine(unpackingDirectoryPath, Path.GetFileNameWithoutExtension(System.Reflection.Assembly.GetEntryAssembly().Location) + "_" + Guid.NewGuid().ToString()); } Directory.CreateDirectory(tempDir); // Load relative path to the main exe pathToMainExe = me.ReadString(); // Load launch arguments for main exe launchArguments = me.ReadString(); timer.Start(); Process splashProgressBarProc = null; // Keep extracting files until the end of the stream while (me.BaseStream.Position < me.BaseStream.Length) { // If unpacking process takes too long, display splash screen with progress bar if (isProgressBarSplashExePresent && broadcaster == null && timer.ElapsedMilliseconds > SPLASH_POPUP_DELAY) { // Create XDMessagingClient broadcaster to report progress XDMessagingClient client = new XDMessagingClient(); broadcaster = client.Broadcasters.GetBroadcasterForMode(XDTransportMode.HighPerformanceUI); splashProgressBarProc = Process.Start(Path.Combine(repackerTempDir, "ProgressBarSplash.exe"), "-unpacking"); timer.Stop(); } // Report progress to the Splash screen with progress bar broadcaster?.SendToChannel("AppackerProgress", $"{me.BaseStream.Position} {me.BaseStream.Length}"); targetAppFilesCount++; string path = me.ReadString(); int length = me.ReadInt32(); byte[] data = me.ReadBytes(length); // Create subdirectory if necessary string dir = Path.GetDirectoryName(path); if (!string.IsNullOrWhiteSpace(dir) && !Directory.Exists(Path.Combine(tempDir, dir))) { Directory.CreateDirectory(Path.Combine(tempDir, dir)); } File.WriteAllBytes(Path.Combine(tempDir, path), data); } unpackingDoneTimestamp = DateTime.Now; splashProgressBarProc?.Kill(); } // Open tempDir in Explorer if corresponding flag is set if (openUnpackedDir) { Process.Start(new ProcessStartInfo() { FileName = "explorer.exe", Arguments = tempDir, UseShellExecute = true, Verb = "open" }); } // Launch unpacked app ProcessStartInfo procInfo = new ProcessStartInfo() { FileName = Path.Combine(tempDir, pathToMainExe), Arguments = launchArguments + " " + string.Join(" ", args.Select(x => $"\"{x}\"")), WorkingDirectory = tempDir, UseShellExecute = !stdoutRedirected // if stdout is redirected, then redirect i/o of the target app too }; Process proc = Process.Start(procInfo); // Wait until app exits to delete its files from temp directory proc.WaitForExit(); }
private void Observer_ExplorerSelectionChanged(object sender, IntPtr e) { broadcaster.SendToChannel("SelectionOfExplorerWindowChanged", e.ToString()); }
/// <summary> /// The closing overrride used to broadcast on the status channel that the window is /// closing. /// </summary> /// <param name = "e"></param> protected override void OnClosing(CancelEventArgs e) { base.OnClosing(e); var message = string.Format("{0} is shutting down", Handle); broadcast.SendToChannel("Status", message); }
protected override void OnClosing(CancelEventArgs e) { base.OnClosing(e); var message = $"{Handle} is shutting down"; broadcast.SendToChannel("Status", message); }