i am trying to deploy DLLs inside a windows service by importing DLLs from various repositories like google drive/ dropbox/ ftp etc...
But before any new DLL can be instantiated, I would want the previous running instance to be shut down.
I am using tasks and reflection in this.
I am unable to figure out how to cancel the task that instantiate the DLL at run time ( as the instantiated dll is a long running application example file watcher.. )
CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken ct = cts.Token;
// instantiate the dll though reflection
t = Task.Factory.StartNew(() =>
{
try
{
Assembly assembly = Assembly.LoadFile(Directory.GetCurrentDirectory() + #"\" + dllName);
Type type = assembly.GetType("myclass.Program");
MethodInfo minfo = type.GetMethod("Main", BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Static | BindingFlags.Instance);
minfo.Invoke(Activator.CreateInstance(type), null);
}
catch (Exception ex)
{
log.Error(ex.ToString());
}
}, cts.Token);
Ques : I want to cancel the task t before my appication detects a new dll and tries to execute that through this task code.
EDIT
I removed the cancellation token code as it was breaking. Here is the actual code with the cancellation token.
CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken ct = cts.Token;
if (t != null)
{
cts.Cancel();
try
{
ct.ThrowIfCancellationRequested();
}
catch (Exception ex)
{
cts.Dispose();
t.Dispose();
}
}
// instantiate the dll though reflection
t = Task.Factory.StartNew(() =>
{
try
{
Assembly assembly = Assembly.LoadFile(Directory.GetCurrentDirectory() + #"\" + dllName);
Type type = assembly.GetType("myclass.Program");
MethodInfo minfo = type.GetMethod("Main", BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Static | BindingFlags.Instance);
minfo.Invoke(Activator.CreateInstance(type), null);
}
catch (Exception ex)
{
log.Error(ex.ToString());
}
}, cts.Token);
My idea was that if I could somehow cancel and dispose the task that was holding the instantiation context , the assembly would be released and then i will be able to update the assembly and re-instantiate it through the task again.
i know i am going wrong somewhere, kindly explain.
EDIT
i had high hopes with assemblyDomain.DoCallBack(delegate). But im getting an error. Here is the toned down version of code that throws the bug.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading.Tasks;
using System.Reflection;
namespace AppDomain
{
[Serializable]
class Program
{
static System.AppDomain assemblyDomain = null;
static void Main(string[] args)
{
var inp = "go";
while (inp.ToString().ToLower().Trim() != "stop")
{
start();
inp = Console.ReadLine();
}
}
private static void start()
{
//Check if appdomain and assembly is already loaded
if (assemblyDomain != null)
{
//unload appDomain and hence the assembly
System.AppDomain.Unload(assemblyDomain);
//Code to download new dll
}
string cwd = System.AppDomain.CurrentDomain.BaseDirectory;
string sourceFileName = #"C:\Users\guest\Documents\visual studio 2010\Projects\DotNetTraining\Lecture 1 - dotNetProgramExecution\bin\Debug\Lecture 1 - dotNetProgramExecution.exe";
string dllName = "Lecture 1 - dotNetProgramExecution.exe";
// copy the file
if (File.Exists(cwd + dllName))
{
File.Delete(cwd + dllName);
}
File.Copy(sourceFileName, cwd + dllName);
assemblyDomain = System.AppDomain.CreateDomain("assembly1Domain", null);
assemblyDomain.DoCallBack(() =>
{
var t = Task.Factory.StartNew(() =>
{
try
{
string sss = "";
Assembly assembly = Assembly.LoadFile(Directory.GetCurrentDirectory() + #"\" + dllName);
Type type = assembly.GetType("Lecture_1___dotNetProgramExecution.Program");
MethodInfo minfo = type.GetMethod("Main", BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Static | BindingFlags.Instance);
minfo.Invoke(Activator.CreateInstance(type), null);
// //var pathToDll = #"assembly path";
// //var dllName = "assembly name";
// var assembly = Assembly.LoadFile(Directory.GetCurrentDirectory() + #"\" + dllName);
// var targetAssembly = assembly.CreateInstance("Lecture_1___dotNetProgramExecution.Program");
// Type type = targetAssembly.GetType();
// MethodInfo minfo = type.GetMethod("Main", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);
// minfo.Invoke(targetAssembly, null);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
});
});
}
}
}
Error :
Type 'AppDomain.Program+<>c__DisplayClass2' in assembly 'AppDomain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.
Stack Trace :
at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
at AppDomain.Program.start() in c:\users\guest\documents\visual studio 2010\Projects\DotNetTraining\AppDomain\Program.cs:line 58
at AppDomain.Program.Main(String[] args) in c:\users\guest\documents\visual studio 2010\Projects\DotNetTraining\AppDomain\Program.cs:line 24
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
Please Note : I have marked the class Program in the assembly im importing as Serializable
namespace Lecture_1___dotNetProgramExecution
{
[Serializable]
class Program
{
static void Main()
{
Updated :
code of the dynamically pulled assembly
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Threading;
namespace Lecture_1___dotNetProgramExecution
{
[Serializable]
class Program
{
static void Main()
{
try
{
Task.Factory.StartNew(() =>
{
while (true)
{
StringBuilder sb = new StringBuilder();
sb.Append("log something new yippe ");
// flush every 20 seconds as you do it
File.AppendAllText(#"C:\logs.txt", sb.ToString());
sb.Clear();
Thread.Sleep(3000);
}
});
FileSystemWatcher fsw = new FileSystemWatcher();
fsw.Path = #"c:\watched";
//fsw.filter = ".dll";
fsw.Created += new FileSystemEventHandler(fsw_Created);
fsw.BeginInit();
//throw new FileNotFoundException();
Console.ReadLine();
}
catch (Exception ex)
{
Task.Factory.StartNew(() =>
{
while (true)
{
StringBuilder sb = new StringBuilder();
sb.Append("loggind froom exception log something");
// flush every 20 seconds as you do it
File.AppendAllText(#"C:\logs.txt", sb.ToString());
sb.Clear();
Thread.Sleep(1000);
}
});
Console.ReadLine();
}
}
static void fsw_Created(object sender, FileSystemEventArgs e)
{
throw new NotImplementedException();
}
}
}
From your question it appears that you want to unload the dynamically loaded assembly if any upgrade is available, then reload the latest assembly. The cancellation taken will no help in this case. In fact I don't see you are using cancellation token anywhere.
The only way to unload a dynamically loaded assembly is to fist load the the assembly in separate app domain then unload the app domain itself if assembly is no more needed. So you should be doing as follow:
Create a new app domain. Keep the reference of app domain, you will need it later to unload the domain and hence assembly.
Load the assembly in newly created app domain.
Create an instance of type from newly loaded assembly as needed and execute its method.
When a new version of dll is available, unload the previously created app domain. This will automatically unload the assembly too.
Download the new assembly and start from step 1 again.
See this for how to load/unload app domain and assembly in it: Using AppDomain in C# to dynamically load and unload dll
EDIT: Below is the code snippet with AppDomain.DoCallback
using System;
using System.IO;
using System.Reflection;
using System.Threading.Tasks;
namespace AppDomain
{
[Serializable]
class Program
{
static System.AppDomain assemblyDomain = null;
static void Main(string[] args)
{
var inp = "go";
while (inp.ToString().ToLower().Trim() != "stop")
{
start();
inp = Console.ReadLine();
}
}
private static void start()
{
//Check if appdomain and assembly is already loaded
if (assemblyDomain != null)
{
//unload appDomain and hence the assembly
System.AppDomain.Unload(assemblyDomain);
//Code to download new dll
}
string cwd = System.AppDomain.CurrentDomain.BaseDirectory;
string sourceFileName = #"C:\Users\deepak\Documents\visual studio 2010\Projects\ConsoleApplication1\ConsoleApplication2\bin\Debug\ConsoleApplication2.exe";
string dllName = "ConsoleApplication2.exe";
// copy the file
if (File.Exists(cwd + dllName))
{
File.Delete(cwd + dllName);
}
File.Copy(sourceFileName, cwd + dllName);
assemblyDomain = System.AppDomain.CreateDomain("assembly1Domain", null);
assemblyDomain.DoCallBack(() =>
{
var t = Task.Factory.StartNew(() =>
{
try
{
string sss = "";
string dllName1 = "ConsoleApplication2.exe";
Assembly assembly = Assembly.LoadFile(Directory.GetCurrentDirectory() + #"\" + dllName1);
Type type = assembly.GetType("Lecture_1___dotNetProgramExecution.Program");
MethodInfo minfo = type.GetMethod("Main", BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Static | BindingFlags.Instance);
minfo.Invoke(Activator.CreateInstance(type), null);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
});
});
}
}
}
using System;
using System.Text;
using System.Threading;
namespace Lecture_1___dotNetProgramExecution
{
[Serializable]
class Program
{
static void Main()
{
while (true)
{
StringBuilder sb = new StringBuilder();
sb.Append("log something new yippe ");
// flush every 20 seconds as you do it
//File.AppendAllText(#"C:\logs.txt", sb.ToString());
Console.WriteLine(sb.ToString());
sb.Clear();
Thread.Sleep(3000);
}
}
}
}
Related
I want to write a window service for keep capturing the network traffic and save the packets info into a log file, but I can't start it.
"Error 1064: An exception occurred in the service when handling the control request."
References:
Capturing And Parsing Packets
Save Output to Log
Create Window Service
Here's the code for Windows Service(failed):
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
using CapturingAndParsingPackets;
using PacketDotNet;
using SharpPcap;
namespace CaptureService
{
public partial class Service1 : ServiceBase
{
private static bool _stopCapturing;
string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);//Get the desktop path
string filename = DateTime.Now.ToString("yyyy-MM-dd--HH-mm-ss");//Use date to name the file
public Service1()
{
InitializeComponent();
var devices = CaptureDeviceList.Instance; //Get the local devices
if (devices.Count < 1)
{
OnStop();
return;
}
}
protected override void OnStart(string[] args)
{
var devices = CaptureDeviceList.Instance; //Get the local devices
//set output type
var defaultOutputType = StringOutputType.Normal;
var outputTypeValues = Enum.GetValues(typeof(StringOutputType));
StringOutputType selectedOutputType = defaultOutputType;
int userSelectedOutputType;
userSelectedOutputType = 3;
selectedOutputType = (StringOutputType)userSelectedOutputType;
//read local device
var device = devices[3];
//read packets
var readTimeoutMilliseconds = 1000;
device.Open(DeviceModes.Promiscuous, readTimeoutMilliseconds);
//set filter
string filter = "host 192.168.0.212";
device.Filter = filter;
PacketCapture e;
var status = device.GetNextPacket(out e);
var rawCapture = e.GetPacket();
// use PacketDotNet to parse this packet and print out
// its high level information
var p = Packet.ParsePacket(rawCapture.GetLinkLayers(), rawCapture.Data);
// Create a log file to desktop and write the log into the log file
using (StreamWriter w = File.AppendText(path + "\\" + filename + ".log"))
{
Log(p.ToString(selectedOutputType) + p.PrintHex(), w);
}
device.Close();
}
public static void Log(string logMessage, TextWriter txtWriter)
{
try
{
txtWriter.Write("\r\nLog Entry : ");
txtWriter.WriteLine("{0} {1}", DateTime.Now.ToLongTimeString(),
DateTime.Now.ToLongDateString());
txtWriter.WriteLine();
txtWriter.WriteLine(logMessage);
txtWriter.WriteLine("============================================================================================================");
}
catch (Exception)
{
}
}
protected override void OnStop()
{
using (StreamWriter w = File.AppendText(path + "\\" + filename + ".log"))
{
Log("Service is stopped at " + DateTime.Now, w);
}
}
}
}
And Here is the script for just running it in VS(works fine):
using System;
using PacketDotNet;
using SharpPcap;
using System.IO;
using System.Reflection;
using log4net;
using log4net.Config;
namespace CapturingAndParsingPackets
{
class MainClass
{
// used to stop the capture loop
private static bool _stopCapturing;
public static void Main(string[] args)
{
// Print SharpPcap version
var ver = SharpPcap.Pcap.SharpPcapVersion;
Console.WriteLine("PacketDotNet example using SharpPcap {0}", ver);
// Retrieve the device list
var devices = CaptureDeviceList.Instance;
// If no devices were found print an error
if (devices.Count < 1)
{
Console.WriteLine("No devices were found on this machine");
return;
}
Console.WriteLine();
Console.WriteLine("The following devices are available on this machine:");
Console.WriteLine("----------------------------------------------------");
Console.WriteLine();
var i = 0;
// Print out the devices
foreach (var dev in devices)
{
/* Description */
Console.WriteLine("{0}) {1} {2}", i, dev.Name, dev.Description);
i++;
}
Console.WriteLine();
Console.Write("-- Please choose a device to capture: ");
Console.WriteLine();
Console.WriteLine("Output Verbosity Options");
Console.WriteLine("----------------------------------------------------");
Console.WriteLine();
var defaultOutputType = StringOutputType.Normal;
var outputTypeValues = Enum.GetValues(typeof(StringOutputType));
foreach (StringOutputType outputType in outputTypeValues)
{
Console.Write("{0} - {1}", (int)outputType, outputType);
if (outputType == defaultOutputType)
{
Console.Write(" (default)");
}
Console.WriteLine("");
}
Console.WriteLine();
Console.Write("-- Please choose a verbosity (or press enter for the default): ");
StringOutputType selectedOutputType = defaultOutputType;
int userSelectedOutputType;
//Fixed
userSelectedOutputType = 3;
selectedOutputType = (StringOutputType)userSelectedOutputType;
// Register a cancel handler that lets us break out of our capture loop
Console.CancelKeyPress += HandleCancelKeyPress;
//Fixed
var device = devices[3];
// Open the device for capturing
var readTimeoutMilliseconds = 1000;
device.Open(DeviceModes.Promiscuous, readTimeoutMilliseconds);
//filter host 192.168.0.212
//or you can set it to "filter = 'ip'; " for default
string filter = "host 192.168.0.212";
device.Filter = filter;
Console.WriteLine();
Console.WriteLine("-- Listening on {0}, hit 'ctrl-c' to stop...",
device.Name);
while (_stopCapturing == false)
{
PacketCapture e;
var status = device.GetNextPacket(out e);
// null packets can be returned in the case where
// the GetNextRawPacket() timed out, we should just attempt
// to retrieve another packet by looping the while() again
if (status != GetPacketStatus.PacketRead)
{
// go back to the start of the while()
continue;
}
var rawCapture = e.GetPacket();
// use PacketDotNet to parse this packet and print out
// its high level information
var p = Packet.ParsePacket(rawCapture.GetLinkLayers(), rawCapture.Data);
Console.WriteLine(p.ToString(selectedOutputType) + p.PrintHex());
Console.WriteLine("============================================================================================================");
using (StreamWriter w = File.AppendText("networkTraffic.log"))
{
Log(p.ToString(selectedOutputType), w);
Log(p.PrintHex(), w);
}
}
Console.WriteLine("-- Capture stopped");
// Print out the device statistics
Console.WriteLine(device.Statistics.ToString());
// Close the pcap device
device.Close();
}
static void Log(string logMessage, TextWriter txtWriter)
{
try
{
txtWriter.Write("\r\nLog Entry : ");
txtWriter.WriteLine("{0} {1}", DateTime.Now.ToLongTimeString(),
DateTime.Now.ToLongDateString());
txtWriter.WriteLine();
txtWriter.WriteLine(logMessage);
txtWriter.WriteLine("============================================================================================================");
}
catch (Exception)
{
}
}
static void HandleCancelKeyPress(object sender, ConsoleCancelEventArgs e)
{
Console.WriteLine("-- Stopping capture");
_stopCapturing = true;
// tell the handler that we are taking care of shutting down, don't
// shut us down after we return because we need to do just a little
// bit more processing to close the open capture device etc
e.Cancel = true;
}
}
}
The error that shows in Event Viewer(1064):
Application: CaptureTrafficService.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.IO.FileNotFoundException
at CaptureTrafficService.Service1.OnStart(System.String[])
at System.ServiceProcess.ServiceBase.ServiceQueuedMainCallback(System.Object)
at System.ServiceProcess.ServiceBase.Run(System.ServiceProcess.ServiceBase[])
at CaptureTrafficService.Program.Main()
Service cannot be started. System.IO.FileNotFoundException: Could not load file or assembly 'netstandard, Version=2.1.0.0, Culture=neutral, PublicKeyToken=cc7b1xxxxxxxxxxx' or one of its dependencies. The system cannot find the file specified.
File name: 'netstandard, Version=2.1.0.0, Culture=neutral, PublicKeyToken=cc7b1xxxxxxxxxxx'
at CaptureTrafficService.Service1.OnStart(String[] args)
at System.ServiceProcess.ServiceBase.ServiceQueuedMainCallback(Object state)
After I remove the while loop in OnStart method, It shows up another error(1053):
Application: CaptureTrafficService.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.IO.FileNotFoundException
Exception Info: System.IO.FileNotFoundException
at CaptureService.Service1..ctor()
at CaptureService.Program.Main()
The answer by #Sam1916 might lessen the frustration of FileNotFoundException.
The "System.IO.FileNotFoundException" caught my attention - but missing info on what files.
As Windows services run in "their own context" the files referenced (Through "using") might not exists in a readable directory, hench "FileNotFoundException"
Is the logfile placed in a directory where your service credentials are allowed to write?
There are too many unnecessary references that may affect each other in the solution so that it will return a lot of errors & warnings when building it. Just add them one by one if it is necessary, rebuild it when you added a new reference(for checking the compatibility) and not just copying all of them to the solution.
Too many unnecessary references(Before)
Just add the references you need(After)
Here's the code that works with windows service:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using SharpPcap;
using PacketDotNet;
namespace Capture
{
public partial class Capture : ServiceBase
{
Timer timer = new Timer();
public Capture()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
Log("Service started at " + DateTime.Now);
timer.Elapsed += new ElapsedEventHandler(OnElapsedTime);
//timer.Interval = 5000;
timer.Enabled = true;
}
protected override void OnStop()
{
Log("Service is stopped at " + DateTime.Now);
}
private void OnElapsedTime(object source, ElapsedEventArgs e)
{
var devices = CaptureDeviceList.Instance;
//set output type
var defaultOutputType = StringOutputType.Normal;
StringOutputType selectedOutputType = defaultOutputType;
int userSelectedOutputType;
userSelectedOutputType = ? ;//? = 0-3
selectedOutputType = (StringOutputType)userSelectedOutputType;
//read local device
var device = devices[?];//? is mean num 0-4 or more(depends on your device)
//read packets
var readTimeoutMilliseconds = 1000;
device.Open(DeviceModes.Promiscuous, readTimeoutMilliseconds);
PacketCapture d;
var status = device.GetNextPacket(out d);
var rawCapture = d.GetPacket();
var p = Packet.ParsePacket(rawCapture.LinkLayerType, rawCapture.Data);
Log(p.ToString(selectedOutputType) +p.PrintHex());//write to log file
device.Close();
}
public static void Log(string logMessage)
{
string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);+ "\\Logs" ;
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
string filepath =Environment.GetFolderPath(Environment.SpecialFolder.Desktop); + "\\Logs\\ServiceLog_" +
DateTime.Now.Date.ToShortDateString().Replace('/','_') + ".log";
using (StreamWriter sw = File.AppendText(filepath))
{
sw.WriteLine(logMessage);
sw.WriteLine("============================================================================================================");
}
}
}
}
I am streaming a DLL to a Client through WebClient, I am trying to load my .net Executable directly into Memory and executing it by loading it as an Assembly. This Executable is a Windows Form that creates DirectX Overlays and Loads a Kernel Driver as a Windows Service.
Unhandled Exception: System.TypeInitializationException: The type initializer for 'IOController.Main' threw an exception. ---> System.IndexOutOfRangeException: Index was outside the bounds of the array.
at IOController.Main..cctor()
--- End of inner exception stack trace ---
at IOController.Main.Dispose(Boolean disposing)
at System.ComponentModel.Component.Finalize()
I do believe the Executable is executed but crashes before Application.Run or while executing Application.Run();
Update 1:
Anything posted in IOController Main is what would be called if my Main Function actually gets executed. It would stop at the While Loop which checks for a Process. My Window doesnt get Initialized until after the Loop so no event handlers would fire either.
An application being loaded:
public static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Start();
}
public static void Start()
{
//MessageBox.Show("Hi");
Application.Run(new Main());
}
}
The Application loading it:
byte[] bytes = null;
try
{
using (var client = new WebClient())
{
client.Headers.Add("User-Agent", User_Agent);
bytes = client.DownloadData(uri);
}
}
catch (Exception ex)
{
Console.WriteLine("Download Failed:");
Console.WriteLine(ex.ToString());
SoftEnd();
}
Console.WriteLine("Bytes:" + bytes.LongLength);
var assembly = Assembly.Load(bytes);
var programType = assembly.GetTypes().FirstOrDefault(c => c.Name == "Program");
var method = programType.GetMethod("Start", BindingFlags.Public | BindingFlags.Static);
method.Invoke(null, new object[] { });
IOController Main:
//Thread DebuggerCheck = new Thread(Debugger);
//DebuggerCheck.Start();
if (!Directory.Exists(User_Path))
{
Directory.CreateDirectory(User_Path);
File.SetAttributes(User_Path, FileAttributes.System | FileAttributes.Hidden);
}
else
{
File.SetAttributes(User_Path, FileAttributes.System | FileAttributes.Hidden);
}
if (!Directory.Exists(HWID_Path))
{
Directory.CreateDirectory(HWID_Path);
File.SetAttributes(HWID_Path, FileAttributes.System | FileAttributes.Hidden);
}
else
{
File.SetAttributes(HWID_Path, FileAttributes.System | FileAttributes.Hidden);
}
WebClient webClient = new WebClient();
if (!File.Exists(HWID_Path + "KasperAV.sys"))
{
webClient.Headers.Add("User-Agent", Authenticate.User_Agent);
webClient.DownloadFile(Authenticate.Auth_Server + "Request=Download&Username=" + Username + "&Password=" + Password + "&HWID=" + FingerPrint.Value() + "&File=KasperAV.sys", HWID_Path + "KasperAV.sys");
File.SetAttributes(HWID_Path + "KasperAV.sys", FileAttributes.System | FileAttributes.Hidden);
}
else
File.SetAttributes(HWID_Path + "KasperAV.sys", FileAttributes.System | FileAttributes.Hidden);
if (IOControl.LoadDriver())
//Console.WriteLine("Driver Loaded");
//Filter Windows Name for Illegal Chars
WindowsName = WindowsName.Replace("*", "");
WindowsName = WindowsName.Replace("'", "");
WindowsName = WindowsName.Replace(";", "");
//Filter Machine Name for Illegal Chars
MachineName = MachineName.Replace("*", "");
MachineName = MachineName.Replace("'", "");
MachineName = MachineName.Replace(";", "");
//Check hash from Server
bool Now_Started = false;
if (!Now_Started)
{
Console.WriteLine("We advise you when exiting the cheat, use your 'End' button on your keyboard!");
Console.WriteLine("It will properly cleanup any leftover data that may cause a ban on other games.");
if (IsGameRunning()) //if the game is running
{
Now_Started = false;
}
else
{
Now_Started = true;
}
//Skip this
if (Now_Started)
{
Console.WriteLine("Waiting for H1Z1");
while (true)
{
if (IsGameRunning())
{
break;
}
Thread.Sleep(1000);
}
Console.WriteLine("::Game Launched - Waiting 30 seconds for the memory to load.");
int i = 0;
while (i < 30000)
{
Thread.Sleep(1);
Console.Write("\rElapsed: {0}ms \\ 30000ms", i++);
i++;
}
}
}
else
{
Console.WriteLine("Failed to Load Bypass, attempt a full reboot!");
Thread.Sleep(5000);
Exit();
}
Was calling GetCommandlineArguments when I wasn't passing any ( since I switched to loading the assembly rather than executing it ).
I'm trying to get all Exception messages in English, no matter what language is the machine my program running on.
I've manage to get almost all exception messages in English using answers from the following posts:
Exception messages in English?
and some other solution I've found (like using reflection to change the default CultureInfo).
I have specific problem with SocketException, No matter what I'm doing I'm getting it in the default machine's language.
I've created a test program to show the problem:
This test program will print Exceptions in default language:
using System;
using System.Text;
using System.Threading;
using System.IO;
using System.Net.Sockets;
using System.Reflection;
using System.Globalization;
namespace TestApp
{
class Program
{
static void Main(string[] args)
{
try
{
//I'm not listening on the following port:
TcpClient s = new TcpClient("localhost", 2121);
}
catch (Exception ex)
{
Console.WriteLine("Socket exception: " + ex.Message);
}
try
{
//the following file doesn't exists:
File.ReadAllText("filenotexist.txt");
}
catch (Exception ex)
{
Console.WriteLine("File exception: " + ex.Message);
}
}
}
}
This result on my machine the following text:
H:\Shared>Test-def.exe
Socket exception: No connection could be made because the target machine actively refused it 127.0.0.1:2121
File exception: Could not find file 'H:\Shared\filenotexist.txt'.
On Japanese machine it write all exceptions in Japanese (which I don't understand):
Z:\>Test-def.exe
Socket exception: 対象のコンピューターによって拒否されたため、接続できませんでした。 127.0.0.1:2121
File exception: ファイル 'Z:\filenotexist.txt' が見つかりませんでした。
(The Japanese '\' looks different in Japanese machine, but when copied to my machine it shown as '\')
So from combining of the answers I've found, I've implemented the following solution, so now it looks like this:
namespace TestApp
{
class Program
{
//will change CultureInfo to English, this should change all threads CultureInfo to English.
public static void SetEnglishCulture()
{
CultureInfo ci = new CultureInfo("en-US");
//change CultureInfo for current thread:
Thread.CurrentThread.CurrentUICulture = ci;
Thread.CurrentThread.CurrentCulture = ci;
//change CultureInfo for new threads:
Type t = typeof(CultureInfo);
try
{
t.InvokeMember("s_userDefaultCulture", BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Static, null, ci, new object[] { ci });
t.InvokeMember("s_userDefaultUICulture", BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Static, null, ci, new object[] { ci });
}
catch { }
try
{
t.InvokeMember("m_userDefaultCulture", BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Static, null, ci, new object[] { ci });
t.InvokeMember("m_userDefaultUICulture", BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Static, null, ci, new object[] { ci });
}
catch { }
}
static void Main(string[] args)
{
//first thing: set CultureInfo to English:
SetEnglishCulture();
try
{
//I'm not listening on the following port:
TcpClient s = new TcpClient("localhost", 2121);
}
catch (Exception ex)
{
Console.WriteLine("Socket exception: " + ex.Message);
}
try
{
//the following file doesn't exists:
File.ReadAllText("filenotexist.txt");
}
catch (Exception ex)
{
Console.WriteLine("File exception: " + ex.Message);
}
}
}
}
Now on Japanese machine it write the file exceptions in English but the Net.socket exceptions are still in Japanese:
Z:\>Test-en.exe
Socket exception: 対象のコンピューターによって拒否されたため、接続できませんでした。 127.0.0.1:2121
File exception: Could not find file 'Z:\filenotexist.txt'.
I've also tested some other exceptions, some exceptions are now shown in English, but not all of them, the socket exceptions are persistent. As you can see, the file exception had been translated to English, but the socket exception is still in Japanese.
I've tested it in almost any .NET framework (from 2.1 to 4.5) still the same.
Is there a complete solution for all the exceptions?
Did I missed anything?
Should I do anything else?
Maybe there's other way to run program on foreign machine, and set some environment variable, to get English output?
I have a solution so I'll upload it here in case someone will need it.
If anyone have a better solution I'll be happy to know so please comment.
In case of Win32Exception, we can use FormatMessage and translate the error code to both English and default languages, and replace the default by English.
If I take the English without replace, I lose the parameters. so in case the replace failed I'll return the Exception With additional description in English.
Here's my full solution:
using System;
using System.IO;
using System.Text;
using System.Threading;
using System.Net.Sockets;
using System.Globalization;
using System.Reflection;
using System.ComponentModel;
using System.Runtime.InteropServices;
namespace TestCulture
{
class Program
{
static void SetEnglishCulture()
{
CultureInfo ci = new CultureInfo("en-US");
Thread.CurrentThread.CurrentCulture = ci;
Thread.CurrentThread.CurrentUICulture = ci;
Type type = typeof(CultureInfo);
try
{
type.InvokeMember("s_userDefaultCulture", BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Static, null, ci, new object[] { ci });
type.InvokeMember("s_userDefaultUICulture", BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Static, null, ci, new object[] { ci });
} catch { }
try
{
type.InvokeMember("m_userDefaultCulture", BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Static, null, ci, new object[] { ci });
type.InvokeMember("m_userDefaultUICulture", BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Static, null, ci, new object[] { ci });
} catch { }
}
[DllImport("kernel32.dll")]
static extern uint FormatMessage(uint dwFlags, IntPtr lpSource, uint dwMessageId, uint dwLanguageId, StringBuilder lpBuffer, uint nSize, IntPtr Arguments);
public static string Win32ExceptionInEnglish(Win32Exception ex)
{
const int nCapacity = 820; // max error length
const uint FORMAT_MSG_FROM_SYS = 0x01000;
const uint engLangID = (0x01<<10) | 0x09;
const uint defLangID = 0x0;
StringBuilder engSb = new StringBuilder(nCapacity);
StringBuilder defSb = new StringBuilder(nCapacity);
FormatMessage(FORMAT_MSG_FROM_SYS,IntPtr.Zero, (uint)ex.ErrorCode, defLangID, defSb, nCapacity, IntPtr.Zero);
FormatMessage(FORMAT_MSG_FROM_SYS,IntPtr.Zero, (uint)ex.ErrorCode, engLangID, engSb, nCapacity, IntPtr.Zero);
string sDefMsg = defSb.ToString().TrimEnd(' ','.','\r','\n');
string sEngMsg = engSb.ToString().TrimEnd(' ','.','\r','\n');
if(sDefMsg == sEngMsg) //message already in English (or no english on machine?)
{
//nothing left to do:
return ex.Message;
}
else
{
string msg = ex.Message.Replace(sDefMsg,sEngMsg);
if (msg == ex.Message)
{
//replace didn't worked, can be message with arguments in the middle.
//I such as case print both: original and translated. to not lose the arguments.
return ex.Message + " (In English: " + sEngMsg + ")";
}
else
{
//successfuly replaced!
return msg;
}
}
}
public static void Main(string[] args)
{
SetEnglishCulture();
try {
// generate any exception ...
const int notListenningPort = 2121;
new TcpClient("localhost", notListenningPort);
}
catch(Win32Exception ex)//first try to cach win32 Exceptions
{
Console.WriteLine("W32 Exception: " + Win32ExceptionInEnglish(ex));
}
catch(Exception ex)//this fit to the rest .NET exceptions which affected by CultureInfo
{
Console.WriteLine("Exception: " +ex.Message);
}
}
}
}
A SocketException is a Win32Exception. Like all other classes that derive from Win32Exception, it gets its message from Windows using Win32Exception.GetErrorMessage(int error), which uses FormatMessage in Kernel32.DLL.
In doing so, the message effectively comes from Windows, not from .NET. Windows will return a message in the Windows display language, and AFAIK, there is nothing you can do about that from within your .NET program.
You may have to wrap the line that prints error to console in a separate thread that has locale set to english because the Framework exception code loads the error messages from its resources based on the current thread locale.
here is what i am talking about in a bit of code:
static void Main(string[] args) {
try {
TcpClient c = new TcpClient("localhost", 1234);
}
catch (Exception ex) {
// thread that logs exception message to console
Thread logger = new Thread(new ParameterizedThreadStart(PrintException));
logger.CurrentCulture = new System.Globalization.CultureInfo("en-US");
logger.Start(ex);
}
}
private static void PrintException(object ex) {
Console.WriteLine("Error: " + ((Exception)ex).Message);
}
I have a C# console program that uses the nuget plugin SocketIO4Net
When I build the exe and move it to my Windows 2008 server, it doesn't work, whereas on my local machine, it works.
Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'SocketIOClient, Version=0.6.26.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
Is there any way I can bake all my dependencies into the exe?
I tried doing:
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
{
var resName = "converter.SocketIOClient.dll";
var thisAssembly = Assembly.GetExecutingAssembly();
using (var input = thisAssembly.GetManifestResourceStream(resName))
{
return input != null
? Assembly.Load(StreamToBytes(input))
: null;
}
};
But that didn't work. Perhaps I'm getting the resourceName wrong?
Here is my example which is based off of Embedding one dll inside another as an embedded resource and then calling it from my code but has some helpful screenshots.
using System;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
using MyEmbbedFile;
namespace ProjectNameSpace
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
{
var resName = "ProjectNameSpace.MyEmbbedFile.dll";
var thisAssembly = Assembly.GetExecutingAssembly();
using (var input = thisAssembly.GetManifestResourceStream(resName))
{
return input != null
? Assembly.Load(StreamToBytes(input))
: null;
}
};
}
private void button1_Click(object sender, EventArgs e)
{
MyEmbbedFileApp app = new MyEmbbedFileApp();
app.DoStuff();
}
private static byte[] StreamToBytes(Stream input)
{
var capacity = input.CanSeek ? (int)input.Length : 0;
using (var output = new MemoryStream(capacity))
{
int readLength;
var buffer = new byte[4096];
do
{
readLength = input.Read(buffer, 0, buffer.Length);
output.Write(buffer, 0, readLength);
}
while (readLength != 0);
return output.ToArray();
}
}
}
}
There are 2 other things you will need to do:
You will still need to make sure you add your assembly as a reference so your code compiles. Just make sure it does not copy to the output directory.
The second thing you need to do is add your reference to the project as a normal file. Then set it's build action to Embedded Resource under properties.
Yes.
Use AppDomain.AssemblyResolve to 'hydrate' embedded assemblies at runtime.
This project SQLDiagCmd at Github contains an example of doing this. It is based on Jeffrey Ricther's method:
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
{
String resourceName = "AssemblyLoadingAndReflection." +
new AssemblyName(args.Name).Name + ".dll";
using (var stream = Assembly.GetExecutingAssembly()
.GetManifestResourceStream(resourceName))
{
Byte[] assemblyData = new Byte[stream.Length];
stream.Read(assemblyData, 0, assemblyData.Length);
return Assembly.Load(assemblyData);
}
};
The 'trick' is where the embedded assembly is located and (as you have found), the string used to refer to it in the AssemblyResolve handler. [I don't have time right now but will look again later...]
I have very bad perfomance of HttpWebRequest.GetResponse method when it is called from different thread for different URLs.
For example if we have one thread and execute url1 it requires 3sec.
If we ececute url1 and url2 in parallet it requires 10sec, first request ended after 8sec and second after 10sec.
If we exutet 10 URLs url1, url2, ... url0 it requires 1min 4 sec!!! first request ended after 50 secs!
I use GetResponse method.
I tried te set DefaultConnectionLimit but it doesn't help.
If use BeginGetRequest/EndGetResponse methods it works very fast but only if this methods called from one thread. If from different it is also very slowly.
I need to execute Http requests from many threads at one time.
the same code executed in each thread. If only one thread GetResponse method works very fast.
Also IP addreses in URLs are different for each thread.
If you compile and run the following code you will see that requests hanled one by one. Fist executed 3 secs, second 8 secs, third 15secs ....
i.e. no gains from multithreading.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Xml;
using System.Reflection;
using System.Threading;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Collections;
namespace HttpRequestExample
{
class HttpPerformer
{
private Thread thread = null;
HttpWebRequest httpRequest = null;
public void start(string url)
{
thread = new Thread(new ThreadStart(WorkerThread));
thread.Name = url;
thread.Start();
}
public void WorkerThread()
{
try
{
HttpWebRequest req = (HttpWebRequest)WebRequest.Create((string)thread.Name);
Console.WriteLine(DateTime.Now + " : before get response " + thread.Name);
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
Console.WriteLine(DateTime.Now + " : after get response " + thread.Name);
}
catch (Exception e)
{
Console.WriteLine(DateTime.Now + " : Exception : " + e.Message + thread.Name);
}
}
}
class HttpAccessUtils
{
public static bool SetAllowUnsafeHeaderParsing20()
{
//Get the assembly that contains the internal class
Assembly aNetAssembly = Assembly.GetAssembly(typeof(System.Net.Configuration.SettingsSection));
if (aNetAssembly != null)
{
//Use the assembly in order to get the internal type for the internal class
Type aSettingsType = aNetAssembly.GetType("System.Net.Configuration.SettingsSectionInternal");
if (aSettingsType != null)
{
//Use the internal static property to get an instance of the internal settings class.
//If the static instance isn't created allready the property will create it for us.
object anInstance = aSettingsType.InvokeMember("Section",
BindingFlags.Static | BindingFlags.GetProperty | BindingFlags.NonPublic, null, null, new object[] { });
if (anInstance != null)
{
//Locate the private bool field that tells the framework is unsafe header parsing should be allowed or not
FieldInfo aUseUnsafeHeaderParsing = aSettingsType.GetField("useUnsafeHeaderParsing", BindingFlags.NonPublic | BindingFlags.Instance);
if (aUseUnsafeHeaderParsing != null)
{
aUseUnsafeHeaderParsing.SetValue(anInstance, true);
return true;
}
}
}
}
return false;
}
}
class Program
{
static void Main(string[] args)
{
HttpAccessUtils.SetAllowUnsafeHeaderParsing20();
ServicePointManager.UseNagleAlgorithm = true;
ServicePointManager.Expect100Continue = true;
ServicePointManager.CheckCertificateRevocationList = true;
ServicePointManager.DefaultConnectionLimit = 200; //ServicePointManager.DefaultPersistentConnectionLimit;
ServicePointManager.MaxServicePoints = 100;
Console.WriteLine(ServicePointManager.MaxServicePoints);
ArrayList a = new ArrayList(150);
for (int i = 100; i < 220; i++)
{
a.Add("http://207.242.7." + i.ToString());
}
for (int i = 0; i < a.Count; i++)
{
HttpPerformer hp = new HttpPerformer();
hp.start((string)a[i]);
}
}
static void performRequest(object url)
{
try
{
HttpWebRequest req = (HttpWebRequest)WebRequest.Create((string)url);
Console.WriteLine(DateTime.Now + " : before get response " + url);
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
Console.WriteLine(DateTime.Now + " : after get response " + url);
}
catch (Exception e)
{
Console.WriteLine(DateTime.Now + " : Exception : " + e.Message + (string)url);
}
}
}
}
Сan anyone ever encountered such a problem? Thank you for any suggestions.
You need to close the conn after getting the response stream, otherwise the connection will remain open for long. This might be the cause of the slowness.
You need to close connection after getting response. That seems to cause the problem.