some delay processing message in MessageInterceptor - c#

Sorry, my english is not quite well.
I'm new in programming world and tried to create an application using messageinterceptor on windows mobile 6.5.3.
but when i send text message to my phone, there was delay about 30 seconds or more before the message is processed, either text message which contain keywords or not.
I read several sources before deciding to try to make my own application, but these source are using Windows Form (GUI), instead of using Windows Form, i make it run in console mode.
here is the code:
using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using Microsoft.WindowsMobile.PocketOutlook.MessageInterception;
using Microsoft.WindowsMobile.PocketOutlook;
using Microsoft.WindowsMobile;
using System.IO;
namespace PenerimaPesan
{
class Program
{
static void Main(string[] args)
{
string applicationID;
applicationID = "tracker";
MessageInterceptor pesanmasuk = null;
pesanmasuk = new MessageInterceptor();
pesanmasuk.EnableApplicationLauncher(applicationID);
if (MessageInterceptor.IsApplicationLauncherEnabled(applicationID))
{
string keyword;
StreamReader key = new StreamReader(#"\Windows\conf.txt");
string data = key.ReadToEnd();
string[] isi = data.Split(new char[] { '\n' });
keyword = isi[1];
keyword = keyword.Replace(" ", "");
pesanmasuk = new MessageInterceptor(InterceptionAction.NotifyAndDelete, false);
pesanmasuk.MessageCondition = new MessageCondition(MessageProperty.Body, MessagePropertyComparisonType.StartsWith, ""+keyword);
pesanmasuk.MessageReceived += new MessageInterceptorEventHandler(pesanmasuk_MessageReceived);
}
}
static void pesanmasuk_MessageReceived(object sender, MessageInterceptorEventArgs e)
{
SmsMessage pesan = e.Message as SmsMessage;
if (pesan != null)
{
string perintah;
string[] command = pesan.Body.Split(new char[] { '.' });
perintah = command[1];
if (perintah == "helo")
/*do some Stuff*/
}
}
}

I've never used MessageInterceptor, so I decided I'd try to implement this code in my application. To test it, I renamed Main to Main2, then cleaned it up to match "my style".
Anyway, I ran into errors when I tried wrapping the MessageInterceptor in a using block - not because MessageInterceptor does not implement IDispose, but because you have declared a new instance of it.
Take a look at this snippet of your code:
MessageInterceptor pesanmasuk = new MessageInterceptor();
pesanmasuk.EnableApplicationLauncher(applicationID);
if (MessageInterceptor.IsApplicationLauncherEnabled(applicationID)) {
string keyword;
StreamReader key = new StreamReader(#"\Windows\conf.txt");
string data = key.ReadToEnd();
string[] isi = data.Split(new char[] { '\n' });
keyword = isi[1];
keyword = keyword.Replace(" ", "");
pesanmasuk = new MessageInterceptor(InterceptionAction.NotifyAndDelete, false);
OK, right there. Stop. You created a new instance of your pesanmasuk variable, set Properties, did some checking, worked with data from a text file, then...
Created a new instance of your pesanmasuk variable.
All of your previous settings are now whipped out.
I'm guessing your first instance is running and perhaps the second instance has to wait for the first instance to time out before it can be created.
At this point, I'm interested to learn just how to use this MessageInterceptor on MSDN, looked into the example there, and came up with this [untested] version:
static void Main2(string[] args) {
const string stackOverflowUrl = #"http://stackoverflow.com/questions/8520488/some-delay-processing-message-in-messageinterceptor";
string empty = String.Empty;
StreamReader key = new StreamReader(#"\Windows\conf.txt");
string data = key.ReadToEnd();
string[] lines = data.Split(new char[] { '\n' });
string keyword = lines[1].Replace(" ", empty);
string applicationID = "trackingApplication";
using (MessageInterceptor smsInterceptor = new MessageInterceptor(applicationID, false)) {
smsInterceptor.InterceptionAction = InterceptionAction.NotifyAndDelete;
smsInterceptor.MessageCondition = new MessageCondition(MessageProperty.Body, MessagePropertyComparisonType.StartsWith, empty + keyword);
smsInterceptor.MessageReceived += new MessageInterceptorEventHandler(Intercept_MessageReceived);
smsInterceptor.EnableApplicationLauncher(applicationID);
if (MessageInterceptor.IsApplicationLauncherEnabled(applicationID)) {
// Here, you'd need to launch your Form1 or enable some timer,
// otherwise the code will return immediately and the MessageInterceptor
// instance will be disposed of.
}
smsInterceptor.MessageReceived -= MessageInterceptorEventHandler;
}
}
static void Intercept_MessageReceived(object sender, MessageInterceptorEventArgs e) {
SmsMessage newMessage = e.Message as SmsMessage;
if (newMessage != null) {
Console.WriteLine("From: {0}", newMessage.From.Address);
Console.WriteLine("Body: {0}", newMessage.Body);
string[] command = newMessage.Body.Split(new char[] { '.' });
string line = command[1];
if (line == "helo") {
/*do some Stuff*/
}
}
}
I hope this helps, but keep in mind that I've never actually used this control and my code has not been tested.

Related

Calling a static method in C#

I implemented a plugin (using pGina software) to allow the user to authenticate the username/password in their computer by scanning a NFC tag.
I used a program I found called CSharp PC/SC Wrapper for .NET to read the tag ID. Every time a tag is scanned the program writes the ID to a text file and checks that the ID is the the same as the one set on the string.
if (userInfo.Username.Contains("hello") && userInfo.Password.Contains("pGina")
&& text.Equals("UID = 0x04 82 EC BA 7A 48 80"))
The plugin is set to find the .exe file that reads the ID (PC/SC Wrapper). Everything works fine. However, I don't one the reader program to be in a different file. I want everything to be in the plugin file.
I created a method and copied the code from the wrapper that performs the reading of the tag ID (runme()), but I'm not sure how to replace the line that calls the .exe file with the method I created
ProcessStartInfo ps = new ProcessStartInfo(#"C:\Users\Student\Desktop\CSharpPCSC\CSharpPCSC\ExamplePCSCReader\bin\Release\ExamplePCSCReader.exe");
Any suggestions? I'm new to C#
Below is my code for the plugin with the method containing the code that reads the ID
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using pGina.Shared.Types;
using log4net;
using System.IO;
using System.Diagnostics;
using GS.PCSC;
using GS.Apdu;
using GS.SCard;
using GS.Util.Hex;
using System.Threading;
namespace HelloPlugin
{
public class PluginImpl : pGina.Shared.Interfaces.IPluginAuthentication
{
private ILog m_logger;
private static readonly Guid m_uuid = new Guid("CED8D126-9121-4CD2-86DE-3D84E4A2625E");
public PluginImpl()
{
m_logger = LogManager.GetLogger("pGina.Plugin.HelloPlugin");
}
public string Name
{
get { return "Hello"; }
}
public string Description
{
get { return "Authenticates users with 'hello' in the username and 'pGina' in the password"; }
}
public Guid Uuid
{
get { return m_uuid; }
}
public string Version
{
get
{
return System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
}
}
public void Starting()
{
}
public void Stopping() { }
public BooleanResult AuthenticateUser(SessionProperties properties)
{
UserInformation userInfo = properties.GetTrackedSingle<UserInformation>();
ProcessStartInfo ps = new ProcessStartInfo(#"C:\Users\Student\Desktop\CSharpPCSC\CSharpPCSC\ExamplePCSCReader\bin\Release\ExamplePCSCReader.exe");
Process.Start(ps);
Thread.Sleep(2000);
string text = File.ReadAllText(#"C:\Users\Student\Desktop\text.txt", Encoding.UTF8);
text = text.Trim();
if (userInfo.Username.Contains("hello") && userInfo.Password.Contains("pGina") && text.Equals("UID = 0x04 82 EC BA 7A 48 80"))
{
// Successful authentication
m_logger.InfoFormat("Successfully authenticated {0}", userInfo.Username);
return new BooleanResult() { Success = true };
}
// Authentication failure
m_logger.ErrorFormat("Authentication failed for {0}", userInfo.Username);
return new BooleanResult() { Success = false, Message = "Incorrect username or password." };
}
static void runme()
{
ConsoleTraceListener consoleTraceListener = new ConsoleTraceListener();
Trace.Listeners.Add(consoleTraceListener);
PCSCReader reader = new PCSCReader();
string cardid = "";
try
{
reader.Connect();
reader.ActivateCard();
RespApdu respApdu = reader.Exchange("FF CA 00 00 00"); // Get NFC Card UID ...
if (respApdu.SW1SW2 == 0x9000)
{
Console.WriteLine("UID = 0x" + HexFormatting.ToHexString(respApdu.Data, true));
cardid = "UID = 0x" + HexFormatting.ToHexString(respApdu.Data, true);
cardid = cardid.Trim();
}
}
catch (WinSCardException ex)
{
Console.WriteLine(ex.WinSCardFunctionName + " Error 0x" +
ex.Status.ToString("X08") + ": " + ex.Message);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
string path = #"C:\Users\Student\Desktop\text.txt";
string text2write = cardid;
System.IO.StreamWriter writer = new System.IO.StreamWriter(path);
writer.Write(text2write);
writer.Close();
reader.Disconnect();
Environment.Exit(0);
Console.WriteLine("Please press any key...");
Console.ReadLine();
}
}
}
}
You've created a class called PluginImpl and in that class declared the method runme. To call that method from anywhere, you need to write PluginImpl.runme().
Since you've put your class in the namespace HelloPlugin - if the calling *.cs file is in a different namespace, you'll need a using HelloPlugin directive at the top.
That's all!
It's possible I have misunderstood your question, if so please re-word your question and send me a comment.
If you want to replace the line
ProcessStartInfo ps = new ProcessStartInfo(
#"C:\Users\Student\Desktop\CSharpPCSC\CSharpPCSC\"
+"ExamplePCSCReader\bin\Release\ExamplePCSCReader.exe");
with a method call instead, you want something like this
ProcessStartInfo ps = runme();
Since you are calling your static method from within the class, you don't need a PluginImpl. prefix.
Okay, so now it will complain that runme doesn't return ProcessStartInfo. You're going to need to change runme so that it does. Any subclass of ProcessStartInfo will do.
static ProcessStartInfo runme()
{
// ... Some code
ProcessStartInfo toReturn = new ProcessStartInfo( //...
);
// ... More code
return toReturn;
}

Keylogger API and converting to a string

I'm attempting to write a simple keylogger that will check typed words against a blacklist and fire a screenshot when a word is triggered. This is because we have a new PREVENT agenda that we have to use in UK schools to capture any possible extremist views.
I've been looking at the Keylogger API from https://github.com/fabriciorissetto/KeystrokeAPI
I'm using the following code as a test but i'm trying to add the characters to a string so i can then fire a comparison with a word list when the user presses the spacebar. The trouble i'm having is that i cannot convert character into a string. Is it possible do this so i can append it to another string a whilst waiting for a spacebar key?
class Program
{
static void Main(string[] args)
{
using (var api = new KeystrokeAPI())
{
api.CreateKeyboardHook((character) => { Console.Write(character); });
Application.Run();
}
}
}
This is what i have so far, the error i get is on the if statement converting character to a string.
static void Main(string[] args)
{
string line = "";
using (var api = new KeystrokeAPI())
{
api.CreateKeyboardHook((character) => {
line += character.ToString();
if (character.ToString() = "space")
{
Console.Write("Spacebar Hit");
}
Console.Write(character.KeyCode);
});
Application.Run();
}
}
Edit.
I rewrote this.
Captures both spaces and enter commands
static void Main(string[] args)
{
string line = string.Empty;
using (var api = new KeystrokeAPI())
{
api.CreateKeyboardHook((character) => {
if (character.KeyCode.ToString() == "Space" || character.KeyCode.ToString() == "Return")
{
if(BannedWordsCheck(line))
{
Console.WriteLine("Banned Word Typed: " + line);
}
line = string.Empty;
}
else
{
line += character.KeyCode.ToString();
}
});
Application.Run();
}
}
static bool BannedWordsCheck(string word)
{
if(word.ToLower().Contains("terror"))
{
return true;
}
else
{
return false;
}
}
The error you are receiving in your code is due to the following line
if (character.ToString() = "space")
You are attempting to assign the string literal "space" to character.ToString(), I also have this error in my comment which I can't edit anymore.
Here's a snippet that will check the key code against an enum instead of a string, it will then call the HandleComparison method if Space was pressed, and then clear out the StringBuilder
The only issue I found here is that pressing Shift will prefix the string with <shift>, so some additional logic will have to be applied for action keys, but this is a base to get you started with a working code sample.
I hope this helps.
class Program
{
private static StringBuilder builder;
static void Main(string[] args)
{
using (var api = new KeystrokeAPI())
{
builder = new StringBuilder();
api.CreateKeyboardHook(HandleKeyPress);
Application.Run();
}
}
private static void HandleKeyPress(KeyPressed obj)
{
// To be more reliable, lets use the KeyCode enum instead
if (obj.KeyCode == KeyCode.Space)
{
// Spacebar was pressed, let's check the word and flush the StringBuilder
HandleComparison(builder.ToString());
builder.Clear();
return;
}
// Space wasn't pressed, let's add the word to the StringBuilder
builder.Append(obj);
}
// Handle comparison logic here, I.E check word if exists on blacklist
private static void HandleComparison(string compareString)
{
Console.WriteLine(compareString);
}
}
Could you use the StringBuilder as a buffer?
something like this
var buffer = new StringBuilder();
using (var api = new KeystrokeAPI())
{
api.CreateKeyboardHook((character) => {
if (character.ToString() == " ")
{
//check the word
CallSomeMethodToCheckWord(buffer.ToString());
//reset the buffer
buffer = new StringBuilder();
}
else
{
//ToString returns special characters in it, so you could append here and parse later, or parse here.
buffer.Append(character.ToString());
}
});
Application.Run();
}

C# threading parallel issue

Help is very welcome and extremely appreciated, thank you. What this program is, is a ProxyChecker, because i've bought a bunch and will continue to do so of proxies with different user/passes etc, however some have expired. I added a break point and what it's doing is actually skipping the ProxyClient code and going straight to for each var item in 1, if item accepts connection etc, it then just returns false and finishes.
private static void CheckProxy(object state)
{
var u = user[0];
var p = pass[0];
var l = new List<MyIP>();
Parallel.ForEach(l.ToArray(), (ip_item) =>
{
try
{
string ip = ip_item.IP;
using (var client = new ProxyClient(ip, u, p))
{
Console.WriteLine(ip, user, pass);
client.Connect();
ip_item.AcceptsConnection = client.IsConnected;
}
}
catch
{
l.Remove(ip_item);
}
});
foreach (var item in l)
{
if (item.AcceptsConnection == true)
{
WriteToFile(user[0], pass[0]);
}
Console.WriteLine(item.IP + " is " + (item.AcceptsConnection) + " accepts connections" + " doesn not accept connections");
}
}
Load ips function:#
private static void loadips()
{
using (TextReader tr = new StreamReader("ips.txt"))
{
var l = new List<MyIP>();
string line = null;
while ((line = tr.ReadLine()) != null)
{
l.Add(new MyIP { IP = line });
}
}
}
I have added this in response to the answer. I believe this is a variable issue as the variable is locally declared not publicly any ideas how to fix? i'm unable to find a way to get this working seems like i'm being dumb. thanks.
The problem is in these two lines:
var l = new List<MyIP>();
Parallel.ForEach(l.ToArray(), (ip_item) =>
You just created l as a new List with no items in it. Calling ToArray() will give you an empty array. When Parallel.ForEach sees an empty array, it just gets skipped since there's nothing to iterate over.

C# threading parallel

Help is very welcome and extremely appreciated, thank you. What this program is, is a ProxyChecker, because i've bought a bunch and will continue to do so of proxies with different user/passes etc, however some have expired. I added a break point and what it's doing is actually skipping the ProxyClient code and going straight to for each var item in 1, if item accepts connection etc, it then just returns false and finishes.
private static void CheckProxy(object state)
{
var u = user[0];
var p = pass[0];
var l = new List<MyIP>();
Parallel.ForEach(l.ToArray(), (ip_item) =>
{
try
{
string ip = ip_item.IP;
using (var client = new ProxyClient(ip, u, p))
{
Console.WriteLine(ip, user, pass);
client.Connect();
ip_item.AcceptsConnection = client.IsConnected;
}
}
catch
{
l.Remove(ip_item);
}
});
foreach (var item in l)
{
if (item.AcceptsConnection == true)
{
WriteToFile(user[0], pass[0]);
}
Console.WriteLine(item.IP + " is " + (item.AcceptsConnection) + " accepts connections" + " doesn not accept connections");
}
}
Load ips function:#
private static void loadips()
{
using (TextReader tr = new StreamReader("ips.txt"))
{
var l = new List<MyIP>();
string line = null;
while ((line = tr.ReadLine()) != null)
{
l.Add(new MyIP { IP = line });
}
}
}
I have added this in response to the answer. I believe this is a variable issue as the variable is locally declared not publicly any ideas how to fix? i'm unable to find a way to get this working seems like i'm being dumb. thanks.
Your code "skips" the Parallel.ForEach because the local variable l is an empty list (you just created it with new List<MyIP>().
Your loadips() method only fills a list referenced only by (another) local variable l, which is out of scope when the using block is left.
There are several ways to solve that. If both methods are in the same class, you could declare a member variable in that class of type List<MyIP> and fill that list in your loadips().
My suggestion would be to change loadips() so that it returns the list of read ip addresses and call this from CheckProxy():
private static List<MyIP> loadips() // changed return type to List<MyIP>
{
using (TextReader tr = new StreamReader("ips.txt"))
{
var l = new List<MyIP>();
string line = null;
while ((line = tr.ReadLine()) != null)
{
l.Add(new MyIP { IP = line });
}
return l; // return the list!
}
}
and the CheckProxy:
private static void CheckProxy(object state)
{
var u = user[0];
var p = pass[0];
var l = loadips(); // load IPs here
Parallel.ForEach(l.ToArray(), (ip_item) =>
{
...

Why won't MSMQ send a space character?

I'm exploring MSMQ services, and I wrote a simple console client-server application that sends each of the client's keystrokes to the server. Whenever hit a control character (DEL, ESC, INS, etc) the server understandably throws an error. However, whenever I type a space character, the server receives the packet but doesn't throw an error and doesn't display the space.
Server:
namespace QIM
{
class Program
{
const string QUEUE = #".\Private$\qim";
static MessageQueue _mq;
static readonly object _mqLock = new object();
static XmlSerializer xs;
static void Main(string[] args)
{
lock (_mqLock)
{
if (!MessageQueue.Exists(QUEUE))
_mq = MessageQueue.Create(QUEUE);
else
_mq = new MessageQueue(QUEUE);
}
xs = new XmlSerializer(typeof(string));
_mq.BeginReceive(new TimeSpan(0, 1, 0), new object(), OnReceive);
while (Console.ReadKey().Key != ConsoleKey.Escape) { }
}
static void OnReceive(IAsyncResult result)
{
Message msg;
lock (_mqLock)
{
try
{
msg = _mq.EndReceive(result);
Console.Write(".");
Console.Write(xs.Deserialize(msg.BodyStream));
}
catch (Exception ex)
{
Console.Write(ex);
}
}
_mq.BeginReceive(new TimeSpan(0, 1, 0), new object(), OnReceive);
}
}
}
Client:
namespace QIM_Client
{
class Program
{
const string QUEUE = #".\Private$\qim";
static MessageQueue _mq;
static void Main(string[] args)
{
if (!MessageQueue.Exists(QUEUE))
_mq = MessageQueue.Create(QUEUE);
else
_mq = new MessageQueue(QUEUE);
ConsoleKeyInfo key = new ConsoleKeyInfo();
while (key.Key != ConsoleKey.Escape)
{
key = Console.ReadKey();
_mq.Send(key.KeyChar.ToString());
}
}
}
}
Client Input:
Testing, Testing...
Server Output:
.T.e.s.t.i.n.g.,..T.e.s.t.i.n.g......
You'll notice that the space character sends a message, but the character isn't displayed.
Your issue is not with MSMQ, it's with the XmlSerializer class. See:
var key = Console.ReadKey();
XmlSerializer s = new XmlSerializer(typeof(string));
using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
{
s.Serialize(ms, key.KeyChar.ToString());
ms.Position = 0;
var foo = (string)s.Deserialize(ms);
}
If you type a space in the console, you'll see that key.KeyChar.ToString() yields " ", but foo is equal to "". Because of the default implementation of XmlReader, the XmlSerializer class considers a string of only whitespace to be empty; if the string contains any other characters, both leading and trailing spaces are preserved. The whitespace does get serialized, but deserializing it turns it into an empty string.
Use this instead:
Console.Write(
s.Deserialize(System.Xml.XmlReader.Create(msg.BodyStream,
new System.Xml.XmlReaderSettings()
{
IgnoreWhitespace = false
})));
The answer from #Adam is right. The easiest solution is to use BinaryMessageFormatter (it will result in slightly smaller messages anyway).
After you initialize the message queue objects in both the client and the server, set the formatter explicitly:
_mq.Formatter = new BinaryMessageFormatter();
Then in the server, don't try to mess with BodyStream directly. Instead just use Body (which will have already been deserialized by the formatter):
Console.Write(".");
Console.Write(msg.Body);

Categories