I wrote the following EXE File in C#:
namespace Service
{
class Program
{
[DllImport("user32.dll")]
public static extern int GetAsyncKeyState(Int32 i);
static void Main(string[] args)
{
StartLogging();
}
static void StartLogging()
{
while (true)
{
//sleeping for while, this will reduce load on cpu
Thread.Sleep(10);
for (Int32 i = 0; i < 255; i++)
{
int keyState = GetAsyncKeyState(i);
if (keyState == 1 || keyState == -32767)
{
using (StreamWriter outputFile = new StreamWriter("C:\\Output.txt", true))
{
outputFile.WriteLine((Keys)i);
}
break;
}
}
}
}
}
}
This program captures every keyboard event, no matter in which program. It works fine.
Then i tried to put this into a Windows Service and it doesn't work.
The following code is my Service:
namespace Dienst
{
public class Service : ServiceBase
{
[DllImport("user32.dll")]
public static extern int GetAsyncKeyState(Int32 i);
static void StartLogging()
{
while (true)
{
//sleeping for while, this will reduce load on cpu
Thread.Sleep(10);
for (Int32 i = 0; i < 255; i++)
{
int keyState = GetAsyncKeyState(i);
if (keyState == 1 || keyState == -32767)
{
using (StreamWriter outputFile = new StreamWriter("C:\\TestNeu.txt", true))
{
outputFile.WriteLine((Keys)i);
}
break;
}
}
}
}
static void Main()
{
Service.Run(new Service());
}
protected override void OnStart(string[] args)
{
base.OnStart(args);
StartLogging();
}
protected override void OnContinue()
{
base.OnContinue();
}
protected override void OnStop()
{
base.OnStop();
}
}
[RunInstaller(true)]
public class Installation : Installer
{
private ServiceInstaller service;
private ServiceProcessInstaller process;
public Installation()
{
service = new ServiceInstaller();
process = new ServiceProcessInstaller();
service.ServiceName = "Service1";
service.DisplayName = "Service1";
service.Description = "WindowsService";
process.Account = ServiceAccount.LocalSystem;
Installers.Add(process);
Installers.Add(service);
}
}
}
The result from GetAsyncKeyState(i) is always 0.
Can anyone help me? I don't know, because this code as Service doesn't work.
And no, I don't want write a keylogger, only if someone think this.
Related
I developed an MPI test program where the master node distributes work to the worker nodes.
The worker node uses comm.Send() to request work and the master node checks with comm.ImmediateProbe if any of the worker nodes wants to request some work. If a request is available it is read with comm.Receive and the work is sent to the worker for processing.
When I run my test program with mpiexec.exe on a single host, either localhost or also a remote host everything works as expected, but when I run it on two hosts at the same time
the Send on the remote host blocks and the master nodes ImmediateProbe never receives the message sent from the worker on the remote host.
I run the program with mpiexec.exe -wdir \\DESKTOP-58QONBS\MPITest -hosts 2 DESKTOP-58QONBS 2 LAPTOP-L8F7AN5R 1 MPITest.exe
I'm new to MPI, so maybe I am doing something wrong I just could not figure out yet why the behaviour is like this when using two hosts at the same time.
The full code is below:
using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading;
namespace MPITest
{
public abstract class MPIMasterWorkerBase<TWork, TResult>
where TWork : class
where TResult : class
{
protected abstract void Initialize(bool isMaster);
protected abstract void Main();
protected abstract void ProcessResult(TResult result);
protected abstract TResult ProcessWork(TWork work);
protected abstract TWork GetWork();
private volatile bool terminate = false;
private Thread thread;
private MPI.Intracommunicator comm;
public void Run(string[] args)
{
MPI.Environment.Run(ref args, comm =>
{
this.comm = comm;
if (comm.Size < 2)
{
Console.WriteLine("At least 2 processes are required.");
return;
}
if (comm.Rank == 0)
{
Initialize(isMaster: true);
thread = new Thread(MasterThread);
thread.Start();
Main();
terminate = true;
thread.Join();
}
else
{
Initialize(isMaster: false);
thread = new Thread(WorkerThread);
thread.Start();
thread.Join();
}
});
}
private void MasterThread()
{
Console.WriteLine($"MasterStart {MPI.Environment.ProcessorName}");
var done = new bool[comm.Size];
done[0] = true;
while (!done.All(x => x == true))
{
for (int i = 1; i < comm.Size; i++)
{
if (comm.ImmediateProbe(i, 0) != null)
{
Console.WriteLine($"Receive: {i}");
comm.Receive<int>(i, 0);
var work = GetWork();
if (work != null)
{
comm.Send(1, i, 0);
comm.Send(work, i, 0);
}
else
{
if (terminate)
{
comm.Send(-1, i, 0);
done[i] = true;
}
else
{
comm.Send(0, i, 0);
}
}
}
if (comm.ImmediateProbe(i, 1) != null)
{
var result = comm.Receive<TResult>(i, 1);
ProcessResult(result);
}
}
Thread.Sleep(1000);
}
Console.WriteLine("MasterStop");
}
private void WorkerThread()
{
Console.WriteLine($"WorkerStart: {comm.Rank} {MPI.Environment.ProcessorName}");
while (!terminate)
{
Thread.Sleep(1000);
Console.WriteLine($"Send: {comm.Rank}");
comm.Send(0, 0, 0);
var flag = comm.Receive<int>(0, 0);
if (flag == -1)
break;
else if (flag == 0)
continue;
var work = comm.Receive<TWork>(0, 0);
var result = ProcessWork(work);
comm.Send(result, 0, 1);
}
Console.WriteLine($"WorkerStop: {comm.Rank}");
}
}
[Serializable]
public class WorkItem
{
public int Id { get; set; }
}
public class MPITest : MPIMasterWorkerBase<WorkItem, WorkItem>
{
private ConcurrentQueue<WorkItem> queue = new();
private int id;
protected override void Initialize(bool isMaster)
{
}
protected override void Main()
{
var startTime = DateTime.UtcNow;
while ((DateTime.UtcNow - startTime).TotalSeconds < 10)
{
for (int i = 0; i < 2; i++)
queue.Enqueue(new WorkItem { Id = id++ });
Thread.Sleep(1000);
}
}
protected override WorkItem GetWork()
{
if (queue.TryDequeue(out var result))
return result;
return null;
}
protected override WorkItem ProcessWork(WorkItem work)
{
Console.WriteLine($"Processing Work {work.Id}");
return work;
}
protected override void ProcessResult(WorkItem result)
{
Console.WriteLine($"Process Result {result.Id}");
}
}
class Program
{
static void Main(string[] args)
{
new MPITest().Run(args);
}
}
}
The comm.Send was blocking, but after some minutes of waiting the program started to work.
The issues were caused by the VirtualBox Host-Only Network Adapter that was also installed on the system. Disabling this adapter in the network settings resolved all the issues.
I have a step counter service. It works fine when the app is open. How do I make the service count the steps when the app is closed? When you close the application, the number of steps does not increase, this makes the application useless... I found information about "batching", but did not find a normal use case.
[Service(Exported = true, Enabled = true,
Label = "StepCounterService")]
public class StepCounterService : Service, ISensorEventListener
{
private SensorManager sManager;
private long currentStepsCount = 0;
private long overSteppers = 0;
private DateTime lastUpdateTime;
public event EventHandler<long> StepUpdated;
private long _steps = 0;
public long Steps
{
get
{
UpdateValue(_steps);
return _steps;
}
private set { _steps = value; }
}
public static StepCounterService Current { get; private set; }
public StepCounterService()
{
}
[return: GeneratedEnum]
public override StartCommandResult OnStartCommand(Intent intent, [GeneratedEnum] StartCommandFlags flags, int startId)
{
lastUpdateTime = AppPreferences.Get(nameof(lastUpdateTime), nameof(Class), new DateTime());
overSteppers = AppPreferences.Get(nameof(overSteppers), nameof(Class), 0L);
InitSensorService();
return StartCommandResult.Sticky;
}
public override void OnCreate()
{
base.OnCreate();
Current = this;
}
public void InitSensorService()
{
sManager = Android.App.Application.Context.GetSystemService(Context.SensorService) as SensorManager;
sManager.RegisterListener(this, sManager.GetDefaultSensor(SensorType.StepCounter), SensorDelay.Fastest);
}
public void OnAccuracyChanged(Sensor sensor, [GeneratedEnum] SensorStatus accuracy)
{
}
public void OnSensorChanged(SensorEvent e)
{
if (e.Values[0] == 0)
{
overSteppers = 0;
AppPreferences.Save(overSteppers, nameof(overSteppers), nameof(Class));
currentStepsCount = AppPreferences.Get(nameof(currentStepsCount), nameof(Class), 0L);
}
UpdateValue((long)e.Values[0]);
Steps = (long)e.Values[0] - overSteppers + currentStepsCount;
StepUpdated?.Invoke(this, Steps);
}
private void UpdateValue(long defaultValue)
{
if (DateTime.Now.Date > lastUpdateTime.Date)
{
lastUpdateTime = DateTime.Now;
overSteppers = defaultValue;
Steps = 0;
currentStepsCount = 0;
}
}
private void SaveData()
{
AppPreferences.Save(lastUpdateTime, nameof(lastUpdateTime), nameof(Class));
AppPreferences.Save(overSteppers, nameof(overSteppers), nameof(Class));
AppPreferences.Save(_steps, nameof(currentStepsCount), nameof(Class));
}
public void StopSensorService()
{
sManager.UnregisterListener(this);
sManager.Dispose();
SaveData();
}
public override void OnDestroy()
{
SaveData();
base.OnDestroy();
}
public override IBinder OnBind(Intent intent)
{
return null;
}
}
When I start the app, I start the service:
MyApp.Context.StartService(new Intent(MyApp.Context, typeof(StepCounterService)));
My problem might be a dumb one but after hours of searching, I have to ask you for help.
I have a WPF form LoginPage that features a Label ,(called AlertText) that displays messages to the user and I need to change his content from another class.
To change the content I use AlertText.Content = "content" and it works perfectly.
But when I'm on another class and I want to change it that doesn't do anything.
Both class are under the same namespace.
I've tried this :
LoginPage lg = new LoginPage();
lg.AlertText.Content = "content";
The object is created but the second line isn't executed.
I've tried to create a public function SetAlertText() in my LoginPage class but that doesn't worked either.
I made it static and called it by LoginPage.SetAlertText() but same problem persists.
I've added this in my LoginPage :
public static LoginPage instance;
public LoginPage()
{
instance = this;
}
And called it by
LoginPage.instance.SetAlertText();
and
LoginPage.instance.AlertText.Content = "content";
but neither worked.
I also tried :
public LoginPage()
{
instance = new LoginPage();
}
What can I do ?
Edit :
Here's the full code of both classes :
namespace TMClientWPF
{
/// <summary>
/// Logique d'interaction pour LoginPage.xaml
/// </summary>
public partial class LoginPage : Page
{
ClientTCP client;
bool isConnected = false;
public RegisterPage registerPage;
public static LoginPage instance;
public LoginPage()
{
instance = this;
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
AlertText.Content = "";
try
{
if (isConnected == false)
{
client = new ClientTCP();
client.Connect();
isConnected = true;
}
client.SEND_LOGINS(UsernameText.Text, PasswordText.Password.ToString());
}
catch (NullReferenceException)
{
AlertText.Visibility = Visibility.Visible;
AlertText.Content = "Failed to connect to server, please try again later.";
}
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
registerPage = new RegisterPage();
this.NavigationService.Navigate(registerPage);
}
private void Button_Click_2(object sender, RoutedEventArgs e)
{
Application.Current.Shutdown();
}
public void SetAlertText(string text)
{
AlertText.Visibility = Visibility.Visible;
AlertText.Content = "Welcome Home";
}
}
}
///////////////////////////////
namespace TMClientWPF
{
public class ClientHandlePackets
{
public static ByteBuffer playerBuffer;
private delegate void Packet_(byte[] data);
private static Dictionary<long, Packet_> packets;
private static long pLength;
public static void HandleData(byte[] data)
{
InitializePackets();
byte[] Buffer;
Buffer = (byte[])data.Clone();
if (playerBuffer == null)
{
playerBuffer = new ByteBuffer();
}
playerBuffer.WriteBytes(Buffer);
if (playerBuffer.Count() == 0)
{
playerBuffer.Clear();
return;
}
if (playerBuffer.Length() >= 8)
{
pLength = playerBuffer.ReadLong(false);
if (pLength <= 0)
{
playerBuffer.Clear();
return;
}
}
while (pLength > 0 & pLength <= playerBuffer.Length() - 8)
{
if (pLength <= playerBuffer.Length() - 8)
{
playerBuffer.ReadLong(); //read out the packet identifier
data = playerBuffer.ReadBytes((int)pLength); //get the full package length
HandleDataPackets(data);
}
pLength = 0;
if (playerBuffer.Length() >= 8)
{
pLength = playerBuffer.ReadLong(false);
if (pLength < 0)
{
playerBuffer.Clear();
return;
}
}
}
}
private static void HandleDataPackets(byte[] data)
{
long packetIdentifier;
ByteBuffer buffer;
Packet_ packet;
buffer = new ByteBuffer();
buffer.WriteBytes(data);
packetIdentifier = buffer.ReadLong();
buffer.Dispose();
if (packets.TryGetValue(packetIdentifier, out packet))
{
packet.Invoke(data);
}
}
private static void InitializePackets()
{
packets = new Dictionary<long, Packet_>();
packets.Add((long)ServerPackets.S_INFORMATION, PACKET_INFORMATION);
packets.Add((long)ServerPackets.S_EXECUTEMETHODONCLIENT, PACKET_EXECUTEMETHOD);
packets.Add((long)ServerPackets.S_LOGCALLBACK, Packet_LogCallback);
}
#region packets
private static void PACKET_INFORMATION(byte[] data)
{
ByteBuffer buffer = new ByteBuffer();
buffer.WriteBytes(data);
long packetIndentifier = buffer.ReadLong();
string msg1 = buffer.ReadString();
string msg2 = buffer.ReadString();
int level = buffer.ReadInteger();
buffer.Dispose();
ClientTCP.instance.SEND_THANKYOU();
}
private static void PACKET_EXECUTEMETHOD(byte[] data)
{
ClientTCP client = new ClientTCP();
}
private static void Packet_LogCallback(byte[] data)
{
ByteBuffer buffer = new ByteBuffer();
buffer.WriteBytes(data);
buffer.ReadLong();
string message = buffer.ReadString();
string username = buffer.ReadString();
buffer.Dispose();
if(message == "true")
{
// LoginPage.SetAlertText("Welcome Home.");
}
else
{
LoginPage lg = new LoginPage();
LoginPage.instance.SetAlertText("Invalid logins.");
}
}
#endregion
}
}
I have a static class A which has a public static ConcurrentQueue.
This class has a method which calls a method of another static class B.
In this method of static class B, a worker thread is started which polls for items in the static ConcurrentQueue of class A. If found, it dequeues the item and processes it.
The same method in class B also starts another thread which checks if the queue of class A is being constantly filled. If the filling occasionally is somehow stuck, a call to a static method in class A is made which resets and restarts the process.
And here comes the problem: When I restart the filling, items are inserted again into the static queue of static class A. But my thread in static class B which checks for items in the queue does not find any items anymore.
So my idea is that in class B I somehow lost the reference to the original static queue of class A. I think I oversee here some principles of static classes, but can not figure out what exactly.
EDIT: Here are some more details.
Main:
public static void Main(string[] args)
{
B.Initialize(8);
A.StartDataStream();
Console.ReadKey();
}
Class A:
class A
{
private static ACOMObject MyCOMObjekt;
public static ConcurrentQueue<PriceItem> Prices = new ConcurrentQueue<PriceItem>();
public static void StartDataStream()
{
DataStream myDataStream = GetDataStream();
FillStream(myDataStream);
B.StartHeartbeatCheck();
Console.WriteLine("Press Key to Exit Stream Call.");
Console.ReadKey();
GC.KeepAlive(myDataStream);
GC.KeepAlive(MyCOMObjekt);
}
private static DataStream GetDataStream()
{
if (MyCOMObjekt== null)
{
MyCOMObjekt= new ACOMObject ();
}
return (DataStream) MyCOMObjekt.DataStream;
}
private static void FillStream(DataStream myDataStream)
{
foreach (var symbol in Symbols.SymbolList)
{
myDataStream.Add(symbolNr, 1);
}
myDataStream.Bid += new _IDataStreamEvents_BidEventHandler(myDataStream_Bid);
myDataStream.Ask += new _IDataStreamEvents_AskEventHandler(myDataStream_Ask);
}
private static void myDataStream_Bid(int SymbolNr, float Price, DateTime Time)
{
PriceItem p;
p.SymbolNr = SymbolNr;
p.Price = Price;
p.Time = Time;
p.IsBid = true;
Prices.Enqueue(p);
}
private static void myDataStream_Ask(int SymbolNr, float Price, DateTime Time)
{
PriceItem p;
p.SymbolNr = SymbolNr;
p.Price = Kurs;
p.Time = Zeit;
p.IsBid = false;
Prices.Enqueue(p);
}
public static void RestartMyCOMProcess()
{
try
{
Process proc = Process.GetProcessesByName("MyCOMProcess")[0];
proc.Kill();
}
catch (Exception)
{
//No Process = fine
}
MyCOMObjekt = null;
DataStream myDataStream = GetDataStream();
myDataStream.Bid -= new _IDataStreamEvents_BidEventHandler(myDataStream_Bid); //probably not necessary...
myDataStream.Ask -= new _IDataStreamEvents_AskEventHandler(myDataStream_Ask); //probably not necessary...
FillStream(myDataStream);
}
}
Class B:
class B
{
private static int countPrices; //Incremented every time a price is taken out of Price Queue
public static void Initialize(int numberOfWorkerThreads)
{
StartWorkers(numberOfWorkerThreads);
}
public static void StartWorkers(int number)
{
for (int j = 0; j < number; j++)
{
Thread t = new Thread(ScanForPrices);
t.Name = "ScanForPrices" + j;
t.Start();
}
}
private static void ScanForPrices()
{
try
{
while (true)
{
PriceItem p;
if (A.Prices.TryDequeue(out p))
{
if (p.IsBid)
{
AnalyzeBidPrice(p);
}
else
{
HandleAskPrice(p);
}
Interlocked.Increment(ref countPrices)
}
else
{
Thread.Sleep(1);
}
}
}
catch (ThreadAbortException)
{
Console.WriteLine("Price Scan Thread aborted.");
}
}
public static void StartHeartbeatCheck()
{
Thread t = new Thread(CheckHeartBeat);
t.Name = "CheckHeartBeat";
t.Start();
}
private static void CheckHeartBeat()
{
TimeSpan start = new TimeSpan(09, 0, 0); //09 o'clock
TimeSpan end = new TimeSpan(20, 0, 0); //20 o'clock
TimeSpan stopTime = new TimeSpan(20, 5, 0); //20 o'clock and 5 minutes
int countSuccessiveBlockings = 0;
try
{
while (true)
{
Thread.Sleep(5000);
TimeSpan now = DateTime.Now.TimeOfDay;
if ((now > start) && (now < end))
{
int countOld = countPrices;
Thread.Sleep(1000);
if (countOld == countPrices)
{
Console.WriteLine(DateTime.Now + ": Price Stream blocked!");
countSuccessiveBlockings++;
}
else
{
countSuccessiveBlockings = 0;
}
if (countSuccessiveBlockings > 2)
{
A.RestartMyCOMProcess();
countSuccessiveBlockings = 0;
}
}
}
}
catch (ThreadAbortException)
{
Console.WriteLine("Heartbeat Thread aborted.");
}
}
}
By going through some samples, I referred to Polling Service - C# for my polling.
This is my code.
public partial class Service1 : ServiceBase
{
private readonly PollingService _pollingService = new PollingService();
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
_pollingService.StartPolling();
}
protected override void OnStop()
{
_pollingService.StopPolling();
}
}
public class PollingService
{
private Thread _workerThread;
private AutoResetEvent _finished;
private const int _timeout = 60 * 1000;
string command = "5120000000000000000000000000000";
public void StartPolling()
{
_workerThread = new Thread(Poll);
_finished = new AutoResetEvent(false);
_workerThread.Start();
}
private void Poll()
{
while (!_finished.WaitOne(_timeout))
{
//do the task
using (TcpClient newclient = new TcpClient())
{
IAsyncResult ar = newclient.BeginConnect("192.168.0.151", 4000, null, null);
if (!ar.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(2), false))
{
return;
}
NetworkStream ns = newclient.GetStream();
byte[] outbytes = HexStringToByteArray(command);
ns.Write(outbytes, 0, outbytes.Length);
}
}
}
public void StopPolling()
{
_finished.Set();
_workerThread.Join();
}
public static byte[] HexStringToByteArray(string hexString)
{
if (hexString.Length % 2 > 0)
{
throw new Exception("Invalid command.");
}
byte[] result = new byte[hexString.Length / 2];
try
{
for (int i = 0; i < result.Length; i++)
{
result[i] = Convert.ToByte(hexString.Substring(2 * i, 2), 16);
}
}
catch (Exception)
{
throw;
}
return result;
}
}
I've managed to install. However, when I'm trying to start the service, I'm getting Windows could not start the service on Local Computer. Error 5: Access is denied. I've tried using the solutions given here, Error 5 : Access Denied when starting windows service, however, it is not working.
I found the solution by changing the service properties from This Account to Local System Account with some updated codes.
using (TcpClient newclient = new TcpClient("192.168.0.151", 4000))
{
NetworkStream ns = newclient.GetStream();
byte[] outbytes = Encoding.ASCII.GetBytes(command);
ns.Write(outbytes, 0, outbytes.Length);
ns.Close();
newclient.Close();
}