66// - do some kind of "pkill vnc-software/tigervnc-linux-x86_64/usr/bin/x0vncserver -rfbport=55900" to ensure none other is still running
77// - do some kind of "pkill vnc-software/tigervnc-linux-x86_64/usr/bin/vncviewer SecurityTypes=None 127.0.0.1::45900" to ensure none other is still running
88// - before starting a new client or server process, check if serverChild or clientChild are initialized and if yes, stop them
9+ // - support (a list of) multiple running clientChilds instead of just one
910
1011const { app, BrowserWindow, ipcMain, shell } = require ( 'electron' ) ;
12+ const nodePath = require ( 'node:path' ) ;
1113import { existsSync } from 'node:fs' ;
1214
1315let serverChild ;
@@ -101,14 +103,17 @@ function stopChild(child) {
101103// Search order:
102104// - vnc-software/ (when launching in development)
103105// - /tmp/.mount_peervizdlxvC/resources/vnc-software/ (launched from appimage or .deb package installation)
106+ // - on windows: check console.log to know what __dirname and process.cwd() are
104107function findResourceFile ( filename ) {
108+ console . log ( "findResourceFile __dirname = " ) ;
105109 console . log ( __dirname )
110+ console . log ( "findResourceFile process.cwd = " ) ;
106111 console . log ( process . cwd ( ) )
107- const magicName = "vnc-software/" ;
108- const parts = __dirname . split ( '/' ) ;
109- let appImageMount = parts . slice ( 0 , - 3 ) . join ( '/' ) ; // /tmp/.mount_peervizdlxvC/resources/app.asar/.webpack/main becomes /tmp/.mount_peervizdlxvC/resources
112+ const magicName = "vnc-software" + nodePath . sep ;
113+ const parts = __dirname . split ( nodePath . sep ) ;
114+ let appImageMount = parts . slice ( 0 , - 3 ) . join ( nodePath . sep ) ; // /tmp/.mount_peervizdlxvC/resources/app.asar/.webpack/main becomes /tmp/.mount_peervizdlxvC/resources
110115 // placesToCheck are directories that should end with a slash
111- let placesToCheck = [ magicName , appImageMount + "/" + magicName , "/" ] ;
116+ let placesToCheck = [ magicName , appImageMount + nodePath . sep + magicName , nodePath . sep ] ;
112117 for ( const str of placesToCheck ) {
113118 let fullName = str + filename ;
114119 console . log ( "checking exists: " + str ) ;
@@ -122,6 +127,13 @@ function findResourceFile(filename) {
122127}
123128
124129ipcMain . on ( 'run-server' , ( event ) => {
130+ // Make sure this OS is supported
131+ if ( process . platform !== 'linux' && process . platform !== 'win32' ) {
132+ let error = 'Unsupported platform ' + process . platform + '. Only linux and win32 are supported, darwin (MacOS) not yet. Please reach out!' ;
133+ console . log ( error ) ;
134+ event . reply ( error ) ;
135+ return - 1 ;
136+ }
125137 if ( ! serverChild ) { // Only run the server if not started already. It keeps running the whole time.
126138 event . reply ( 'run-server-log' , "Initializing network layer..." ) ;
127139 publicKeyServer = startHyperTeleServer ( ) ;
@@ -130,14 +142,36 @@ ipcMain.on('run-server', (event) => {
130142 event . reply ( 'run-server-log' , "Network layer initialized." ) ;
131143
132144 event . reply ( 'run-server-log' , "Preparing for incoming connections..." ) ;
133- // default debian package has x0tigervncserver instead
134- serverChild = runProcess ( 'tigervnc-linux-x86_64/usr/bin/x0vncserver' , [ 'SecurityTypes=None' , '-localhost=1' , '-interface=127.0.0.1' , '-rfbport=55900' ] ) ;
145+ if ( process . platform === 'linux' ) {
146+ let binaryName = 'tigervnc-linux-x86_64/usr/bin/x0vncserver' ;
147+ let foundBinary = findResourceFile ( binaryName ) ;
148+ if ( ! foundBinary ) {
149+ console . log ( "Binary " + binaryName + " not found." ) ;
150+ return - 2 ;
151+ }
152+ let dirname = nodePath . dirname ( foundBinary ) ;
153+ serverChild = runProcess ( foundBinary , [ 'SecurityTypes=VncAuth' , 'localhost=1' , 'interface=127.0.0.1' , 'rfbport=55900' , 'PasswordFile=' + dirname + nodePath . sep + 'plain.bin' ] ) ;
154+ } else if ( process . platform === 'win32' ) {
155+ serverChild = findAndRunProcess ( 'vnc-software\\uvnc-windows\\x64\\winvnc.exe' ) ; // uses the config file next to the binary
156+ }
157+ if ( ! serverChild ) {
158+ event . reply ( 'run-server-log' , "ERROR: Listening for connections using VNC server failed." ) ;
159+ return ;
160+ }
135161 }
136162 event . reply ( 'run-server-pubkey' , publicKeyServer ) ;
137163 event . reply ( 'run-server-log' , "Ready for incoming connections." ) ;
138164} ) ;
139165
140166ipcMain . on ( 'run-client' , ( event , data ) => {
167+ // Make sure this OS is supported
168+ if ( process . platform !== 'linux' && process . platform !== 'win32' ) {
169+ let error = 'Unsupported platform ' + process . platform + '. Only linux and win32 are supported, darwin (MacOS) not yet. Please reach out!' ;
170+ console . log ( error ) ;
171+ event . reply ( error ) ;
172+ return - 1 ;
173+ }
174+
141175 event . reply ( 'run-client-log' , "Initializing network layer..." ) ;
142176 console . log ( "running client with connectto data: " + data ) ;
143177 let hyperTeleProxy = startHyperTeleClient ( data ) ;
@@ -148,10 +182,21 @@ ipcMain.on('run-client', (event, data) => {
148182 event . reply ( 'run-client-log' , "Network layer initialized." ) ;
149183
150184 event . reply ( 'run-client-log' , "Establishing outgoing connection..." ) ;
151- // default debian package has xtigervncviewer instead
152- let clientChild = runProcess ( 'tigervnc-linux-x86_64/usr/bin/vncviewer' , [ 'SecurityTypes=None' , '127.0.0.1::45900' ] ) ;
185+ if ( process . platform === 'linux' ) {
186+ let binaryName = 'tigervnc-linux-x86_64/usr/bin/vncviewer' ;
187+ let foundBinary = findResourceFile ( binaryName ) ;
188+ if ( ! foundBinary ) {
189+ console . log ( "Binary " + binaryName + " not found." ) ;
190+ return - 2 ;
191+ }
192+ // PasswordFile of TigerVNC viewer cannot be passed on commandline, so use the file next to the binary.
193+ let dirname = nodePath . dirname ( foundBinary ) ;
194+ clientChild = runProcess ( foundBinary , [ 'SecurityTypes=VncAuth' , 'PasswordFile=' + dirname + nodePath . sep + 'plain.bin' , '127.0.0.1::45900' ] ) ;
195+ } else if ( process . platform === 'win32' ) {
196+ clientChild = findAndrunProcess ( 'vnc-software\\uvnc-windows\\x64\\vncviewer.exe' , [ '/password nopassword' , 'localhost:45900' ] ) ;
197+ }
153198 if ( ! clientChild ) {
154- event . reply ( 'run-client-log' , "Outgoing connection using vncviewer failed." ) ;
199+ event . reply ( 'run-client-log' , "ERROR: Outgoing connection using vncviewer failed." ) ;
155200 return ;
156201 }
157202 // Stop the hyperTeleProxy from listening when the client is closed, because the next run might use a different client
@@ -164,18 +209,16 @@ ipcMain.on('run-client', (event, data) => {
164209 event . reply ( 'run-client-log' , "Outgoing connection established." ) ;
165210} ) ;
166211
167- function runProcess ( binaryName , args ) {
168- if ( process . platform !== 'linux' ) { // win32/darwin not supported
169- console . log ( 'Unsupported platform ' + process . platform + '. Only linux is supported, win32/darwin not yet. Please reach out!' ) ;
170- return - 1 ;
171- }
172-
212+ function findAndRunProcess ( binaryName , args ) {
173213 let foundBinary = findResourceFile ( binaryName ) ;
174214 if ( ! foundBinary ) {
175215 console . log ( "Binary " + binaryName + " not found." ) ;
176216 return - 2 ;
177217 }
218+ return runProcess ( foundBinary ) ;
219+ }
178220
221+ function runProcess ( foundBinary , args ) {
179222 const { spawn } = require ( 'child_process' ) ;
180223 const child = spawn ( foundBinary , args ) ;
181224 return child ;
0 commit comments