Link to home
Start Free TrialLog in
Avatar of T0masz
T0masz

asked on

Serial port dumper as service

Hey,
Im looking for a sample program that would run as a NT5/win2k/xp service and dump all the data from a certain com port to a file The program would read the input from the serial port line by line ( it would phrase the line after \n ) and insert it into the file. I would prefer something written in perl or delphi

Thanks
Tom
Avatar of sunnycoder
sunnycoder
Flag of India image

Avatar of T0masz
T0masz

ASKER

I know how to write a sample program that reads from a port, the problem is that It has to be running as a NT service...

Tom
check this

How to write a Windows NT Service (Delphi 5)
http://www.delphifaq.com/fq/q3055.shtml

Creating NT services in Delphi
http://builder.com.com/5100-6387-1050538.html?tag=sc
Avatar of T0masz

ASKER

The serial components dont work for delphi 7 and thats the only one I have...
Thanks for your help.
Tom
Hi Tom,

I am a bot confused here ... You said in last post that you have the program to read/write to serial ports and need to make it run as a service ... Now you say that you do not have the working program ....

What is that you are looking for ?
Avatar of T0masz

ASKER

I dont have a working program, Im trying to write one, so far I got SerialNG to work but I have no clue how to make it read line by line and write to a file... another question is how far is it to go from a program thats designed as an :application: to a service?

Tom
Hello..
If you use Delphi try the ComPort Component.
You will find it at: http://www.winsoft.sk
Regards,
gtokas.
P.S. As I understand you know how to make an NT Service.
Avatar of T0masz

ASKER

Whats the advantage of using the commercial version? and Nope I have no clue how to make a service in delphi 7...

Tom
The advantage is that it is a component added at Delphi's system tab and you don't need to hard code.
As I recall(I don't use Delphi, I use BCB) there is a "NTservice project wizard" at the "New" dialog in Delphi.
Also there are many examples on how to implement a NTService with Delphi. Borland community have some i.e.

gtokas
Avatar of T0masz

ASKER

Well I might aswell use SerialNG, its a component, I just have no clue how to get it to print every single line to a window/file. As for the service Delphi 7 has no such thing as NTService in the project wizard, There is "Service" or "Service Application" would that be it? OK I guess Service Application is what Im looking for. Ill browse thru the samples from serialng and see what I can come up.

Thanks
Tom
Yes that is what you are looking for.
I'm not familiar with SerialNG so I can't help you.
On the other hand I have extensive expierience with ComPort.

gtokas.
Avatar of T0masz

ASKER

http://www.domis.de/cms/index.php?module=ContentExpress&func=display&ceid=8
From what I understand I can either read it char by char or as a cluster, the cluster doesnt really work for me cuz Im not looking for size. So onrxcharevent i would have to check if its \n if yes, write to file, if not add onto the string. Is that a good solution? does comport offer a better solution? onreadline even or something?

Tom
Avatar of T0masz

ASKER

public string ReadUntil(char terminator);

Reads a string of characters, terminated by specified character, from the communication device. Waits for received data, if its needed.

I guess ComPort has what Im looking for, but Ill try to work with serialng for now
here is a question I asked about serialng
https://www.experts-exchange.com/questions/20971167/SerialNG-read-a-line.html

Tom
Below is the example for Delphi6 for ComPort. I think you can find it helpfull.

unit UDemo;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ComPort, StdCtrls, Buttons, ComCtrls;

type
  TFormComPort = class(TForm)
    Edit: TEdit;
    ComPort: TComPort;
    Memo: TMemo;
    Label1: TLabel;
    Label2: TLabel;
    ComboBoxBaudRate: TComboBox;
    ComboBoxDataBits: TComboBox;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    ComboBoxStopBits: TComboBox;
    ComboBoxParity: TComboBox;
    SpeedButtonOpenClose: TSpeedButton;
    SpeedButtonSend: TSpeedButton;
    ComboBoxDeviceName: TComboBox;
    StatusBar: TStatusBar;
    SpeedButtonSetRTS: TSpeedButton;
    SpeedButtonClearRTS: TSpeedButton;
    SpeedButtonSetDTR: TSpeedButton;
    SpeedButtonClearDTR: TSpeedButton;
    procedure ComPortRxChar(Sender: TObject);
    procedure SpeedButtonOpenCloseClick(Sender: TObject);
    procedure ComboBoxBaudRateChange(Sender: TObject);
    procedure ComboBoxDataBitsChange(Sender: TObject);
    procedure ComboBoxStopBitsChange(Sender: TObject);
    procedure ComboBoxParityChange(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure SpeedButtonSendClick(Sender: TObject);
    procedure ComboBoxDeviceNameChange(Sender: TObject);
    procedure ComPortError(ComPort: TCustomComPort; E: EComError;
      var Action: TComAction);
    procedure ComPortLineError(Sender: TObject; LineErrors: TLineErrors);
    procedure ComPortCTSChange(Sender: TObject);
    procedure ComPortDSRChange(Sender: TObject);
    procedure ComPortRing(Sender: TObject);
    procedure ComPortRLSDChange(Sender: TObject);
    procedure ComPortAfterWrite(Sender: TObject; Buffer: Pointer;
      Length: Integer; WaitOnCompletion: Boolean);
    procedure SpeedButtonSetRTSClick(Sender: TObject);
    procedure SpeedButtonClearRTSClick(Sender: TObject);
    procedure SpeedButtonClearDTRClick(Sender: TObject);
    procedure SpeedButtonSetDTRClick(Sender: TObject);
  private
    { Private declarations }
    FReadCount: Integer;
    FWriteCount: Integer;
    procedure SetModemStatus;
    procedure AddReadBytes(ReadCount: Integer);
    procedure AddWriteBytes(WriteCount: Integer);
  public
    { Public declarations }
  end;

var
  FormComPort: TFormComPort;

implementation

{$R *.DFM}

procedure TFormComPort.SpeedButtonSendClick(Sender: TObject);
begin
  ComPort.WriteString(Edit.Text + #13);
end;

procedure TFormComPort.ComPortRxChar(Sender: TObject);
var Text: String;
begin
  Text := ComPort.ReadString;
  Memo.SelText := Text;
  AddReadBytes(Length(Text));
end;

procedure TFormComPort.SpeedButtonOpenCloseClick(Sender: TObject);
begin
  with ComPort do
  begin
    Active := not Active;

    if Active then
      SpeedButtonOpenClose.Caption := 'Close'
    else
      SpeedButtonOpenClose.Caption := 'Open';

    Memo.Enabled := Active;
    Edit.Enabled := Active;
    SpeedButtonSend.Enabled := Active;
    ComboBoxDeviceName.Enabled := not Active;
    SetModemStatus;
  end;
end;

procedure TFormComPort.ComboBoxDeviceNameChange(Sender: TObject);
begin
  ComPort.DeviceName := ComboBoxDeviceName.Text;
end;

procedure TFormComPort.ComboBoxBaudRateChange(Sender: TObject);
begin
  ComPort.BaudRate := TBaudRate(ComboBoxBaudRate.ItemIndex);
end;

procedure TFormComPort.ComboBoxDataBitsChange(Sender: TObject);
begin
  ComPort.DataBits := TDataBits(ComboBoxDataBits.ItemIndex);
end;

procedure TFormComPort.ComboBoxStopBitsChange(Sender: TObject);
begin
  ComPort.StopBits := TStopBits(ComboBoxStopBits.ItemIndex);
end;

procedure TFormComPort.ComboBoxParityChange(Sender: TObject);
begin
  ComPort.Parity := TParity(ComboBoxParity.ItemIndex);
end;

procedure TFormComPort.FormCreate(Sender: TObject);
begin
  ComboBoxBaudRate.ItemIndex := 0;
  ComboBoxDataBits.ItemIndex := 0;
  ComboBoxStopBits.ItemIndex := 0;
  ComboBoxParity.ItemIndex := 0;
  AddReadBytes(0);
  AddWriteBytes(0);
  SetModemStatus;
end;

procedure TFormComPort.ComPortError(ComPort: TCustomComPort; E: EComError;
  var Action: TComAction);
begin
  MessageDlg('Error ' + IntToStr(E.ErrorCode) + ': ' + E.Message, mtError, [mbOK], 0);
  Action := caAbort;
end;

procedure TFormComPort.ComPortLineError(Sender: TObject;
  LineErrors: TLineErrors);
begin
  if leBreak in LineErrors then MessageDlg('Break detected', mtError, [mbOK], 0);
  if leDeviceNotSelected in LineErrors then MessageDlg('Device not selected', mtError, [mbOK], 0);
  if leFrame in LineErrors then MessageDlg('Frame error', mtError, [mbOK], 0);
  if leIO in LineErrors then MessageDlg('IO error', mtError, [mbOK], 0);
  if leMode in LineErrors then MessageDlg('Mode error', mtError, [mbOK], 0);
  if leOutOfPaper in LineErrors then MessageDlg('Out of paper', mtError, [mbOK], 0);
  if leOverrun in LineErrors then MessageDlg('Overrun error', mtError, [mbOK], 0);
  if leDeviceTimeOut in LineErrors then MessageDlg('Device timeout', mtError, [mbOK], 0);
  if leRxOverflow in LineErrors then MessageDlg('Receiver overflow', mtError, [mbOK], 0);
  if leParity in LineErrors then MessageDlg('Parity error', mtError, [mbOK], 0);
  if leTxFull in LineErrors then MessageDlg('Transmitter full', mtError, [mbOK], 0);
end;

procedure TFormComPort.SetModemStatus;
var ModemStatus: TModemStatus;
begin
  if not ComPort.Active then
  begin
    StatusBar.Panels[2].Text := 'CTS:';
    StatusBar.Panels[3].Text := 'DSR:';
    StatusBar.Panels[4].Text := 'Ring:';
    StatusBar.Panels[5].Text := 'RLSD:';
  end
  else
  begin
    ModemStatus := ComPort.ModemStatus;

    if msCTS in ModemStatus then
      StatusBar.Panels[2].Text := 'CTS: On'
    else
      StatusBar.Panels[2].Text := 'CTS: Off';

    if msDSR in ModemStatus then
      StatusBar.Panels[3].Text := 'DSR: On'
    else
      StatusBar.Panels[3].Text := 'DSR: Off';

    if msRing in ModemStatus then
      StatusBar.Panels[4].Text := 'Ring: On'
    else
      StatusBar.Panels[4].Text := 'Ring: Off';

    if msRLSD in ModemStatus then
      StatusBar.Panels[5].Text := 'RLSD: On'
    else
      StatusBar.Panels[5].Text := 'RLSD: Off';
  end;
end;

procedure TFormComPort.ComPortCTSChange(Sender: TObject);
begin
  SetModemStatus;
end;

procedure TFormComPort.ComPortDSRChange(Sender: TObject);
begin
  SetModemStatus;
end;

procedure TFormComPort.ComPortRing(Sender: TObject);
begin
  SetModemStatus;
end;

procedure TFormComPort.ComPortRLSDChange(Sender: TObject);
begin
  SetModemStatus;
end;

procedure TFormComPort.AddReadBytes(ReadCount: Integer);
begin
  FReadCount := FReadCount + ReadCount;
  StatusBar.Panels[0].Text := 'Read bytes: ' + IntToStr(FReadCount);
end;

procedure TFormComPort.AddWriteBytes(WriteCount: Integer);
begin
  FWriteCount := FWriteCount + WriteCount;
  StatusBar.Panels[1].Text := 'Write bytes: ' + IntToStr(FWriteCount);
end;

procedure TFormComPort.ComPortAfterWrite(Sender: TObject; Buffer: Pointer;
  Length: Integer; WaitOnCompletion: Boolean);
begin
  AddWriteBytes(Length);
end;

procedure TFormComPort.SpeedButtonSetRTSClick(Sender: TObject);
begin
  ComPort.SetRTS;
end;

procedure TFormComPort.SpeedButtonClearRTSClick(Sender: TObject);
begin
  ComPort.ClearRTS;
end;

procedure TFormComPort.SpeedButtonSetDTRClick(Sender: TObject);
begin
  ComPort.SetDTR;
end;

procedure TFormComPort.SpeedButtonClearDTRClick(Sender: TObject);
begin
  ComPort.ClearDTR;
end;

end.

Regards,
gtokas.
Avatar of T0masz

ASKER

uciaport did the trick, it had everything I needed.

Tom
ASKER CERTIFIED SOLUTION
Avatar of modulo
modulo

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial