homebridge-config-ui-x
Version:
A web based management, configuration and control platform for Homebridge.
146 lines • 5.74 kB
JavaScript
import { execSync } from 'node:child_process';
import { createWriteStream } from 'node:fs';
import { arch } from 'node:os';
import { resolve } from 'node:path';
import process from 'node:process';
import axios from 'axios';
import { pathExists, remove } from 'fs-extra/esm';
import { BasePlatform } from '../base-platform.js';
export class Win32Installer extends BasePlatform {
async install() {
this.checkIsAdmin();
await this.hbService.portCheck();
await this.hbService.storagePathCheck();
await this.hbService.configCheck();
const nssmPath = await this.downloadNssm();
const installCmd = `"${nssmPath}" install ${this.hbService.serviceName} `
+ `"${process.execPath}" "\""${this.hbService.selfPath}"\"" run -I -U "\""${this.hbService.storagePath}"\""`;
const setUserDirCmd = `"${nssmPath}" set ${this.hbService.serviceName} AppEnvironmentExtra ":UIX_STORAGE_PATH=${this.hbService.storagePath}"`;
try {
execSync(installCmd);
execSync(setUserDirCmd);
await this.configureFirewall();
await this.start();
await this.hbService.printPostInstallInstructions();
}
catch (e) {
console.error(e.toString());
this.hbService.logger('ERROR: Failed Operation', 'fail');
}
}
async uninstall() {
this.checkIsAdmin();
await this.stop();
try {
execSync(`sc delete ${this.hbService.serviceName}`);
this.hbService.logger(`Removed ${this.hbService.serviceName} Service`, 'succeed');
}
catch (e) {
console.error(e.toString());
this.hbService.logger('ERROR: Failed Operation', 'fail');
}
}
async start() {
this.checkIsAdmin();
try {
this.hbService.logger(`Starting ${this.hbService.serviceName} Service...`);
execSync(`sc start ${this.hbService.serviceName}`);
this.hbService.logger(`${this.hbService.serviceName} Started`, 'succeed');
}
catch (e) {
this.hbService.logger(`Failed to start ${this.hbService.serviceName}`, 'fail');
}
}
async stop() {
this.checkIsAdmin();
try {
this.hbService.logger(`Stopping ${this.hbService.serviceName} Service...`);
execSync(`sc stop ${this.hbService.serviceName}`);
this.hbService.logger(`${this.hbService.serviceName} Stopped`, 'succeed');
}
catch (e) {
this.hbService.logger(`Failed to stop ${this.hbService.serviceName}`, 'fail');
}
}
async restart() {
this.checkIsAdmin();
await this.stop();
setTimeout(async () => {
await this.start();
}, 4000);
}
async rebuild(all = false) {
this.checkIsAdmin();
try {
execSync('npm rebuild --unsafe-perm', {
cwd: process.env.UIX_BASE_PATH,
stdio: 'inherit',
});
this.hbService.logger(`Rebuilt modules in ${process.env.UIX_BASE_PATH} for Node.js ${process.version}.`, 'succeed');
}
catch (e) {
console.error(e.toString());
this.hbService.logger('ERROR: Failed Operation', 'fail');
}
}
async updateNodejs(job) {
this.hbService.logger('ERROR: This command is not supported on Windows.', 'fail');
this.hbService.logger(`Please download Node.js v${job.target} from https://nodejs.org/en/download/ and install manually.`, 'fail');
}
checkIsAdmin() {
try {
execSync('fsutil dirty query %systemdrive% >nul');
}
catch (e) {
this.hbService.logger('ERROR: This command must be run as an Administrator', 'fail');
this.hbService.logger('Node.js command prompt shortcut -> Right Click -> Run as administrator', 'fail');
process.exit(1);
}
}
async downloadNssm() {
const downloadUrl = `https://github.com/homebridge/nssm/releases/download/2.24-101-g897c7ad/nssm_${arch()}.exe`;
const nssmPath = resolve(this.hbService.storagePath, 'nssm.exe');
if (await pathExists(nssmPath)) {
return nssmPath;
}
const nssmFile = createWriteStream(nssmPath);
this.hbService.logger(`Downloading NSSM from ${downloadUrl}`);
return new Promise((res, rej) => {
axios({
method: 'GET',
url: downloadUrl,
responseType: 'stream',
})
.then((response) => {
response.data.pipe(nssmFile).on('finish', () => {
return res(nssmPath);
}).on('error', (err) => {
return rej(err);
});
})
.catch(async (e) => {
nssmFile.close();
await remove(nssmPath);
this.hbService.logger(`Failed to download nssm: ${e.message}`, 'fail');
process.exit(0);
});
});
}
async configureFirewall() {
const cleanFirewallCmd = 'netsh advfirewall firewall Delete rule name="Homebridge"';
const openFirewallCmd = `netsh advfirewall firewall add rule name="Homebridge" dir=in action=allow program="${process.execPath}"`;
try {
execSync(cleanFirewallCmd);
}
catch (e) {
}
try {
execSync(openFirewallCmd);
}
catch (e) {
this.hbService.logger('Failed to configure firewall rule for Homebridge.', 'warn');
this.hbService.logger(e);
}
}
}
//# sourceMappingURL=win32.js.map