Using a remote PC's Windows OS by Node.js

This Smart Pascal program, inspired by James's remote control of the Raspberry Pi, uses Node.js to execute commands on a remote Windows PC. It has a similar set-up to that described in detail above. As with the Pi version, the user has the choice of selecting one of the tested commands in the combo box or typing a command into the edit box. The commands received from all clients are collected in a single file on the server.

The Smart Pascal code of the server and client follow the screenshot of the program in action. See the Pi version for the XML code of the form of the client.

Application in Action

Application in Action

Smart Pascal Code of Server

You can compare this code with a JavaScript version.

unit Unit1;

interface

type
  TServer = class
  public
    procedure Run;
  end;

implementation

uses
  NodeJS.Core, NodeJS.http, Node_Static, socket.io, NodeJS.fs;

procedure TServer.Run;
begin
  var ws := fs.createWriteStream('requests.txt', nil);

  var fileserver := TNodeStaticServer.Create('./public');
  //start http server
  var server: JServer := http.createServer(
    procedure(request: JServerRequest; response: JServerResponse)
    begin
      Console.log('http request: ' + request.url);
      if request.url = '/' then
        request.url := '/WinClientExec.html';
      fileserver.serve(request, response);
    end);
  server.listen(8079, '');
  Console.log('Server running at http://192.168.0.2:8079');

  var value := 0;
  var io := socketio().listen(server);
  io.sockets.on('connection',    // waiting for connections
    procedure(socket: JSocketIO)
    begin
      socket.on('requestFromClient',  // waiting for a special request from the client
        procedure(data: Variant; callback: JSocketIODataFunction)
        begin
          Console.log('Received from client: ' + data);
          ws.write(data + #13#10, 'utf8');
          asm
            var exec = require('child_process').exec;
            exec(data, function(err, stdout, stderr) {
              if (err) {
                @callback('error code ' + err.code);
                return;
              }
              @callback(stdout);
            });
          end;
      end);
    end);
end;

end.    

Smart Pascal Code of Form of Client

unit Form1;

interface

uses 
  SmartCL.System, SmartCL.Graphics, SmartCL.Components, SmartCL.Forms, 
  SmartCL.Fonts, SmartCL.Borders, SmartCL.Application, SmartCL.Controls.Button,
  SmartCL.Controls.Panel, SmartCL.Controls.EditBox, SmartCL.Controls.Memo,
  socketioclient, SmartCL.Controls.ComboBox;

type
  TForm1 = class(TW3Form)
    procedure W3Button1Click(Sender: TObject);
  private
    FSocket: JSocketIO;
    {$I 'Form1:intf'}
  protected
    procedure InitializeObject; override;
  end;

implementation

procedure TForm1.W3Button1Click(Sender: TObject);
begin
  FSocket.emit('requestFromClient', [W3EditBox1.Text],
    procedure(aData: variant)
    begin
      W3Memo1.Text := aData;
    end);
end;

procedure TForm1.InitializeObject;
begin
  inherited;
  {$I 'Form1:impl'}
  FSocket := socketio.connect('http://192.168.0.2:8079');
  W3Combobox1.Add('echo This is fun!');
  W3Combobox1.Add('dir');
  W3Combobox1.Add('type requests.txt');
  W3Combobox1.Add('ipconfig');
  W3Combobox1.Add('path');
  W3Combobox1.Add('ver');
  W3Combobox1.Add('node -v');

  W3Combobox1.OnClick := procedure(Sender: TObject)
    begin
      FSocket.emit('requestFromClient', [W3Combobox1.Items[W3Combobox1.SelectedIndex]],
        procedure(aData: variant)
        begin
          W3Memo1.Text := aData;
        end);
    end;
  W3Editbox1.Text := 'dir';
end;

initialization
  Forms.RegisterForm({$I %FILE%}, TForm1);
end.    

Programming - a skill for life!

Using Node.js for a server that updates connected clients in real time and remote use of a Raspberry Pi's OS