c# serial port redirection - c#

Is there a way to, in c# write a serial port redirector? I have an app that is coded to use port 1 (com1:) however, my port on the handheld (Intermec CN50) is always 3. I do not have access to modify the mobile software, however I would like to redirect any data going out to 1 to copy it to 3 and any data coming in to copy it from 3 to 1, so the app doesnt know the difference.
I know this is a difficult issue, but I am sure one of you guys out there have an answer.
I sure dont.
Thanks
Chris

No, there isn't. You have a couple alternatives, depending on the device and your exact needs.
The first, and simplest, is to redirect the driver. If your device doesn't already have a COM1 device defined, you can modify the registry in HKLM\drivers\builtin and change the Index for your specific port from 3 to 1. That will cause device.exe to expose the port as COM1 and not COM3. In my experience this isn't likely to work, though, as most serial ports are set to let the OS auto-assign the index, meaning COM1 and COM2 are already in use. You can, however, still work around this. You simply have to explicitly assign an Index to every instance at or below 3 for the device. Move index 1 to 3 and index 3 to 1 and you effectively swap the ports.
Here are some examples - there are a few because it depends on how the OEM set up driver initialization. Here's an example of a driver with no explicit port named (in this case I2C, but it works the same way):
Note there is a Prefix and an Index. This driver is going to enumerate as "I2C0:". If you changes the Index value to something else, say '2', then it would enumerate as "I2C2:".
In some cases the driver can provide a specific port name, like this one:
Note here that the Port value matches Prefix plus Index. No idea what would happen if you manually set them different, so don't do that. If you wanted to move this one to COM3, you'd change Index to 3 and Port to COM3, but you have to make sure there's nothing else in the registry already set to use those values. You don't want two driver instances trying to enumerate at the same Index. If you do, I think the behavior is that the second one just gets incremented, but it's best to explicitly set the values as unique so you know what's happening.
If that doesn't meet your needs, you'd have to write an actual device driver to do the port move/aggregation. It would work a lot like the existing GPS Intermediate Driver (GPSID) under Windows Mobile and would allow you to redirect the serial data to any port you want. This, however, must be written in C because managed code (in the CF) cannot export native symbols so there's no way to get device.exe to load a C# assembly.

Related

Assign fixed COM ports to keyspan adapters on Windows

I have an application that reads and sends data from/to 2/3 machines attached to the PC through keyspan USB to Serial adapter. Sending/receiving works well.
My problem is that on restart of the PC, the COM ports are assigned "at random", often swapped. That makes automatic processing of data impossible.
I tried to manually set the COMm ports in the Device Manager and with Keyspan assist software without success.
Questions:
how to fix COM ports on Windows so after restart they are always same?
How to assign COM ports with java/c#/powershell (get ports setting and save it(once configured), set on next restart from configuration file)?
Thank you in advance for any suggestions.
Roman
thank you very much for your help.
In the mean time I've slightly modified the solution from http://syswow.blogspot.ch/2013/03/change-device-com-port-via-powershell.html
Unfortunately my current keyspan device ID's are not stable (KEYSPAN*USA19HMAP\00_00 and KEYSPAN*USA19HMAP\01_00 and KEYSPAN*USA19HMAP\02_00), as noted before. These ID's can and often change in between restarts (I suppose as Windows is "registering" them).
I have swapped to another vendor and now I get stable ID's / COM's (FTDIBUS\VID_0403+PID_6001+FTH8ZL5AA\0000 and FTDIBUS\VID_0403+PID_6001+FTH919SZA\0000 etc.).
Thank you once again for your help.
Roman
It's not possible without special USB drivers from your vendor. I don't know who made the USB drivers for your keyspan USB, but you might send them an email asking if they offer something like this. We use Silabs CP210X drivers for usb drivers for our products and they offer a special one that makes it so the COM ports are assigned and don't change randomly when our devices are plugged in. You might try it and see, but no promises it will work with your USB.
In my experience, COM port names are stable in Windows. I suspect there is something weird about the way your USB-to-Serial adapters were implemented, or something weird about the Windows driver you are using with it.
However, given that the COM port names are not stable for you, I would suggest using libusbp. It's a USB abstraction libary written in C which can enumerate the USB devices on your system and tell you the names of their COM ports. What you would do is:
Get a list of devices using libusbp_list_connected_devices.
For each device, call libusbp_device_get_os_id. This will return a string that is something like USB\\VID_1234&PID_DA01\6&11A23516&18&0000. That string should be stable across reboots, so you would have a list of those strings in a configuration file for your software.
If you see a device whose ID matches what is in your configuration file, then use libusbp_serial_port_create and libusbp_serial_port_get_name to get the COM port name.
The library is in C, but it can compile to a Win32 DLL, and you can use PInvoke (FFI) to call functions in it from C# or Java. The library might have some minor compilation errors if you try to compile it in Visual Studio, since it is mainly used in MinGW/GCC/clang environments. You should be able to fix those errors and/or report them as issues on GitHub.

Store data available to multiple computers to be changed and rewritten

I am trying to write a program that generates a specific serial number but it will be able to be accessed by multiple computers in different locations.
The serial number will look something like this:
(2 letters)AA(month)02(year)16(four numbers)0000
Full thing: AA02160000
The last 4 digits will increment by one every time the user clicks a button.
I need to be able to get that serial number from multiple computers in different locations not on the same network and edit it and rewrite it. I can't have any sort of overlap being a serial number and unique to a specific item. I also can't use a guid for the number otherwise it would be much easier.
What is the best way to do this in C#?
I have considered making a server for it but I was running into problems when trying to create directories to pull the number from because of the drive letter.
Can I access a website that is hosted on a computer in one location and have it grab that serial number and increment it and then place the new value on the website?
A bit of help here would be much appreciated.
You could use the Google Docs (or SpreadSheets) and its api.
https://developers.google.com/drive/v3/web/quickstart/dotnet
But you will need access to Internet on all the computers
Another way is to use UNC shared location in your local network for the file.
Also you could create WCF service to update it and write/read the SN to a file (no need to set up db for it)

Getting unique hardware ID changes everytime C#

I want to make a program and sell it, so I was thinking to make some kind of licensing system. What I've found on google is this:
http://www.codeproject.com/Articles/28678/Generating-Unique-Key-Finger-Print-for-a-Computer
I am running Windows 7 (32 bit) in VirtualBox from Ubuntu. I get the same UID, but when I restart my Windows, I get a new UID. I am just thinking that some people will buy my program and they may run it from VirtualBox, so it would be a problem.
Do you guys have any suggestions?
Even if it's an easier way, but something that won't change even if I restart my VBox.
You need to not get so bogged down in the whole DRM process, there are always smarter people out there and someone will work out how to circumvent it.
If you're really concerned:
Set up an online license server to hold your users licenses
Prevent the application from doing anything until the user enters a valid license
This licence would be validated over the internet by your service
You could restrict the number of "active" applications using your service that way
Think along the lines of how iTunes allows you to authorise up to 5 computers to access your media library.
Even if a lot of time has passed, I want to add a possible solution to this question, pointing out something that happened to me trying to generate a fingerprint with exactly that code and facing the same problem.
The identifier function retrieves only the first not-empty value of wmiProperty for each wmiClass. The first important thing you should be aware of is this: what is returned for every wmiClass might not belong to the same ManagementObject. Hence, if something changes to "not the first object", this might affect also your fingerprint.
Be advised that using Win32_DiskDrive as wmiClass is dangerous since plugging in a USB device often results in this device being recognized as the first one (instead of your hard drive), changing the fingerprint as you plug-in or out your device. Even if this doesn't happen, still one of the wmiProperty could be taken from your USB device if your main drive has it empty (e.g. the disk signature, which happened to me).
A possible solution to that would be excluding all USB devices by checking InterfaceType and excluding all those who match "USB", or at least that's what I did.

get list of printer ports

I'm looking for a way to list all printer ports on the current PC. I want to list them and put them into a combo box. I was going to create a list and pull that in every time the cbo must load, however I then thought about if people add their own ports and some printers install themselves to new ports. Because of this just stating a generic list of ports might not be the correct way.
I am using DOS print process to the printer port directly and in the settings need the user to select which port to print to.
I'm sure someone has a quick way, or a way they can point me to. I saw a couple ways online however It completely boggled my mind and I don't like using code I can't understand, and don't have the time to understand it right now unfortunately. I am sure there must be a class of somesort in C# already created to do this. Most of the other ways I saw to me appeared to be importing several dlls and or running through a few registeries.
And assistance is greatly appreciated
UPDATE just to be clear I want a way that will simply return to me LPT1 LPT2 COM1....

Receiving Invalid Data from Serial Port using SerialPort.ReadExisting()

I have written a program in .NET that listens to a particular Serial Port and processes the data that is being received. I wrote a test program using com0com (the Null-modem emulator) and my program was working fine. I even tested it with HyperTerminal and that seemed to work fine too.
However when I interfaced the software with the original device (an output received from a control system), the data received was garbled. It contained special characters. The same device when connected with Hyper Terminal produced the desired output. I changed the baud rates, parity etc but the data received was the same set of garbage characters.
I have used the DataReceived event of the SerialPort component and used the following line of code to capture data:
string data = portRecieve.ReadExisting();
Can somebody tell me where am i missing out? In the current environment, the output from the device is directly connected with a dot matrix printer which prints whatever is received on the port. The printer seems to catch what is being sent but my code couldn't.
If you ever encountered a similar scenario, Please share your findings.
Thanks
How did you set
SerialPort.DiscardNull
SerialPort.Encoding
And maybe show us an example of the special chars you are receiving.
I can think of the following reasons why the data might apperar garbled:
If there is a bad physical connection, you can sometimes just get garbage (rather than nothing at all). Try unplugging and replugging the leads - and check that you have the correct lead (e.g. do you need a nullmodem?). It looks as though you have this covered by checking in HyperTerminal.
If the baud rate, stop bits, parity are not correct - sounds like you have this one covered
You are trying to receive the data as a string. If it is not sent as plain text, or if your encoding is wrong, then it could easily appear garbage-like. Try using a binary receive and examine the raw data that you are receiving. This will tell you whether the data is just wrong or the .net conversion is screwing it up - eliminate the middle man!
It sounds to me like the device is putting the printer into some special graphics mode. If so, there is likely to be escape sequences in the data being sent to the printer, ie. character sequences starying with an escape (27, 0x1B) character.
In this case, you'll have to look at the printer manual to see what the commands do. Alternatively, you might be able to tell the device to use a simple ASCII only printer, rather than a intellifent one.

Categories

Resources