How to Run an External jar file from within a firefox extension - javascript

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.

Related

How to execute / access local file from Thunderbird WebExtension?

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

node.js child process doesn't work in window service

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

Batch-file command (net user and findstr) with output convert to javascript

I write a HTA File with javascript to display some userinformation.
How can I run windows cmd commands (like in a batch file) and get the output in a variable.
What I need in Javascript syntax
batch-file code
net user %username% /domain | findstr /c:"password expires"
so that I have this in a variable in javascript function.
Same like this:
function username()
{
var wshshell=new ActiveXObject("wscript.shell");
var username=wshshell.ExpandEnvironmentStrings("%username%");
return username
}
function ipAddress() {
var ipAddress = "";
var wmi = GetObject("winmgmts:{impersonationLevel=impersonate}");
e = new Enumerator(wmi.ExecQuery("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = True"));
for(; !e.atEnd(); e.moveNext()) {
var s = e.item();
ipAddress = s.IPAddress(0);
}
return ipAddress
}
You can use WScript.shell object. It allows you to execute shell commands.
var objShell = new ActiveXObject("WScript.shell");
It has run method.
https://learn.microsoft.com/en-us/previous-versions/windows/desktop/legacy/bb776890(v=vs.85)

Get output on shell execute in js with ActiveXObject

i tried to get exe file callback result when i doing shell execute like this:
var oShell = new ActiveXObject("WScript.Shell");
var args = folderName + "\\dir\\scan.exe scan " + params.join(" ");
var ret = oShell.Run(args ,0 ,true);
but ret gaves me 0 for fail and 1 for success.
when i run the file in the cmd like this:
scan.exe arg1 arg2 arg3
this is return the correct result that i wanted : "test/test" and not 1...
what can i do?
tnx a lot
I know I might be a bit late to answer this question but I hope it can still help someone.
The way I achieved it was with the oShell.Exec() function and not with the oShell.Run().
oShell.Exec() returns an object with a property called StdOut which acts like a text file, so you can perform ReadLine(), ReadAll(), etc.
The problem is that it does not wait for the command to end, so when you run your code, it is very likely that your StdOut object will be undefined. You have to add that waiting option on the command itself.
var wshShell = new ActiveXObject("WScript.Shell");
try {
// Excecute the 'cd' command.
wshShell.CurrentDirectory = "C:\\Users";
var execOut = wshShell.Exec('cmd /C start /wait /b cd');
}
catch (e) {
console.log(e);
}
// Get command execution output.
var cmdStdOut = execOut.StdOut;
var line = cmdStdOut.ReadLine();
console.log(line);
The code above will execute a cd command on the directory C:\Users and store the output on the line variable.
I hope this answers the question.
Using a shell to receive output from BATCH file:
script.js
var pathToFile = "your_path_here"
var shell= new ActiveXObject("WScript.shell");
var output = shell.Exec(pathToFile + 'example.bat');
var response = output.StdOut.ReadLine();
console.log(response)
example.bat
#ECHO OFF
echo Hello From Batch World
exit 0

How can I send quit command to current ffmpeg.exe

var fpath="C:\\TVT_"+cur_date+"_"+cur_time+".avi";
Components.utils.import("resource://gre/modules/FileUtils.jsm");
var env = Components.classes["#mozilla.org/process/environment;1"]
.getService(Components.interfaces.nsIEnvironment);
var shell = new FileUtils.File(env.get("COMSPEC"));
var args = ["/c", "cd.. & cd.. & C: & cd C:/ffmpeg/bin & record.bat "+fpath];
var process = Components.classes["#mozilla.org/process/util;1"]
.createInstance(Components.interfaces.nsIProcess);
process.init(shell);
process.runAsync(args, args.length);
I don't want to use taskkill.exe, /MIN, /C, /B, rather I want to quit this ffmpeg process
I read about CMDOW but did not find cmdow.exe inside system32 directory.
So how can I send quit command within the same window which is running ffmpeg process?
Using Windows XP service pack 2 with Firefox 12
Thanks..
That's not quite trivial - Firefox doesn't have any built-in functionality for that meaning that you would need to use js-ctypes for that and call Win32 API functions directly. Win32 - Get Main Wnd Handle of application describes how you would get hold of the top-level window for an application, after that you can send WM_QUIT message to it. This approach actually works:
Components.utils.import("resource://gre/modules/ctypes.jsm");
var userlib = ctypes.open("user32");
var HWND = ctypes.voidptr_t;
var UINT = ctypes.uint32_t;
var WPARAM = ctypes.uint16_t;
var LPARAM = ctypes.uint32_t;
var LRESULT = ctypes.uint32_t;
var DWORD = ctypes.uint32_t;
var WNDENUMPROC = ctypes.FunctionType(ctypes.stdcall_abi,
ctypes.bool,
[HWND, LPARAM]).ptr;
var WM_CLOSE = 0x0010;
var EnumWindows = userlib.declare(
"EnumWindows", ctypes.winapi_abi,
ctypes.bool,
WNDENUMPROC, LPARAM
);
var GetWindowThreadProcessId = userlib.declare(
"GetWindowThreadProcessId", ctypes.winapi_abi,
DWORD,
HWND, DWORD.ptr
);
var IsWindowVisible = userlib.declare(
"IsWindowVisible", ctypes.winapi_abi,
ctypes.bool,
HWND
);
var SendMessage = userlib.declare(
"SendMessageW", ctypes.winapi_abi,
LRESULT,
HWND, UINT, WPARAM, LPARAM
);
var callback = WNDENUMPROC(function(hWnd, lParam)
{
var procId = DWORD();
GetWindowThreadProcessId(hWnd, procId.address());
if (procId.value == pid && IsWindowVisible(hWnd))
SendMessage(hWnd, WM_CLOSE, 0, 0);
return true;
});
EnumWindows(callback, 0);
userlib.close();
I tested this and could successfully close a Notepad window with it (the usual warning will appear if the text hasn't been saved so it is a clean shutdown). In your case the problem might be however that you aren't running your ffmpeg directly but rather via the command line shell - so you will close the command line window which might not terminate ffmpeg. I guess you will just have to try, if it doesn't work you will probably have to look at the title of the window instead of its process ID (which is obviously a less reliable approach).

Categories