|
Oddly is that when I send the 9 character length of a string (i.e. 123A45678), my serial port dataReceived event recieves the message but it reads as:
123A4567
8
Unsure on how to get the whole string as was sent by the other com port?
here's my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using RS232;
namespace RemoteCFG
{
public class RemoteConfiguration
{
SerialPort serialPort;
RS232Comm rs232Comm = new RS232Comm();
Object lockingObj = new object();
public RemoteConfiguration()
{
}
public string strMessage { get; set; }
public string cfgNumber { get; set; }
public string vloValue { get; set; }
public string atcValue { get; set; }
public List<string> EnumerateComPorts()
{
return rs232Comm.GetAvailableComPorts();
}
public int OpenPort(string comPort)
{
serialPort = rs232Comm.OpenPort(comPort);
serialPort.DataReceived +=new SerialDataReceivedEventHandler(serialPort_DataReceived);
if (serialPort != null)
return 1;
else
return 0;
}
public int ClosePort()
{
try
{
serialPort.Close();
return 1;
}
catch (Exception ex)
{
return 0;
}
}
void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string inData = sp.ReadExisting().Trim();
strMessage = inData;
switch (inData)
{
case "PLC": SendMsg("OK"); break;
case "CFG": ValidateCFG(); break;
case "OFF": serialPort.Close(); break;
case "VLO": GetVLO(); break;
case "ATC": GetATC(); break;
default: System.Diagnostics.Debug.WriteLine(strMessage); break;
}
}
private void GetATC()
{
if (atcValue != null && atcValue != string.Empty)
{
int value = 0;
if (int.TryParse(atcValue, out value))
{
if (value >= 0 || value <= 99)
{
SendMsg(atcValue);
}
}
}
}
private void GetVLO()
{
if (vloValue != null && vloValue != string.Empty)
{
int value = 0;
if (int.TryParse(vloValue, out value))
{
if (value >= 60 || value <= 120)
{
SendMsg(vloValue);
}
}
}
}
private void ValidateCFG()
{
if (cfgNumber != null && cfgNumber != null && cfgNumber != string.Empty)
{
if (cfgNumber.Length == 9)
{
try
{
int Num = 0;
if (int.TryParse(cfgNumber.Substring(0, 3), out Num))
{
int errorCounter = System.Text.RegularExpressions.Regex.Matches(cfgNumber.Substring(3, 1), @"[a-zA-Z]").Count;
if (errorCounter == 1)
{
if (int.TryParse(cfgNumber.Substring(4), out Num))
SendMsg(cfgNumber);
}
}
}
catch
{
}
}
}
}
public int GetCFG(ref string configNumber)
{
int status = 0;
try
{
SendMsg("CFG");
configNumber = strMessage;
}
catch
{
}
return status;
}
int GetDynData(string[] dynamicData)
{
int status = 0;
return status;
}
public int SendMsg(string msg)
{
int status = 0;
serialPort.Write(msg + "\r");
return status;
}
}
}
The serial port is initilized as:
serialPort = new SerialPort(comPortName, 9600, Parity.Even, 7, StopBits.One);
serialPort.Handshake = Handshake.XOnXOff;
|
|
|
|
|
You serial port is set at 9600 baud - this is not a fast speed, certainly not in modern terms.
9600 baud means 9,600 bits per second, so with 1 start bit, one stop bit, even parity and 7 bits per character that's a maximum data transfer rate of 960 characters per second.
You SerialPort.DataRecieved event does not fire when the final character is received, it fires when the first character is received. And the second, and the third....
So when you read all the data from the serial port buffer, you will get a "random" number of characters, which may - or may not be - the whole message you are looking for.
Instead of your existing code, set up a BackgroundWorker thread which processes input data from the serial port, scans it to find whole messages, and then signals up to the main thread that a whole message is ready. If it gets a "partial message" is stores it, and adds the next data on the end before scanning it again.
This message is manufactured from fully recyclable noughts and ones. To recycle this message, please separate into two tidy piles, and take them to your nearest local recycling centre.
Please note that in some areas noughts are always replaced with zeros by law, and many facilities cannot recycle zeroes - in this case, please bury them in your back garden and water frequently.
|
|
|
|
|
You don't need a background worker and the baud rate has nothing to do with your ability or inability to receive a message.
The SerialPort class already operates on its own thread. The truth is the physical serial port on your PC is implemented with a USART and has no buffer of its own. It can hold a single character. When it receives data, it fires an interrupt. The interrupt handler adds the character to a FIFO buffer and notifies the serial port class attached to that port that a character has been received. That message goes into the message queue and your application will receive it via the DataReceived event when the message pump gets around to sending it to your app.
When you read the data from the serial port class, you empty the FIFO buffer either in one swoop or a character at a time. Interlocks are already built into the serial port class so you don't contend with any characters that may be received at the port while the data is being read by the application. For all intents and purposes, you read a string of characters as they have been received up to that point in time.
What is NOT present is any kind of message framing. And that is where you need to do something. The fact is the DataReceived event could be fired for every character that comes in the serial port. You have to grab those characters, append them to a message string, then determine when the message is complete. It is the same as information coming from the keyboard... the user types a single character at a time. If you are looking for a word, you buffer those characters onto a string until you see a space or a carriage return. Same this with the serial port... just think of it as another keyboard where characters arrive (not full strings!).
So you need to decide what your message delimiter is. Normally, for serial communications, the message is ended with a 13... a carriage return. Since it looks like you might be talking to a PLC for data collection, it may also be a fixed-width situation. In that case you need to test the length of the accumulated string each time DataReceived is called. Either way, you need to look for the delimiter or the length in DataRecevied and THEN process your results once the whole string has been received. Make sense?
Secondly, you are casting the serial port from the event arguments. You shouldn't do that. You already have a reference to the serial port in your class-scoped serialPort object. Use it inside of the event handler.
Usually, inside of this event, you setup a While loop that looks at the character count on the serial port. If it is greater than 0, you pull a single character with ReadChar(), check to see if it is your message delimiter, then tack it onto strMessage if it isn't. If it is your delimiter, you pass the message to the processing function and set strMessage to string.empty when you are done.
Remember that DataRecieved is called on a different thread because it is raised by the serial port class. This means your message processing will take place on the worker thread too. If you want to interact with the UI, you will have to marshal the call over to the UI thread.
HTH!
|
|
|
|
|
Hello,
How can I paste outside my application via mouse clicks, When I click in any textbox outside my application it paste from the clipboard ?
I'm already have a code to detect the mouse events but I don't know how to paste outside my windows application
so please provide a good explain and a small example.
Regards
JusT LeT YouR MinD WorK
|
|
|
|
|
"When I click in any textbox outside my application it paste from the clipboard ?"
This doesn't quite make sense: other applications running, that you haven't created, may, or may not, have text-entry fields that allow pasting. If they do, you can just use keyboard Control-V to paste, once you've clicked inside the other application to set the insertion cursor in a Control that allows pasting. Why do you need "more" than that ?
Yes, you can use API calls to find out what window the mouse clicked on "outside your application," but then: how do you discover what kind of control in this other application (you have no control over) they clicked on ? How do you know they clicked on a control that allowed pasting in of text ?
So, could you clarify exactly what you mean by "textBox outside my application," and why would you want to use some mouse-click combination to paste.
yours, Bill
~
“This isn't right; this isn't even wrong." Wolfgang Pauli, commenting on a physics paper submitted for a journal
modified 27-Aug-13 0:34am.
|
|
|
|
|
well I will explain what I want to do.
I have a windows application which is ready to receive some data from the user then make some operations on it then get out the results.
Then the user have to copy the data from the application to store it on webpage to save it on the server.
So what I want to do is to send the results from the the application to the webpage programmatically but I think its not easy, So I think it will be helpful if I made the user paste by doing a double click which I will copy the data from the windows app to clipboard and change it when the user paste on the webpage.
so any other good suggestion for this ?
JusT LeT YouR MinD WorK
|
|
|
|
|
Mahmoud EL-Shazly wrote: copy the data from the application to store it on webpage to save it on the server
That means: there is a web page with a "FORM" element, and on "SUBMIT" the data are transfered to the web server with a GET or - more likely - POST request to a specific URL. Why don't you just do some reverse engineering, and have your application send the data directly to that URL? .Net components for that purpose are available.
|
|
|
|
|
I'm not the developer of that web application I can just use it, so I cannot edit it
All what I need to send the paste action from my application to the windows by double click in any textbox out of my application
as I said I already have a code to detect the mouse events anywhere but I don't know how to send the command to the windows to do the paste action... Will the API help ?
JusT LeT YouR MinD WorK
|
|
|
|
|
In your situation you don't need to paste at all!
Examine the html source of the webpage that you have been trying to paste into. You need to replicate that functionality in your code and send the data (either post or get) directly to the web server programmatically from your application. All the information you need about the expected data to make this work is already in the html source.
|
|
|
|
|
I can detect the mouse clicks in/outside my application
I just want to send WM_PASTE using API to windows so it will execute the paste command.
----------------------------
I need to do that because the user needs to take some data from the customer then enter it to a webpage more than one time and this takes a long time so I want to the user able to store the data in my application then paste them into the webpage faster, this will save a lot of time and of course a lot of money.
I can handle it if the user used it with a control that don't allow pasting in on it.
Now all what I need is to send the paste command to windows successfully.
JusT LeT YouR MinD WorK
|
|
|
|
|
Not so easy. You need a global mouse hook to discover the mouse anywhere. When a click happens, you have to find out the type of the control clicked. In case of "common" textboxes, you can then send the keys for inserting from the clipboard.
It may fail with Java applications when they use "swing".
|
|
|
|
|
Don't post the same question in multiple places - it duplicates work and can annoy people.
You have already posted this in QA, so work with the version there.
This message is manufactured from fully recyclable noughts and ones. To recycle this message, please separate into two tidy piles, and take them to your nearest local recycling centre.
Please note that in some areas noughts are always replaced with zeros by law, and many facilities cannot recycle zeroes - in this case, please bury them in your back garden and water frequently.
|
|
|
|
|
I didn't mean to duplicate my post in many places and if it done I'm sure it done by fault... sorry
JusT LeT YouR MinD WorK
|
|
|
|
|
Question -
There're many obfuscators in the market - what happen if you obfuscate an exe which is NOT signed with a strong name? Strong name - is if you want to install your dll's into GAC, or that you want runtime to check if the binary has been tampered with.
http://www.eziriz.com/help/source/main_panel.html[^]
Take .NET Reactor for instance, it can sign an exe WITHOUT a strong name, with anti tampering/anti disassembly options. In this case, what's the point of having a strong name?
MSDN says ...[^]
dev
modified 26-Aug-13 19:13pm.
|
|
|
|
|
You can always obfuscate a dll which is not signed.
You just can put it in the GAC.
An exe would normally not go into the GAC in any case.
|
|
|
|
|
Bullshit from "MSDN says"
"Strong names offer a powerful mechanism for giving .NET Framework assemblies unique identities. ... mentioned, the .NET Framework verifies the signature either when loading the assembly or when installing it in the GAC. Without access to the private key, a malicious user cannot modify your code and successfully re-sign it."
With all this complication, it has nothing against tampering (If you want anti tampering, buy obfuscation tool from vendor). Unique name? Why not I just read md5 signature? Why bother strong name?
M$ recent years has just been too busy inventing useless sh*t.
For those of you who want to read this bullshit[^]
dev
|
|
|
|
|
devvvy wrote: Why bother strong name?
I load my stuff using the strong name; the fact that it's unique makes it a bit harder to register a new dll on the machine with the same name.
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
devvvy wrote: Why not I just read md5 signature?
Who told you a MD5 hash was unique to only one assembly? That's simply not true. It's rare that two different streams of bytes can come up with the same MD5 hash value, but it is possible.
MD5 is not considered secure anymore. It's too easily broken.
But, it's still just barely useful enough to be a factor in a multiple-factor identification scheme.
|
|
|
|
|
is there any signature based algorithms? I think strong name too much work
dev
|
|
|
|
|
Sign the .EXE with a certificate specifically created for code signing.
|
|
|
|
|
Obfuscation and strong naming serve different purposes.
|
|
|
|
|
for antitampering, use obfuscation tools
for unqiue names/id, seems like i'd prefer simple md5 signature over strong names as strong names takes too much time (sign all 3rd party dll's requires a lot of time) but some argue md5 not unqiue
wonder if all this complexity/additional work from strong name necessary - that really there's no alternative to md5, that we can just run a simple command and generate a unqiue id string like md5 for a binary
dev
|
|
|
|
|
Strongname signing - is for authentication.
Obfuscation - is for encryption.
You, yourself, can authenticate an assembly you are about to load. You need the public key of the assembly supplier, the assembly public key and hash (both stored in the assembly). Now calculate the hash of the assembly using its bytes. If the public key of the assembly matches the public key you know belongs to the supplier, and the hash of the assembly matches the hash you calculated with the public key of the assembly, the assembly can be assumed to be original.
Microsoft .Net performs strong name checking when loading, but it doesn't know whether the assembly's embedded public key is the right public key. That is for you to check.
The same goes for signed executables (VeriSign, etc.) - these all rely on the user being able to tell whether the public key in the executable is the right public key.
Btw. The authentication check only makes sense if all the assemblies to load are checked. Otherwise, a dependent assembly could be tampered with. That is why an assembly should not be strong name signed, if it is dependent on unsigned assemblies.
Hope it makes sense.
Kind Regards,
Keld Ølykke
|
|
|
|
|
Thanks - do you think md5 is sufficient (and much simpler with much lower admin cost) than strong name?
Are you aware of alternatives than strong name and md5?
dev
|
|
|
|
|
Custom MD5 doesn't authenticate that the DLL is the right one so MD5 isn't even an option;
If you have Application A that depends on DLL B
Application A contains in the binary an MD5 sum value of say "12345"
DLL B in the binary has an MD5 sum value of say "12345"
there's nothing stopping an attacker from creating a new version of DLL B with MD5 sum of say "23456" And then just using a hex editor to modify application A to accept MD5 hash of "23456" so nothing is achieved
If; however; you attempt to do the same thing with strong named Application A and dll B, you won't be able to do it, as Application A will refuse to run when it's modified
Strong naming has nothing remotely to do with the MD5 hash of the file nor do they achieve the same thing.
|
|
|
|