I used the child-process module of node.js.
And i registered node binary exe file with windows service.
Powershell and folderbrowserdialog are used as child-process.
However, it seems to end at the same time as the child-process starts.
Below is my code
const spawn = require('cross-spawn')
const child = spawn("cmd.exe",["/c","powershell.exe","ps\\ps.ps1"])
console.log('path')
child.stdout.on("data",function(data){
path = data.toString()
});
child.on("exit",function(){
res.send(path)
});
child.stdin.end();
This code does not work only when running as a window service.
res.send(path) is alwayse empty("")
my ps code is.
Function Get-Folder($initialDirectory="")
{
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms")|Out-Null
$foldername = New-Object System.Windows.Forms.FolderBrowserDialog
$foldername.rootfolder = "MyComputer"
$foldername.Description = "slect folder"
$foldername.SelectedPath = $initialDirectory
$caller = [System.Windows.Forms.NativeWindow]::new()
$caller.AssignHandle([System.Diagnostics.Process]::GetCurrentProcess().MainWindowHandle)
if($foldername.ShowDialog($caller) -eq [Windows.Forms.DialogResult]::"OK")
{
$folder += $foldername.SelectedPath
}else{
$folder = "D:\\"
}
return $folder
}
Get-Folder
Related
I have an app that is compiled in automator for MacOS.
it executes a javascript and then shell script. It is a bit slow though to execute and i noticed that apps compiled in script editor instead are faster to execute. how do i make an app in script that executes this javascript and shell script ?
#!/usr/bin/env osascript -l JavaScript
function run(input) {
const app = Application.currentApplication();
app.includeStandardAdditions = true;
const obsidianJsonFilePath = app.pathTo("home folder") + "/Library/Application Support/obsidian/obsidian.json";
const vaults = JSON.parse(app.read(obsidianJsonFilePath)).vaults;
let openInObsi = false;
const pathArray = input.toString().split(",");
const toOpen = [];
pathArray.forEach(filePath => {
const isFileInObsidianVault = Object.values(vaults).some(v => filePath.startsWith(v.path));
if (isFileInObsidianVault && !filePath.includes("/.")) { // second condition prevents the opening of files in .obsidian or .trash
toOpen.push("obsidian://open?path=" + encodeURIComponent(filePath));
openInObsi = true;
}
else toOpen.push(filePath);
});
return [openInObsi.toString(), ...toOpen];
}
Shell Script
if $1 ; then
open "$2"
else
open -a "Obsidian" "${#:2}"
fi
Didn't tried anything, because I am not familiar with this code.
I like to write a Thunderbird AddOn that encrypts stuff. For this, I already extracted all data from the compose window. Now I have to save this into files and run a local executable for encryption. But I found no way to save the files and execute an executable on the local machine. How can I do that?
I found the File and Directory Entries API documentation, but it seems to not work. I always get undefined while trying to get the object with this code:
var filesystem = FileSystemEntry.filesystem;
console.log(filesystem); // --> undefined
At least, is there a working AddOn that I can examine to find out how this is working and maybe what permissions I have to request in the manifest.json?
NOTE: Must work cross-platform (Windows and Linux).
The answer is, that WebExtensions are currently not able to execute local files. Also, saving to some local folder on the disk is also not possible.
Instead, you need to add some WebExtension Experiment to your project and there use the legacy APIs. There you can use the IOUtils and FileUtils extensions to reach your goal:
Execute a file:
In your background JS file:
var ret = await browser.experiment.execute("/usr/bin/executable", [ "-v" ]);
In the experiment you can execute like this:
var { ExtensionCommon } = ChromeUtils.import("resource://gre/modules/ExtensionCommon.jsm");
var { FileUtils } = ChromeUtils.import("resource://gre/modules/FileUtils.jsm");
var { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyGlobalGetters(this, ["IOUtils");
async execute(executable, arrParams) {
var fileExists = await IOUtils.exists(executable);
if (!fileExists) {
Services.wm.getMostRecentWindow("mail:3pane")
.alert("Executable [" + executable + "] not found!");
return false;
}
var progPath = new FileUtils.File(executable);
let process = Cc["#mozilla.org/process/util;1"].createInstance(Ci.nsIProcess);
process.init(progPath);
process.startHidden = false;
process.noShell = true;
process.run(true, arrParams, arrParams.length);
return true;
},
Save an attachment to disk:
In your backround JS file you can do like this:
var f = messenger.compose.getAttachmentFile(attachment.id)
var blob = await f.arrayBuffer();
var t = await browser.experiment.writeFileBinary(tempFile, blob);
In the experiment you can then write the file like this:
async writeFileBinary(filename, data) {
// first we need to convert the arrayBuffer to some Uint8Array
var uint8 = new Uint8Array(data);
uint8.reduce((binary, uint8) => binary + uint8.toString(2), "");
// then we can save it
var ret = await IOUtils.write(filename, uint8);
return ret;
},
IOUtils documentation:
https://searchfox.org/mozilla-central/source/dom/chrome-webidl/IOUtils.webidl
FileUtils documentation:
https://searchfox.org/mozilla-central/source/toolkit/modules/FileUtils.jsm
noobie here..
In the course of making an electron app,
I have used electron-process package to make electron run in the background(even when all windows are closed). I noticed that, when the electron app was relaunched, the background process of the previous launch of the app remained, and this made background processes pile up with increase in the number of relaunches of the app (If the app was launched 10 times, I would have 10 background processes of the app).. Then I decided to terminate the background process of the previous launch, when I made the next launch.. I have made an attempt to do the same, which is shown below. I noticed that, the app was launched and almost instantly, the app was terminated(which I figured it out to be, the process termination part of the code being exectued later than the part which created the window and started the app. Hence terminating the current process only, instead of the process of the previous launch of the app).. Please help me in making this code run sequentially.. All comments, suggestions, explainations, advices are warmly welcomed. Thanks in advance..
'use strict';
const electron = require('electron');
const main = require('electron-process').main;
const app = electron.app; // Module to control application life.
const BrowserWindow = electron.BrowserWindow; // Module to create native browser window.
const exec = require('child_process').exec;
const exec1 = require('child_process').exec;
const fs = require('fs');
let mainWindow = null;
let mainWindow1 = null;
app.on('ready', function() {
var pidrun;
var killtask;
var read;
if(process.platform == 'win32'){
exec('tasklist /v /fo csv | findstr /i "electron.exe"', (error, stdout, stderr) => {
if (error){
console.error(`exec error: ${error}`);
return;
}
pidrun = stdout[16]+stdout[17]+stdout[18]+stdout[19];
killtask = "Taskkill /FI \"PID eq "+pidrun+"\" /F";
exec(killtask, (error, stdout, stderr) => {
if (error) {
console.error('exec error: ${error}');
return;
}
if(stdout == "INFO: No tasks running with the specified criteria."){
return;
}
});
});
}
const backgroundhtml = 'file://' + __dirname + '/background.html';
const backgroundProcessHandler = main.createBackgroundProcess(backgroundhtml);
mainWindow = new BrowserWindow({width: 1280, height: 600});
backgroundProcessHandler.addWindow(mainWindow);
mainWindow.loadURL('file://'+__dirname+'/foreground2.html');
mainWindow.loadURL('file://' + __dirname + '/foreground.html');
mainWindow.webContents.openDevTools()
});
Sounds to me like you want only a single instance of your app running at any time, Electron provides app.makeSingleInstance specifically for that purpose.
I have read about Fabrice Bellard's linux simulation in browser.
How does Linux emulator in Javascript by Fabrice Bellard work?
Today I stumbled upon this site, where they are simulating full linux terminal in browser, I am able to run python, perl etc. I know they are running their site on node.js, but I couldn't figure out how they exactly simulating the terminal.
http://runnable.com/UWRl3KlLuONCAACG/read-files-from-filesystem-in-python
The full linux is http://docker.io, the rest is https://github.com/Runnable/dockworker
We're not simulating the terminal but as Kyle says, replicating the terminal over websockets (with an ajax fallback).
In the browser we're using https://github.com/chjj/term.js which was derived from Fabrice Bellard's emulator. It handles the output, and also the keystroke capture.
Let me prefix this by saying it is NOT a good idea to do this.
But, You can spawn a shell and use web-sockets or XMLHttpRequests to push keypresses to the spawned server process. Here's a working example of one that runs on windows. Unfortunately, I didn't get around to hooking up / figuring out Ctrl+c. But, you should get the gist of it.
require("underscore");
var Server = {},
express = require("express"),
path = require("path"),
sys = require("sys"),
application_root = __dirname;
global.Server = Server;
Server.root = application_root;
global.app = express();
Server.setup = require("./lib/setup.js").setup({
//redis: require("./lib/redis-client").createClient(),
app: app,
//mongoose : require("mongoose"),
io : require("socket.io"),
express : express,
port: 1773,
paths : {
views : path.join(application_root,"app","views"),
root : path.join(application_root,"public"),
controllers : path.join(application_root,"app","controllers"),
models : path.join(application_root,"app","models")
}
});
var proc = require('child_process'),
cmd;
app.socket.on('connection', function(socket) {
if (!cmd) {
//console.log('spawning cmd');
cmd = proc.spawn('cmd');
//console.log(cmd?'CMD started':'CMD not started');
if (cmd.stdout) {
//console.log('stdout present');
cmd.stdout.on('data',function(data) {
if (data) {
//console.log("data: "+data);
socket.emit('cmd', ""+data);
}
});
}
if (cmd.stderr) {
cmd.stderr.on('data', function(data) {
//console.log('stderr present');
if (data) {
socket.emit('cmd', ""+data);
}
});
}
cmd.on('exit', function() {
//console.log('cmd exited');
socket.emit('cmd', '[CMD Shutdown]');
if (cmd) {
cmd.kill();
cmd = null;
}
});
}
socket.on('sendCmd', function(data) {
if (data && data.buffer) {
var kB = data.buffer.replace("\r","\n");
if (cmd && cmd.stdin) {
cmd.stdin.write(kB);
}
}
});
socket.on('disconnect', function() {
console.log('connection closed');
if (cmd) {
cmd.stdin.end(); //.kill();
if (cmd) {
cmd.kill();
cmd = null;
}
}
});
});
Edit: Actually, this is a portion of a working example. It's missing the client side where you capture and send the keystrokes to the server. But, it should give you the general idea.
Here is the code I have so far...
// Run the external encryption process
var fileExe = Components.classes["#mozilla.org/file/local;1"]
.createInstance(Components.interfaces.nsILocalFile);
fileExe.initWithPath("~/tmp/Encrypt.jar");
var process = Components.classes["#mozilla.org/process/util;1"]
.createInstance(Components.interfaces.nsIProcess);
process.init(fileExe);
var args = ["java -jar Encrypt.jar -e toEncrypt"];
process.run(true, args, args.length);
document.getElementById('hello-world-status-bar-icon').label = "DONE";
This currently does not work. Any suggestions??
EDIT
I've also tried..
// Run the external encryption process
var fileExe = Components.classes["#mozilla.org/file/local;1"]
.createInstance(Components.interfaces.nsILocalFile);
fileExe.initWithPath("java");
var process = Components.classes["#mozilla.org/process/util;1"]
.createInstance(Components.interfaces.nsIProcess);
process.init(fileExe);
var args = new Array();
args[0] = " -jar";
args[1] = "~/tmp/Encrypt.jar";
args[2] = "-e";
args[3] = "toEncrypt";
process.run(true, args, args.length);
document.getElementById('hello-world-status-bar-icon').label = "DONE";
Thanks,
Pat
I think you need to init the process with a reference to the local file that is the "java" executable. That's what needs to be executed at the system level. The arguments need to be passed as an array of individual strings, not a single string.