wifiInterfaces(), wifiConnections() added

This commit is contained in:
Sebastian Hildebrandt 2021-02-10 16:08:55 +01:00
parent cce9fd5f73
commit ac29803f03
18 changed files with 904 additions and 97 deletions

View File

@ -1,35 +1,59 @@
# Changelog
### Major Changes - Version 4
### Major Changes - Version 5
**New Functions**
- `chassis()`: chassis information
- `audio()` detailed audio information
- `bluetoothDevices()` detailed information detected bluetooth devices
- `printers()` detailed printer information
- `usb()` detailed USB information
- `wifiInterfaces()` detected Wi-Fi interfaces
- `wifiConnections()` active Wi-Fi connections
**Breaking Changes**
- `networkStats()`: will provide an **array** of stats for all given interfaces. In previous versions only one interface was provided as a parameter. Pass '*' for all interfaces
- `networkStats()`: `rx` and `tx` changed to `rx_bytes` and `tx_bytes`
- `dockerContainerStats()`: will provide an **array** of stats for all given docker containers. In previous versions only one interface was provided as a parameter. Pass '*' for all docker containers
**Be aware**, that the new version 5.x **is NOT fully backward compatible** to version 4.x ...
**Other Changes**
We had to make several interface changes to keep systeminformation as consistent as possible. We highly recommend to go [through the complete list](https://systeminformation.io/changes.html) and adapt your own code to be again compatible to the new version 5.
- `system()` optimized system detection (e.g. new Raspberry Pi models, ...), additional flags
- `system()`, `bios()`, `baseboard()` information also as non-root (linux)
- `graphics()` better controller and display detection, fixes
- `versions()` optimization, fixes
- `networkInterfaces()` added `operstate`, `type`, `duplex`, `mtu`, `speed`, `carrierChanges`
- `networkStats()` added stats for `errors`, `dropped`
- added TypeScript definitions
**Other Improvements and Changes**
**Be aware**, that the new version 4.x is **NOT fully backward compatible** to version 3.x ...
- `baseboard(): added memMax, memSlots
- `bios()`: added language and features (linux)
- `cpu()`: extended AMD processor list
- `cpu()`: extended socket list (win)
- `cpu()`: added virtualization if cpu supports virtualization
- `cpu()`: now flags are part of this function
- `fsSize()`: added available
- `fsSize()`: improved calculation of used
- `getData()`: support for passing parameters and filters (see section General / getData)
- `graphics()`: extended nvidia-smi parsing
- `networkInterfaces()`: type detection improved (win - wireless)
- `memoryLayout()`: extended manufacturer list (decoding)
- `memoryLayout()`: added ECC flag
- `osInfo()`: better fqdn (win)
- `osinfo()`: added hypervizor if hyper-v is enabled (win only)
- `system()`: better Raspberry PI detection
- `system()`: added virtual and virtualHost (if system is virtual instance)
- `uuid()`: better value support
- `uuid()`: added MACs
- `uuid()`: better Raspberry Pi hardware ID
- `Apple M1 Silicon extended support (now everything supported except of cpu temperature)
- `updated TypeScript definitions
For major (breaking) changes - version 3 and 2 see end of page.
**Test Full Version 5 Functionality**
If you want to see all function results on your machine, please head over to (Testing section)[https://systeminformation.io/tests.html]. We implemented a tiny test suite where you can easily go through all functions and test resuls on your machine without coding.
For major (breaking) changes - **version 4, 3 and 2** - see end of page.
## Version history
| Version | Date | Comment |
| -------------- | -------------- | -------- |
| 5.2.0 | 2020-02-10 | `wifiInterfces()` and `wifiConnections()` added |
| 5.1.2 | 2020-02-08 | fixed node 4 compatibility issue |
| 5.1.1 | 2020-02-08 | `baseboard()` added memMax, memSlots, smaller improvements Raspberry |
| 5.1.0 | 2020-02-08 | `memLayout()` added ECC flag, `bios()` added language, features (linux) |
@ -436,6 +460,29 @@ For major (breaking) changes - version 3 and 2 see end of page.
| 0.0.2 | 2014-03-14 | Optimization FS-Speed & CPU current speed |
| 0.0.1 | 2014-03-13 | initial release |
### Major C`hanges - Version 4
**New Functions**
- `chassis()`: chassis information
**Breaking Changes**
- `networkStats()`: will provide an **array** of stats for all given interfaces. In previous versions only one interface was provided as a parameter. Pass '*' for all interfaces
- `networkStats()`: `rx` and `tx` changed to `rx_bytes` and `tx_bytes`
- `dockerContainerStats()`: will provide an **array** of stats for all given docker containers. In previous versions only one interface was provided as a parameter. Pass '*' for all docker containers
**Other Changes**
- `system()` optimized system detection (e.g. new Raspberry Pi models, ...), additional flags
- `system()`, `bios()`, `baseboard()` information also as non-root (linux)
- `graphics()` better controller and display detection, fixes
- `versions()` optimization, fixes
- `networkInterfaces()` added `operstate`, `type`, `duplex`, `mtu`, `speed`, `carrierChanges`
- `networkStats()` added stats for `errors`, `dropped`
- added TypeScript definitions
**Be aware**, that the new version 4.x is **NOT fully backward compatible** to version 3.x ...
### Major (breaking) Changes - Version 3
- works only with [node.js][nodejs-url] **v4.0.0** and above (using now internal ES6 promise function, arrow functions, ...)

View File

@ -565,7 +565,7 @@ Full function reference with examples can be found at [https://systeminformation
| | ms | X | X | X | X | X | response time in ms |
| si.inetLatency(host, cb) | : number | X | X | X | X | X | response-time (ms) to external resource<br>host parameter is optional (default 8.8.8.8)|
#### 14. Wifi networks
#### 14. Wifi
| Function | Result object | Linux | BSD | Mac | Win | Sun | Comments |
| --------------- | ------------- | ----- | ------- | --- | --- | --- | -------- |
@ -580,6 +580,25 @@ Full function reference with examples can be found at [https://systeminformation
| | [0].security | X | | X | X | | array e.g. WPA, WPA-2 |
| | [0].wpaFlags | X | | X | X | | array of WPA flags |
| | [0].rsnFlags | X | | | | | array of RDN flags |
| si.wifiInterfaces(cb) | [{...}] | X | | X | X | | array of detected wifi interfaces |
| | [0].id | X | | X | X | | ID |
| | [0].iface | X | | X | X | | interface |
| | [0].model | X | | X | X | | model |
| | [0].vendor | X | | X | X | | vendor |
| | [0].mac | X | | X | X | | MAC address |
| si.wifiConnections(cb) | [{...}] | X | | X | X | | array of active wifi connections |
| | [0].id | X | | X | X | | ID |
| | [0].iface | X | | X | X | | interface |
| | [0].name | X | | X | X | | name |
| | [0].mode | X | | X | X | | model |
| | [0].bssid | X | | X | X | | BSSID (mac) |
| | [0].mode | X | | | | | mode |
| | [0].channel | X | | X | X | | channel |
| | [0].frequency | X | | X | X | | frequengy in MHz |
| | [0].signalLevel | X | | X | X | | signal level in dB |
| | [0].quality | X | | X | X | | quaility in % |
| | [0].security | X | | X | X | | array e.g. WPA, WPA-2 |
| | [0].txRate | X | | X | X | | transfer rate MBit/s |
#### 15. Bluetooth

View File

@ -47,9 +47,11 @@
<h4>New Functions</h4>
<ul>
<li><span class="code">audio()</span> detailed audio information </li>
<li><span class="code">bluetoothDevices()</span> detailed information detected bluetooth devices</li>
<li><span class="code">printers()</span> detailed printer information </li>
<li><span class="code">usb()</span> detailed USB information</li>
<li><span class="code">bluetoothDevices()</span> detailed information detected bluetooth devices</li>
<li><span class="code">wifiInterfaces()</span> detected Wi-Fi interfaces</li>
<li><span class="code">wifiConnections()</span> active Wi-Fi connections</li>
</ul>
<h4>Breaking Changes</h4>
<p><span class="bold">Be aware</span>, that the new version 5.x is <span class="bold">NOT fully backward compatible</span> to version 4.x ...</p>
@ -185,6 +187,7 @@
<li><span class="code">uuid()</span>: better value support</li>
<li><span class="code">uuid()</span>: added MACs</li>
<li><span class="code">uuid()</span>: better Raspberry Pi hardware ID</li>
<li><span class="code">versions()</span>: added bash, zsh, fish, powershell, dotnet</li>
<li><span class="code">Apple M1 Silicon</span> extended support (now everything supported except of cpu temperature)</li>
<li>updated TypeScript definitions </li>
</ul>

View File

@ -56,6 +56,11 @@
</tr>
</thead>
<tbody>
<tr>
<th scope="row">5.2.0</th>
<td>2020-02-10</td>
<td><span class="code">wifiInterfces()</span> and <span class="code">wifiConnections()</span> added</td>
</tr>
<tr>
<th scope="row">5.1.2</th>
<td>2020-02-08</td>

View File

@ -170,7 +170,7 @@
<img class="logo" src="assets/logo.png">
<div class="title">systeminformation</div>
<div class="subtitle"><span id="typed"></span>&nbsp;</div>
<div class="version">New Version: <span id="version">5.1.2</span></div>
<div class="version">New Version: <span id="version">5.2.0</span></div>
<button class="btn btn-light" onclick="location.href='https://github.com/sebhildebrandt/systeminformation'">View on Github <i class=" fab fa-github"></i></button>
</div>
<div class="down">
@ -201,7 +201,7 @@
</div>
<div class="row number-section">
<div class="col-xl-4 col-lg-4 col-md-4 col-12">
<div class="numbers">13,280</div>
<div class="numbers">13,533</div>
<div class="title">Lines of code</div>
</div>
<div class="col-xl-4 col-lg-4 col-md-4 col-12">

View File

@ -550,6 +550,56 @@ si.osInfo().then(data => console.log(data));</code></pre class="example">
<td>X</td>
<td>virtualbox version</td>
</tr>
<tr>
<td></td>
<td>bash</td>
<td>X</td>
<td>X</td>
<td>X</td>
<td>X</td>
<td>X</td>
<td>bash version</td>
</tr>
<tr>
<td></td>
<td>zsh</td>
<td>X</td>
<td>X</td>
<td>X</td>
<td>X</td>
<td>X</td>
<td>zsh version</td>
</tr>
<tr>
<td></td>
<td>fish</td>
<td>X</td>
<td>X</td>
<td>X</td>
<td>X</td>
<td>X</td>
<td>fish version</td>
</tr>
<tr>
<td></td>
<td>powershell</td>
<td></td>
<td></td>
<td></td>
<td>X</td>
<td></td>
<td>powershell version</td>
</tr>
<tr>
<td></td>
<td>dotnet</td>
<td></td>
<td></td>
<td></td>
<td>X</td>
<td></td>
<td>dotnet version</td>
</tr>
<tr class="example">
<td></td>
<td colspan="7">
@ -587,7 +637,12 @@ si.versions().then(data => console.log(data));</code></pre class="example">
pip3: '19.0.3',
java: '',
gcc: '4.2.1',
virtualbox: ''
virtualbox: '',
bash: '3.2.57',
zsh: '5.8',
fish: '',
powershell: '',
dotnet: ''
}</pre>
<h5>Example 2</h5>
<pre><code class="js">const si = require('systeminformation');

View File

@ -63,8 +63,8 @@
═══════════════════════════════════════════════════════════
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ a ... Audio h ... Bluetooth s ... Services ? ... Get Object │
│ b ... BIOS i ... INET Latency S ... Shell , ... All Static │
│ a ... Audio h ... Bluetooth s ... Services Y ... Battery ? ... Get Object │
│ b ... BIOS i ... INET Latency S ... Shell z ... Users , ... All Static │
│ B ... Baseboard I ... INET Check Site t ... time 1 ... NET Iface Default . ... All Dynamic │
│ C ... Chassis j ... CPU Current Speed T ... CPU Temperature 2 ... NET Gateway Default / ... All │
│ c ... CPU l ... CPU Current Load u ... USB 3 ... NET Interfaces │
@ -72,9 +72,9 @@
│ D ... DiskIO m ... Memory v ... Versions 5 ... NET Connections │
│ e ... Block Devices M ... MEM Layout V ... Virtual Box 6 ... Docker Info │
│ E ... Open Files o ... OS Info w ... WIFI networks 7 ... Docker Container │
│ f ... FS Size p ... Processes y ... System 8 ... Docker Cont Stats │
│ F ... FS Stats P ... Process Load Y ... Battery 9 ... Docker Cont Proc │
│ g ... Graphics r ... Printer z ... Users 0 ... Docker All q >>> QUIT │
│ f ... FS Size p ... Processes W ... WIFI interfaces 8 ... Docker Cont Stats │
│ F ... FS Stats P ... Process Load x ... WIFI connections 9 ... Docker Cont Proc │
│ g ... Graphics r ... Printer y ... System 0 ... Docker All q >>> QUIT │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘</code></pre>
<p><span class="bold">Press q</span> to exit the test suite</p>
<p>Here a sample output for the e.g. <span class="bold">c ... CPU</span></p>

View File

@ -47,7 +47,7 @@
<div class="col-12 sectionheader">
<div class="title">Wifi</div>
<div class="text">
<p>In this section you will learn how to get detailed information about available wifi networks:</p>
<p>In this section you will learn how to get detailed information about available wifi networks, interfaces and connections:</p>
<p>For function reference and examples we assume, that we imported <span class="code">systeminformation</span> as follows:</p>
<pre><code class="js">const si = require('systeminformation');</code></pre>
<h2>Wifi Networks</h2>
@ -214,6 +214,277 @@ si.wifiNetworks().then(data => console.log(data));</code></pre class="example">
</tbody>
</table>
<h2>Wifi Interfaces</h2>
<p>All functions in this section return a promise or can be called with a callback function (parameter <span class="code">cb</span> in the function reference)</p>
<table class="table table-sm table-bordered table-striped">
<thead>
<tr>
<th>Function</th>
<th>Result object</th>
<th>Linux</th>
<th>BSD</th>
<th>Mac</th>
<th>Win</th>
<th>Sun</th>
<th>Comments</th>
</tr>
</thead>
<tbody>
<tr>
<td>si.wifiInterfaces(cb)</td>
<td>[{...}]</td>
<td>X</td>
<td></td>
<td>X</td>
<td>X</td>
<td></td>
<td>array of detected wifi interfaces</td>
</tr>
<tr>
<td></td>
<td>[0].id</td>
<td>X</td>
<td></td>
<td>X</td>
<td>X</td>
<td></td>
<td>Wifi ID</td>
</tr>
<tr>
<td></td>
<td>[0].iface</td>
<td>X</td>
<td></td>
<td>X</td>
<td>X</td>
<td></td>
<td>interface</td>
</tr>
<tr>
<td></td>
<td>[0].model</td>
<td>X</td>
<td></td>
<td>X</td>
<td>X</td>
<td></td>
<td>model</td>
</tr>
<tr>
<td></td>
<td>[0].vendor</td>
<td>X</td>
<td></td>
<td>X</td>
<td>X</td>
<td></td>
<td>vendor</td>
</tr>
<tr>
<td></td>
<td>[0].mac</td>
<td>X</td>
<td></td>
<td>X</td>
<td>X</td>
<td></td>
<td>interface MAC</td>
</tr>
<tr class="example">
<td></td>
<td colspan="7">
<h5>Example</h5>
<pre><code class="js">const si = require('systeminformation');
si.wifiInterfaces().then(data => console.log(data));</code></pre class="example">
<pre class="example">
[
{
id: 'Wi-Fi',
iface: 'en0',
model: 'AirPort',
vendor: '',
mac: 'a0:b1:c2:d3:e4:f5'
},
...
]</pre>
</tr>
</tbody>
</table>
<h2>Wifi Connections</h2>
<p>All functions in this section return a promise or can be called with a callback function (parameter <span class="code">cb</span> in the function reference)</p>
<table class="table table-sm table-bordered table-striped">
<thead>
<tr>
<th>Function</th>
<th>Result object</th>
<th>Linux</th>
<th>BSD</th>
<th>Mac</th>
<th>Win</th>
<th>Sun</th>
<th>Comments</th>
</tr>
</thead>
<tbody>
<tr>
<td>si.wifiConnections(cb)</td>
<td>[{...}]</td>
<td>X</td>
<td></td>
<td>X</td>
<td>X</td>
<td></td>
<td>array of active wifi connections</td>
</tr>
<tr>
<td></td>
<td>[0].id</td>
<td>X</td>
<td></td>
<td>X</td>
<td>X</td>
<td></td>
<td>Wifi ID</td>
</tr>
<tr>
<td></td>
<td>[0].iface</td>
<td>X</td>
<td></td>
<td>X</td>
<td>X</td>
<td></td>
<td>interface</td>
</tr>
<tr>
<td></td>
<td>[0].name</td>
<td>X</td>
<td></td>
<td>X</td>
<td>X</td>
<td></td>
<td>name</td>
</tr>
<tr>
<td></td>
<td>[0].model</td>
<td>X</td>
<td></td>
<td>X</td>
<td>X</td>
<td></td>
<td>model</td>
</tr>
<tr>
<td></td>
<td>[0].ssid</td>
<td>X</td>
<td></td>
<td>X</td>
<td>X</td>
<td></td>
<td>Wifi network SSID</td>
</tr>
<tr>
<td></td>
<td>[0].bssid</td>
<td>X</td>
<td></td>
<td>X</td>
<td>X</td>
<td></td>
<td>BSSID (mac)</td>
</tr>
<tr>
<td></td>
<td>[0].channel</td>
<td>X</td>
<td></td>
<td>X</td>
<td>X</td>
<td></td>
<td>channel</td>
</tr>
<tr>
<td></td>
<td>[0].frequency</td>
<td>X</td>
<td></td>
<td>X</td>
<td>X</td>
<td></td>
<td>frequency</td>
</tr>
<tr>
<td></td>
<td>[0].type</td>
<td>X</td>
<td></td>
<td>X</td>
<td>X</td>
<td></td>
<td>WiFi type</td>
</tr>
<tr>
<td></td>
<td>[0].security</td>
<td>X</td>
<td></td>
<td>X</td>
<td>X</td>
<td></td>
<td>WiFi security</td>
</tr>
<tr>
<td></td>
<td>[0].signalLevel</td>
<td>X</td>
<td></td>
<td>X</td>
<td>X</td>
<td></td>
<td>signal level in dB</td>
</tr>
<tr>
<td></td>
<td>[0].txRate</td>
<td>X</td>
<td></td>
<td>X</td>
<td>X</td>
<td></td>
<td>transfer rate Mbit/s</td>
</tr>
<tr class="example">
<td></td>
<td colspan="7">
<h5>Example</h5>
<pre><code class="js">const si = require('systeminformation');
si.wifiConnections().then(data => console.log(data));</code></pre class="example">
<pre class="example">
[
{
id: 'Wi-Fi',
iface: 'en0',
name: 'AirPort',
model: 'AirPort',
ssid: 'my-own-internet',
bssid: '01:23:45:67:89:0a',
channel: 36,
frequency: 5180,
type: '802.11',
security: 'wpa2-psk',
signalLevel: 46,
txRate: '405'
},
...
]</pre>
</tr>
</tbody>
</table>
</div>
</div>

View File

@ -552,7 +552,7 @@ function getCpu() {
result.virtualization = flags.indexOf('vmx') > -1 || flags.indexOf('svm') > -1;
if (_windows) {
try {
const systeminfo = execSync('systeminfo').toString();
const systeminfo = execSync('systeminfo', util.execOptsWin).toString();
result.virtualization = result.virtualization || (systeminfo.indexOf('Virtualization Enabled In Firmware: Yes') !== -1) || (systeminfo.indexOf('Virtualisierung in Firmware aktiviert: Ja') !== -1) || (systeminfo.indexOf('Virtualisation activée dans le microprogramme : Qiu') !== -1);
} catch (e) {
util.noop();

View File

@ -408,6 +408,7 @@ function graphics(callback) {
function nvidiaSmi(options) {
const nvidiaSmiExe = getNvidiaSmi();
options = options || util.execOptsWin;
if (nvidiaSmiExe) {
const nvidiaSmiOpts = '--query-gpu=driver_version,pci.sub_device_id,name,pci.bus_id,fan.speed,memory.total,memory.used,memory.free,utilization.gpu,utilization.memory,temperature.gpu,temperature.memory,power.draw,power.limit,clocks.gr,clocks.mem --format=csv,noheader,nounits';
const cmd = nvidiaSmiExe + ' ' + nvidiaSmiOpts + (_linux ? ' 2>/dev/null' : '');

21
lib/index.d.ts vendored
View File

@ -487,6 +487,27 @@ export namespace Systeminformation {
rsnFlags: string[];
}
interface WifiInterfaceData {
id: string;
iface: string;
model: string;
vendor: string;
}
interface WifiConnectionData {
id: string;
iface: string;
model: string;
ssid: string;
bssid: string;
channel: number;
type: string;
security: string;
frequency: number;
signalLevel: number;
txRate: number;
}
// 7. Current Load, Processes & Services
interface CurrentLoadData {

View File

@ -469,6 +469,8 @@ exports.networkStats = network.networkStats;
exports.networkConnections = network.networkConnections;
exports.wifiNetworks = wifi.wifiNetworks;
exports.wifiInterfaces = wifi.wifiInterfaces;
exports.wifiConnections = wifi.wifiConnections;
exports.services = processes.services;
exports.processes = processes.processes;

View File

@ -805,7 +805,8 @@ function networkInterfaces(callback, rescan = true) {
}
mac = details.mac;
// fallback due to https://github.com/nodejs/node/issues/13581 (node 8.1 - node 8.2)
if (mac.indexOf('00:00:0') > -1 && (_linux || _darwin) && parseInt(process.versions.node.split('.'), 10) === 8) {
const nodeMainVersion = parseInt(process.versions.node.split('.'), 10);
if (mac.indexOf('00:00:0') > -1 && (_linux || _darwin) && (!details.internal) && nodeMainVersion >= 8 && nodeMainVersion <= 11) {
if (Object.keys(_mac).length === 0) {
_mac = getMacAddresses();
}

View File

@ -178,7 +178,7 @@ function getFQDN() {
}
if (_windows) {
try {
const stdout = execSync('echo %COMPUTERNAME%.%USERDNSDOMAIN%');
const stdout = execSync('echo %COMPUTERNAME%.%USERDNSDOMAIN%', util.execOptsWin);
fqdn = stdout.toString().replace('.%USERDNSDOMAIN%', '').split(os.EOL)[0];
} catch (e) {
util.noop();
@ -323,7 +323,7 @@ function osInfo(callback) {
try {
const workload = [];
workload.push(util.wmic('os get /value'));
workload.push(execPromise('systeminfo'));
workload.push(execPromise('systeminfo', util.execOptsWin));
util.promiseAll(
workload
).then(data => {
@ -433,6 +433,10 @@ function versions(apps, callback) {
java: '',
gcc: '',
virtualbox: '',
bash: '',
zsh: '',
fish: '',
powershell: '',
dotnet: ''
};
@ -440,7 +444,7 @@ function versions(apps, callback) {
if (apps === '*') {
return {
versions: versionObject,
counter: 26
counter: 30
};
}
if (!Array.isArray(apps)) {
@ -607,7 +611,7 @@ function versions(apps, callback) {
exec('apachectl -v 2>&1', function (error, stdout) {
if (!error) {
const apache = (stdout.toString().split('\n')[0] || '').split(':');
appsObj.versions.apache = (apache.length > 1 ? apache[1].replace('Apache', '').replace('/', '').trim() : '');
appsObj.versions.apache = (apache.length > 1 ? apache[1].replace('Apache', '').replace('/', '').split('(')[0].trim() : '');
}
functionProcessed();
});
@ -926,15 +930,66 @@ function versions(apps, callback) {
functionProcessed();
});
}
if ({}.hasOwnProperty.call(appsObj.versions, 'dotnet')) {
exec('dotnet --version 2>&1', function (error, stdout) {
if ({}.hasOwnProperty.call(appsObj.versions, 'bash')) {
exec('bash --version', function (error, stdout) {
if (!error) {
const dotnet = stdout.toString().split('\n')[0] || '';
appsObj.versions.dotnet = dotnet.trim();
const line = stdout.toString().split('\n')[0];
const parts = line.split(' version ');
if (parts.length > 1) {
appsObj.versions.bash = parts[1].split(' ')[0].split('(')[0];
}
}
functionProcessed();
});
}
if ({}.hasOwnProperty.call(appsObj.versions, 'zsh')) {
exec('zsh --version', function (error, stdout) {
if (!error) {
const line = stdout.toString().split('\n')[0];
const parts = line.split('zsh ');
if (parts.length > 1) {
appsObj.versions.zsh = parts[1].split(' ')[0];
}
}
functionProcessed();
});
}
if ({}.hasOwnProperty.call(appsObj.versions, 'fish')) {
exec('fish --version', function (error, stdout) {
if (!error) {
const line = stdout.toString().split('\n')[0];
const parts = line.split(' version ');
if (parts.length > 1) {
appsObj.versions.fish = parts[1].split(' ')[0];
}
}
functionProcessed();
});
}
if ({}.hasOwnProperty.call(appsObj.versions, 'powershell')) {
if (_windows) {
util.powerShell('$PSVersionTable').then(stdout => {
const lines = stdout.toString().split('\n').map(line => line.replace(/ +/g, ' ').replace(/ +/g, ':'));
appsObj.versions.powershell = util.getVersion(lines, 'psversion');
functionProcessed();
});
} else {
functionProcessed();
}
}
if ({}.hasOwnProperty.call(appsObj.versions, 'dotnet')) {
util.powerShell('gci "HKLM:\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP" -recurse | gp -name Version,Release -EA 0 | where { $_.PSChildName -match "^(?!S)\\p{L}"} | select PSChildName, Version, Release').then(stdout => {
const lines = stdout.toString().split('\r\n');
let dotnet = '';
lines.forEach(line => {
line = line.replace(/ +/g, ' ');
const parts = line.split(' ');
dotnet = dotnet || ((parts[0].toLowerCase().startsWith('client') && parts.length > 2 ? parts[1].trim() : (parts[0].toLowerCase().startsWith('full') && parts.length > 2 ? parts[1].trim() : '')));
});
appsObj.versions.dotnet = dotnet.trim();
functionProcessed();
});
}
} catch (e) {
if (callback) { callback(appsObj.versions); }
resolve(appsObj.versions);

View File

@ -301,7 +301,7 @@ function getWmic() {
wmicPath = WINDIR + '\\system32\\wbem\\wmic.exe';
if (!fs.existsSync(wmicPath)) {
try {
const wmicPathArray = execSync('WHERE WMIC').toString().split('\r\n');
const wmicPathArray = execSync('WHERE WMIC', execOptsWin).toString().split('\r\n');
if (wmicPathArray && wmicPathArray.length) {
wmicPath = wmicPathArray[0];
} else {
@ -392,7 +392,7 @@ function getCodepage() {
if (_windows) {
if (!codepage) {
try {
const stdout = execSync('chcp');
const stdout = execSync('chcp', execOptsWin);
const lines = stdout.toString().split('\r\n');
const parts = lines[0].split(':');
codepage = parts.length > 1 ? parts[1].replace('.', '') : '';

View File

@ -112,7 +112,116 @@ function wifiFrequencyFromChannel(channel) {
return {}.hasOwnProperty.call(frequencies, channel) ? frequencies[channel] : null;
}
function getWifiNetworkAlt(iface) {
function ifaceListLinux() {
const result = [];
const cmd = 'iw dev';
try {
const all = execSync(cmd).toString().split('\n').map(line => line.trim()).join('\n');
const parts = all.split('\nInterface ');
parts.shift();
parts.foreach(ifaceDetails => {
const lines = ifaceDetails.split('\n');
const iface = lines[0];
const id = util.toInt(util.getValue(lines, 'ifindex', ' '));
const mac = util.getValue(lines, 'addr', ' ');
const channel = util.toInt(util.getValue(lines, 'channel', ' '));
result.push({
id,
iface,
mac,
channel
});
});
return result;
} catch (e) {
return [];
}
}
function nmiDeviceLinux(iface) {
const cmd = 'nmcli -t -f general,wifi-properties,capabilities,ip4,ip6 device show ' + iface;
try {
const lines = execSync(cmd).toString().split('\n');
return {
iface,
type: util.getValue(lines, 'GENERAL.TYPE'),
vendor: util.getValue(lines, 'GENERAL.VENDOR'),
product: util.getValue(lines, 'GENERAL.PRODUCT'),
mac: util.getValue(lines, 'GENERAL.HWADDR').toLowerCase(),
ssid: util.getValue(lines, 'GENERAL.CONNECTION'),
};
} catch (e) {
return {};
}
}
function nmiConnectionLinux(ssid) {
const cmd = 'nmcli -t --show-secrets connection show ' + ssid;
try {
const lines = execSync(cmd).toString().split('\n');
return {
ssid,
uuid: util.getValue(lines, 'connection.uuid'),
type: util.getValue(lines, 'connection.type'),
autoconnect: util.getValue(lines, 'connection.autoconnect') === 'yes',
security: util.getValue(lines, '802-11-wireless-security.key-mgmt'),
bssid: util.getValue(lines, '802-11-wireless.seen-bssids').toLowerCase()
};
} catch (e) {
return {};
}
}
function wpaConnectionLinux(iface) {
const cmd = `wpa_cli -i ${iface} status`;
try {
const lines = execSync(cmd).toString().split('\n');
return {
ssid: util.getValue(lines, 'ssid', '='),
uuid: util.getValue(lines, 'uuid', '='),
security: util.getValue(lines, 'key_mgmt', '='),
freq: util.getValue(lines, 'freq', '='),
bssid: util.getValue(lines, 'bssid', '=').toLowerCase()
};
} catch (e) {
return {};
}
}
function getWifiNetworkListNmi() {
const result = [];
const cmd = 'nmcli -t -m multiline --fields active,ssid,bssid,mode,chan,freq,signal,security,wpa-flags,rsn-flags device wifi list 2>/dev/null';
try {
const stdout = execSync(cmd, { maxBuffer: 1024 * 20000 });
const parts = stdout.toString().split('ACTIVE:');
parts.shift();
parts.forEach(part => {
part = 'ACTIVE:' + part;
const lines = part.split(os.EOL);
const channel = util.getValue(lines, 'CHAN');
const frequency = util.getValue(lines, 'FREQ').toLowerCase().replace('mhz', '').trim();
const security = util.getValue(lines, 'SECURITY').replace('(', '').replace(')', '');
const wpaFlags = util.getValue(lines, 'WPA-FLAGS').replace('(', '').replace(')', '');
const rsnFlags = util.getValue(lines, 'RSN-FLAGS').replace('(', '').replace(')', '');
result.push({
ssid: util.getValue(lines, 'SSID'),
bssid: util.getValue(lines, 'BSSID').toLowerCase(),
mode: util.getValue(lines, 'MODE'),
channel: channel ? parseInt(channel, 10) : null,
frequency: frequency ? parseInt(frequency, 10) : null,
signalLevel: wifiDBFromQuality(util.getValue(lines, 'SIGNAL')),
quality: parseFloat(util.getValue(lines, 'SIGNAL')),
security: security && security !== 'none' ? security.split(' ') : [],
wpaFlags: wpaFlags && wpaFlags !== 'none' ? wpaFlags.split(' ') : [],
rsnFlags: rsnFlags && rsnFlags !== 'none' ? rsnFlags.split(' ') : []
});
});
} catch (e) {
return [];
}
}
function getWifiNetworkListIw(iface) {
const result = [];
try {
let iwlistParts = execSync(`export LC_ALL=C; iwlist ${iface} scan 2>&1; unset LC_ALL`).toString().split(' Cell ');
@ -196,80 +305,53 @@ function wifiNetworks(callback) {
process.nextTick(() => {
let result = [];
if (_linux) {
let cmd = 'nmcli --terse --fields active,ssid,bssid,mode,chan,freq,signal,security,wpa-flags,rsn-flags device wifi list 2>/dev/null';
exec(cmd, { maxBuffer: 1024 * 20000 }, function (error, stdout) {
const parts = stdout.toString().split('ACTIVE:');
parts.shift();
parts.forEach(part => {
part = 'ACTIVE:' + part;
const lines = part.split(os.EOL);
const channel = util.getValue(lines, 'CHAN');
const frequency = util.getValue(lines, 'FREQ').toLowerCase().replace('mhz', '').trim();
const security = util.getValue(lines, 'SECURITY').replace('(', '').replace(')', '');
const wpaFlags = util.getValue(lines, 'WPA-FLAGS').replace('(', '').replace(')', '');
const rsnFlags = util.getValue(lines, 'RSN-FLAGS').replace('(', '').replace(')', '');
result.push({
ssid: util.getValue(lines, 'SSID'),
bssid: util.getValue(lines, 'BSSID').toLowerCase(),
mode: util.getValue(lines, 'MODE'),
channel: channel ? parseInt(channel, 10) : null,
frequency: frequency ? parseInt(frequency, 10) : null,
signalLevel: wifiDBFromQuality(util.getValue(lines, 'SIGNAL')),
quality: parseFloat(util.getValue(lines, 'SIGNAL')),
security: security && security !== 'none' ? security.split(' ') : [],
wpaFlags: wpaFlags && wpaFlags !== 'none' ? wpaFlags.split(' ') : [],
rsnFlags: rsnFlags && rsnFlags !== 'none' ? rsnFlags.split(' ') : []
});
});
if (result.length === 0) {
try {
const iwconfigParts = execSync('export LC_ALL=C; iwconfig 2>/dev/null; unset LC_ALL').toString().split('\n\n');
let iface = '';
for (let i = 0; i < iwconfigParts.length; i++) {
if (iwconfigParts[i].indexOf('no wireless') === -1) {
iface = iwconfigParts[i].split(' ')[0];
}
result = getWifiNetworkListNmi();
if (result.length === 0) {
try {
const iwconfigParts = execSync('export LC_ALL=C; iwconfig 2>/dev/null; unset LC_ALL').toString().split('\n\n');
let iface = '';
for (let i = 0; i < iwconfigParts.length; i++) {
if (iwconfigParts[i].indexOf('no wireless') === -1) {
iface = iwconfigParts[i].split(' ')[0];
}
if (iface) {
const res = getWifiNetworkAlt(iface);
if (res === -1) {
// try again after 4 secs
setTimeout(function (iface) {
const res = getWifiNetworkAlt(iface);
if (res != -1) { result = res; }
if (callback) {
callback(result);
}
resolve(result);
}, 4000);
} else {
result = res;
}
if (iface) {
const res = getWifiNetworkListIw(iface);
if (res === -1) {
// try again after 4 secs
setTimeout(function (iface) {
const res = getWifiNetworkListIw(iface);
if (res != -1) { result = res; }
if (callback) {
callback(result);
}
resolve(result);
}
}, 4000);
} else {
result = res;
if (callback) {
callback(result);
}
resolve(result);
}
} catch (e) {
} else {
if (callback) {
callback(result);
}
resolve(result);
}
} else {
} catch (e) {
if (callback) {
callback(result);
}
resolve(result);
}
});
} else {
if (callback) {
callback(result);
}
resolve(result);
}
} else if (_darwin) {
let cmd = '/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -s';
exec(cmd, { maxBuffer: 1024 * 20000 }, function (error, stdout) {
@ -361,3 +443,240 @@ function wifiNetworks(callback) {
}
exports.wifiNetworks = wifiNetworks;
function getVendor(model) {
model = model.toLowerCase();
let result = '';
if (model.indexOf('intel') >= 0) { result = 'Intel'; }
else if (model.indexOf('realtek') >= 0) { result = 'Realtek'; }
else if (model.indexOf('qualcom') >= 0) { result = 'Qualcom'; }
else if (model.indexOf('broadcom') >= 0) { result = 'Broadcom'; }
else if (model.indexOf('cavium') >= 0) { result = 'Cavium'; }
else if (model.indexOf('cisco') >= 0) { result = 'Cisco'; }
else if (model.indexOf('marvel') >= 0) { result = 'Marvel'; }
else if (model.indexOf('zyxel') >= 0) { result = 'Zyxel'; }
else if (model.indexOf('melanox') >= 0) { result = 'Melanox'; }
else if (model.indexOf('d-link') >= 0) { result = 'D-Link'; }
else if (model.indexOf('tp-link') >= 0) { result = 'TP-Link'; }
else if (model.indexOf('asus') >= 0) { result = 'Asus'; }
else if (model.indexOf('linksys') >= 0) { result = 'Linksys'; }
return result;
}
function wifiConnections(callback) {
return new Promise((resolve) => {
process.nextTick(() => {
const result = [];
if (_linux) {
const ifaces = ifaceListLinux();
const networkList = getWifiNetworkListNmi();
ifaces.forEach(ifaceDetail => {
const nmiDetails = nmiDeviceLinux(ifaceDetail.iface);
const wpaDetails = wpaConnectionLinux(ifaceDetail.iface);
const ssid = nmiDetails.ssid;
const network = networkList.filter(nw => nw.ssid === ssid);
const nmiConnection = nmiConnectionLinux(ssid);
const channel = network && network.length && network[0].channel ? network[0].channel : null;
result.push({
id: ifaceDetail.id,
iface: ifaceDetail.iface,
model: nmiDetails.product,
ssid,
bssid: network && network.length && network[0].bssid ? network[0].bssid : (wpaDetails && wpaDetails.bssid ? wpaDetails.bssid : null),
channel,
frequency: channel ? wifiFrequencyFromChannel(channel) : null,
type: nmiConnection && nmiConnection.type ? nmiConnection.type : '802.11',
security: nmiConnection && nmiConnection.security ? nmiConnection.security : (wpaDetails && wpaDetails.security ? wpaDetails.security : null),
signalLevel: network && network.length && network[0].signalLevel ? network[0].signalLevel : null,
txRate: null
});
});
if (callback) {
callback(result);
}
resolve(result);
} else if (_darwin) {
let cmd = 'system_profiler SPNetworkDataType';
exec(cmd, function (error, stdout) {
const parts1 = stdout.toString().split('\n\n Wi-Fi:\n\n');
if (parts1.length > 1) {
const lines = parts1[1].split('\n\n')[0].split('\n');
const iface = util.getValue(lines, 'BSD Device Name', ':', true);
const model = util.getValue(lines, 'hardware', ':', true);
cmd = '/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I';
exec(cmd, function (error, stdout) {
const lines2 = stdout.toString().split('\n');
if (lines.length > 10) {
const ssid = util.getValue(lines2, 'ssid', ':', true);
const bssid = util.getValue(lines2, 'bssid', ':', true);
const security = util.getValue(lines2, 'link auth', ':', true);
const txRate = util.getValue(lines2, 'lastTxRate', ':', true);
const channel = util.getValue(lines2, 'channel', ':', true).split(',')[0];
const type = '802.11';
const rssi = util.toInt(util.getValue(lines2, 'agrCtlRSSI', ':', true));
const noise = util.toInt(util.getValue(lines2, 'agrCtlNoise', ':', true));
const signalLevel = rssi - noise;
// const signal = wifiQualityFromDB(signalLevel);
if (ssid && bssid) {
result.push({
id: 'Wi-Fi',
iface,
model,
ssid,
bssid,
channel: util.toInt(channel),
frequency: channel ? wifiFrequencyFromChannel(channel) : null,
type,
security,
signalLevel,
txRate
});
}
}
if (callback) {
callback(result);
}
resolve(result);
});
}
});
} else if (_windows) {
let cmd = 'netsh wlan show interfaces';
exec(cmd, util.execOptsWin, function (error, stdout) {
const parts = stdout.toString().split(':\r\n\r\n');
parts.shift();
parts.forEach(part => {
const lines = part.split('\r\n');
if (lines.length >= 5) {
const iface = lines[0].indexOf(':') >= 0 ? lines[0].split(':')[1].trim() : '';
const model = lines[1].indexOf(':') >= 0 ? lines[1].split(':')[1].trim() : '';
const id = lines[2].indexOf(':') >= 0 ? lines[2].split(':')[1].trim() : '';
const ssid = util.getValue(lines, 'SSID', ':', true);
const bssid = util.getValue(lines, 'BSSID', ':', true);
const signalLevel = util.getValue(lines, 'Signal', ':', true);
const type = util.getValue(lines, 'Radio type', ':', true) || util.getValue(lines, 'Type de radio', ':', true) || util.getValue(lines, 'Funktyp', ':', true) || null;
const security = util.getValue(lines, 'authentication', ':', true) || util.getValue(lines, 'Authentification', ':', true) || util.getValue(lines, 'Authentifizierung', ':', true) || null;
const channel = util.getValue(lines, 'Channel', ':', true) || util.getValue(lines, 'Canal', ':', true) || util.getValue(lines, 'Kanal', ':', true) || null;
const txRate = util.getValue(lines, 'Transmit rate (mbps)', ':', true) || util.getValue(lines, 'Transmission (mbit/s)', ':', true) || util.getValue(lines, 'Übertragungsrate (MBit/s)', ':', true) || null;
if (model && id && ssid && bssid) {
result.push({
id,
iface,
model,
ssid,
bssid,
channel: util.toInt(channel),
frequency: channel ? wifiFrequencyFromChannel(channel) : null,
type,
security,
signalLevel,
txRate
});
}
}
});
if (callback) {
callback(result);
}
resolve(result);
});
} else {
if (callback) {
callback(result);
}
resolve(result);
}
});
});
}
exports.wifiConnections = wifiConnections;
function wifiInterfaces(callback) {
return new Promise((resolve) => {
process.nextTick(() => {
const result = [];
if (_linux) {
const ifaces = ifaceListLinux();
ifaces.forEach(ifaceDetail => {
const nmiDetails = nmiDeviceLinux(ifaceDetail.iface);
result.push({
id: ifaceDetail.id,
iface: ifaceDetail.iface,
name: ifaceDetail.name,
model: nmiDetails.product,
vendor: nmiDetails.vendor,
mac: ifaceDetail.mac,
});
});
if (callback) {
callback(result);
}
resolve(result);
} else if (_darwin) {
let cmd = 'system_profiler SPNetworkDataType';
exec(cmd, function (error, stdout) {
const parts1 = stdout.toString().split('\n\n Wi-Fi:\n\n');
if (parts1.length > 1) {
const lines = parts1[1].split('\n\n')[0].split('\n');
const iface = util.getValue(lines, 'BSD Device Name', ':', true);
const mac = util.getValue(lines, 'MAC Address', ':', true);
const model = util.getValue(lines, 'hardware', ':', true);
result.push({
id: 'Wi-Fi',
iface,
model,
vendor: '',
mac
});
}
if (callback) {
callback(result);
}
resolve(result);
});
} else if (_windows) {
let cmd = 'netsh wlan show interfaces';
exec(cmd, util.execOptsWin, function (error, stdout) {
const parts = stdout.toString().split(':\r\n\r\n');
parts.shift();
parts.forEach(part => {
const lines = part.split('\r\n');
if (lines.length >= 5) {
const iface = lines[0].indexOf(':') >= 0 ? lines[0].split(':')[1].trim() : '';
const model = lines[1].indexOf(':') >= 0 ? lines[1].split(':')[1].trim() : '';
const id = lines[2].indexOf(':') >= 0 ? lines[2].split(':')[1].trim() : '';
const mac = lines[3].indexOf(':') >= 0 ? lines[3].split(':')[1].trim() : '';
const vendor = getVendor(model);
if (iface && model && id && mac) {
result.push({
id,
iface,
model,
vendor,
mac,
});
}
}
});
if (callback) {
callback(result);
}
resolve(result);
});
} else {
if (callback) {
callback(result);
}
resolve(result);
}
});
});
}
exports.wifiInterfaces = wifiInterfaces;

View File

@ -38,6 +38,8 @@ function test(f) {
else if (f === 'v') { si.versions().then(data => { if (data !== null) { resolve({ data, title: 'Versions' }); } else { resolve('not_supported'); } }); }
else if (f === 'V') { si.vboxInfo().then(data => { if (data !== null) { resolve({ data, title: 'Virtual Box' }); } else { resolve('not_supported'); } }); }
else if (f === 'w') { si.wifiNetworks().then(data => { if (data !== null) { resolve({ data, title: 'WIFI Networks' }); } else { resolve('not_supported'); } }); }
else if (f === 'W') { si.wifiInterfaces().then(data => { if (data !== null) { resolve({ data, title: 'WIFI Interfaces' }); } else { resolve('not_supported'); } }); }
else if (f === 'x') { si.wifiConnections().then(data => { if (data !== null) { resolve({ data, title: 'WIFI Connections' }); } else { resolve('not_supported'); } }); }
else if (f === 'y') { si.system().then(data => { if (data !== null) { resolve({ data, title: 'System' }); } else { resolve('not_supported'); } }); }
else if (f === 'Y') { si.battery().then(data => { if (data !== null) { resolve({ data, title: 'Battery' }); } else { resolve('not_supported'); } }); }
else if (f === 'z') { si.users().then(data => { if (data !== null) { resolve({ data, title: 'Users' }); } else { resolve('not_supported'); } }); }

View File

@ -16,8 +16,8 @@ function printHeader() {
function printMenu() {
console.log('');
console.log('┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐');
console.log('│ a ... Audio h ... Bluetooth s ... Services ? ... Get Object │');
console.log('│ b ... BIOS i ... INET Latency S ... Shell , ... All Static │');
console.log('│ a ... Audio h ... Bluetooth s ... Services Y ... Battery ? ... Get Object │');
console.log('│ b ... BIOS i ... INET Latency S ... Shell z ... Users , ... All Static │');
console.log('│ B ... Baseboard I ... INET Check Site t ... time 1 ... NET Iface Default . ... All Dynamic │');
console.log('│ C ... Chassis j ... CPU Current Speed T ... CPU Temperature 2 ... NET Gateway Default / ... All │');
console.log('│ c ... CPU l ... CPU Current Load u ... USB 3 ... NET Interfaces │');
@ -25,10 +25,11 @@ function printMenu() {
console.log('│ D ... DiskIO m ... Memory v ... Versions 5 ... NET Connections │');
console.log('│ e ... Block Devices M ... MEM Layout V ... Virtual Box 6 ... Docker Info │');
console.log('│ E ... Open Files o ... OS Info w ... WIFI networks 7 ... Docker Container │');
console.log('│ f ... FS Size p ... Processes y ... System 8 ... Docker Cont Stats │');
console.log('│ F ... FS Stats P ... Process Load Y ... Battery 9 ... Docker Cont Proc │');
console.log('│ g ... Graphics r ... Printer z ... Users 0 ... Docker All q >>> QUIT │');
console.log('│ f ... FS Size p ... Processes W ... WIFI interfaces 8 ... Docker Cont Stats │');
console.log('│ F ... FS Stats P ... Process Load x ... WIFI connections 9 ... Docker Cont Proc │');
console.log('│ g ... Graphics r ... Printer y ... System 0 ... Docker All q >>> QUIT │');
console.log('└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘');
}
function EnableUserInput() {
@ -75,6 +76,7 @@ process.stdin.on('keypress', (key, data) => {
if (!waiting) {
waiting = true;
console.time(['Time to complete']);
startDots();
const siPath = path.join(__dirname, 'si.js');
exec(`node ${siPath} '${key}'`, { timeout: 30000 }, (error, stdout) => {
@ -89,9 +91,11 @@ process.stdin.on('keypress', (key, data) => {
try {
if (stdout.toString().startsWith('"no_key')) {
console.log();
console.timeEnd(['Time to complete']);
console.log('Menu item not found. Please select valid menu item ... Press q to quit');
} else if (stdout.toString().startsWith('"not_supported')) {
console.log();
console.timeEnd(['Time to complete']);
console.log('Key: ' + key);
console.log('Not supported');
} else if (stdout.toString()) {
@ -99,6 +103,7 @@ process.stdin.on('keypress', (key, data) => {
console.log();
printTitle(data.title);
console.log(util.inspect(data.data, { colors: true, depth: 4 }));
console.timeEnd(['Time to complete']);
printMenu();
}
} catch (e) {
@ -107,6 +112,7 @@ process.stdin.on('keypress', (key, data) => {
console.log('ERROR');
console.log('----------------------------------------------------------------------------------------------------');
console.log(stdout.toString());
console.timeEnd(['Time to complete']);
console.log();
}
}