Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows, international character sets, powerShell, wmic #616

Open
sebhildebrandt opened this issue Nov 11, 2021 · 12 comments
Open

Windows, international character sets, powerShell, wmic #616

sebhildebrandt opened this issue Nov 11, 2021 · 12 comments

Comments

@sebhildebrandt
Copy link
Owner

sebhildebrandt commented Nov 11, 2021

We have the following situation on windows machines, where tickets #520, #600, #610, #611, #613, #646, #650 are related to:

  • wmic (one of the methods, how this package gained system information) was marked as depricated for some time now. Windows 11 now completely dropped wmic support. But fortunately there are alternatives.

  • due to problems with international character sets we anyway needed to drop wmic and move to the corresponding PowerShell commands. I started this transition with verion 5.9.7.

  • Since version 5.9.10 wmic is no longer used and all commands now use PowerShell.

I used powerShell in systeminformation since verion 3 but did not see any problems so far. But it seems that there are some drawbacks:

  1. PowerShell commands are slightly slower. In some cases (e.g users, I now need to make three calls instead of one).
  2. it seems, that in some cases PowerShell does not clear up completely after giving back the results to nodeJS. I was not able to reproduce it till now so this is under investigation.
  3. Spinning up a PowerShell instance from node.js takes quite a few resources (time and CPU)
  4. You need to have Powershell Version 5+ on your machine to have correct international characters - which should be installed on Windows 10, 11. When you use Window 8.1 or lower there might be an older version of PowerShell installed,

As now all commands are rewritten using PowerShell instead of WMIC I made some improvements to tackle some of the problems above (time and CPU consumption). To only spin up a PowerShell instance once, I have created the possibility to enable the persistent power shell:

  • on startup of your code (if you are running in windows): si.powerShellStart();
  • and then again when shutting down the app: si.powerShellRelease();

This improves speed and CPU consumption drastically and removes the problem of cleaning up after each powerShell call.

@si458
Copy link
Contributor

si458 commented Nov 16, 2021

@sebhildebrandt have you tried calling exec with powershell set as the shell?
rather then calling powershell.exe then the command?
https://stackoverflow.com/questions/10179114/execute-powershell-script-from-node-js
https://stackoverflow.com/a/61219838/1210734

@sebhildebrandt
Copy link
Owner Author

@si458 Thank you, currently making several tests to that. There are some possibilities that I am thinking of. Now testing which ones are faster ...

@sebhildebrandt
Copy link
Owner Author

I made detailed research and it turns out that spinning up PowerShell Process is responsible for consuming a lot of resources and time. I now created a possibility to create a persistent PowerShell which then should reduce resources by 90% ...

It would be great if you can test the latest code here on GitHub: What you have to do to enable the persistent power shell:

  • on startup (if you are running in windows): si.powerShellStart();
  • and then again when shutting down the app: si.powerShellRelease();

All commands In between will then use this already pinned up powerShell.

The implementation ist still a little hacky ... but if your results are fine and this is what you would like to use, I will make a clean up! Any comments are welcome!

@si458
Copy link
Contributor

si458 commented Jan 14, 2022

Hi @sebhildebrandt
ive restarted my little project i was doing using systeminformation, a few issues if i may?

the is no documentation about si.powerShellStart(); and si.powerShellRelease(); anywhere in the README.md or on the website, can you maybe add some?

if i use the powerShellStart all powershell commands run in the one powershell instance as expected rather than opening 20instances of powershell (each at 64mb),
HOWEVER, getStaticData isnt working with powerShellStart for some reason?

Ive managed to narrow down the getStaticData issue with powerShellStart however through,

if i replace the osInfo.uuid() line 90 from index.js with say a string "notworking" then the command returns everything!

but whats even weirder,
if i call getStaticData with uuid replace with again say "notworking",
THEN call abc.uuid = await si.get({uuid:'*'}) or abc.uuid = await si.uuid()
the uuid is returned no problem?

any help would be amazing!?

SAMPLE CODE BELOW:

const si = require('systeminformation');
(async () => {
    si.powerShellStart()
    try {
        const abc = await si.getStaticData();
        // abc.uuid = await si.uuid() // uncomment after changing the index.js in systeminformation
        console.log(abc);
    } catch (e) {
        console.error('ERROR');
        process.exit(1);
    }
    si.powerShellRelease();
})();

@sebhildebrandt
Copy link
Owner Author

@si458 as I am still try to improve the situation, I did not made any official documentation about powerShellStart() and powerShellRelease(). Hope that I can improve this soon.

Concerning your findings with si.uuid() I need to make a little research. Please give me some time for that.

@si458
Copy link
Contributor

si458 commented Jan 14, 2022

@sebhildebrandt glad i could help, any testing let me know 👍
the current implemation of powerShellStart() and powerShellRelease() seems to work a treat so far,
its just weird the uuid is having issues with getStaticData ?

@si458
Copy link
Contributor

si458 commented Jan 14, 2022

@sebhildebrandt narrowed the issue abit for you,

util.powerShell('Get-WmiObject Win32_ComputerSystemProduct | fl *').then((stdout) => {
// let lines = stdout.split('\r\n').filter(line => line.trim() !== '').filter((line, idx) => idx > 0)[0].trim().split(/\s\s+/);
let lines = stdout.split('\r\n');
result.hardware = util.getValue(lines, 'uuid', ':').toLowerCase();
if (callback) {
callback(result);
}
resolve(result);
});

the resolve isnt being returned from inside this function (or rather it is but the powershell is stopping it for some reason?)
if you comment out L1138-L1146 (LEAVE resolve(result); L1145 uncommented) it returns no problems

EDIT:
also util.powerShell is itself a promise, is it maybe a double promise issue?

@si458
Copy link
Contributor

si458 commented Jan 14, 2022

@sebhildebrandt fixed it! found the issue! submit patch soon...
EDIT: patch #639

@stalkercn
Copy link

after powershell is updated to 7.3.0, almost all methods return empty value now, I guess Wmi-Object command is officially deprecated at this version, and it should be replaced with Get-CimInstance?

@sebhildebrandt
Copy link
Owner Author

@stalkercn ... i replaced it here on master in GitHub. Can you pull the current master ant test if this works for all functions now on windows?

@sebhildebrandt
Copy link
Owner Author

sebhildebrandt commented Nov 11, 2022

@stalkercn ... and just to be sure, this would then work also with older versions of powershell?

Ok after making so research starting in PowerShell 3.0, get-wmiobject has been superseded by Get-CimInstance so we should be fine with older versions ... only Windows versions which still uses PowerShell 2.0 could have a problem here ...

Version 5.12.14 just released where all get-WmiObject calls are replaced by Get-CimInstance

@stalkercn
Copy link

@sebhildebrandt I updated si to v5.12.14, but still got empty values, it's odd.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants