I'm am on an embedded system which has an implemented webserver and a ftp-server.
Both servers are handled by a RTOS and I cannot change server-side code at the time.
I need to access and download text-files programmatically over the ftp-server from my website.
So far I am dynamically creating an ftp-link and open it inside a new window, which only shows me the text-content of the requested file.
Now I want to download this text content for serveral files I am about to open in a loop:
Open window - download textcontent - Close window
... Open Window ... and so on.
I cannot "inject" Javascript for the new window, to make it download it content if Im right?
I open the window with
window.open('ftp://username:passwort#myfilename.txt')
from a script running on my webpage.
Is there any possibility to access and download that text content as described?
At the time I do not have the possibility to access the textfiles other than ftp, since the webserver and ftpserver are not on the same filesystem and I can not change the code on the serverside.
Now I know this is kind of hacky... yet I need a workaround for now to access the textfiles.
Thank you in advance!
If you're using node you can try node-ftp
Here's a quick example of how to use:
var Client = require('ftp');
var c = new Client();
c.on('ready', function() {
c.get('foo.txt', function(err, stream) {
if (err) throw err;
console.log(stream);
stream.once('close', function() { c.end(); });
});
});
// connect to localhost:21 as anonymous
c.connect();
Related
I am trying to make a button open an exe file in computer but it doesn't open and it gives me this error
Uncaught ReferenceError: require is not defined
at runExe (main.js:61)
at HTMLButtonElement.onclick
here is the code for my button
<button onclick="runExe()" id="button">click</button>
and i got this code form the internet and when i remove the function runExe() the exe file opens when i start the app and i want it to only open when button is clicked.
here is the code to open the exe file
function runExe(){
var child = require('child_process').execFile;
var executablePath = "winRAR.exe";
child(executablePath, function(err, data) {
if(err){
console.error(err);
return;
}
console.log(data.toString());
});}
The error message says you cannot use require.
You are trying to run that code in the renderer process. If the distinction between main and renderer is new, see https://www.electronjs.org/docs/tutorial/application-architecture#main-and-renderer-processes
One way to do what you want is to instead have the rendered process send the open request to the main process, where the require will work, and where opening a child process should work.
BTW, I don't know if shell.openItem() (https://www.electronjs.org/docs/api/shell) can be used to start any exe? If so, that might be the better way to do it.
I'm trying to trigger some sort of Folder Selection Dialog, I have a working model with nodejs and the powershell but it only works when the server and client are on the same machine. I need the prompt to occur on the client side triggered from the browser. From what i understand I can not trigger Powershell from Chrome? So is there an alternative or am i just screwed?
My current Powershell script
{
param([string]$Description="Select Folder",[string]$RootFolder="Desktop")
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") |
Out-Null
$objForm = New-Object System.Windows.Forms.FolderBrowserDialog
$objForm.Rootfolder = $RootFolder
$objForm.Description = $Description
$Show = $objForm.ShowDialog()
If ($Show -eq "OK")
{
Return $objForm.SelectedPath
}
Else
{
Write-Error "Operation cancelled by user."
}
}
$folder = Select-FolderDialog # the variable contains user folder selection
write-host $folder
My javascript function
async function asyncfindDir() {
//executes powershell script
let promise = new Promise((resolve, reject) => {
const Shell = require('node-powershell');
const ps = new Shell({
executionPolicy: 'Bypass',
noProfile: true
});
ps.addCommand('./selectfolder.ps1');
ps.invoke()
.then(output => {
//console.log(output);
var shelloutput = output;
console.log (shelloutput + '^^from external script');
res.send(shelloutput);
})
.catch(err => {
console.log('please select a directory path')
//console.log('err');
});
});
};
Is there anyway to get that working locally?
Is there a trigger i'm not aware of to access that kind of dialog from the browser? I know i'm not the only person with this issue but i have yet to see a real solution.
Short answer: No.
Longer answer, is best illustrated by rephrasing your question with a different script name:
Using my browser, can I click on a link to visit a website, and have it run a random
PowerShell script called Delete_All_Files.ps1?
Answers why you will never be able to run a PowerShell script from a browser, on a remote machine, and why browsers will deliberately block you from doing it, because people usually don't want to have all their files deleted when they click on a random link in their email.
If you want to run PowerShell scripts on remote machines, then you should look into PSRemoting and Enter-PSSession.
#kuzimoto is right. If you just want to display a folder dialog box, there are easier ways to do that and Fine Uploader is an easier way.
Replying to your comment: If you want to specify a directory name, the reason you can't do it is because you are essentially asking:
Using my browser, can I click on a link to visit a website, and have
it run a script that will enumerate through all the files and folders
in my C:\ so that it can choose the folder C:\users\Justin
Miller\Desktop\SECRET FILES\?
The reason both operations do not work is because both operations require local computer access. i.e. local script execution access, and local directory knowledge access. Security-wize, we, in general, don't want to visit a random website and have it execute random code, or know what files/folders I have on my machine, which is why you won't be able to do what you want to try to do.
I have a Meteor application where I'm downloading files from S3 using pre-signed URLs (need to be generated with an API call).
I was having an issue with popup blockers preventing a new tab from opening with the url generated by the AWS-SDK so I changed my code to the following:
downloadDocument(document, event) {
// open tab immediately to prevent popup blocker
const myNewTab = window.open();
// call method to generate url
Meteor.call('Events.Methods.Document.Download', { key: document.key, eventId: event._id }, (error, res) => {
if (error) { ... } // removed handle error code
// if url generated, set tab location to url
if (res) myNewTab.location.href = res;
// auto close the tab after 1 second
myNewTab.setTimeout(() => { myNewTab.close(); }, 1000);
});
}
This code is working for the most part but it doesn't feel very clean. Also if the API call ever takes more than 1 second (slow internet) then the tab will close before the download begins
How can I change this so that I can wait for the download to happen, before closing the tab? Or a similar solution that would result in me ensuring the downloads always go through without popup blockers being an issue?
Thanks
You are always going to run afoul of pop-up blockers if you open a new window.
What you should do is generate an <a href="my-custom-server-generated-url" download> link with the download property, which will force a download without needing a new window.
Then you also don't need to close the window on a timer (which wasn't a good approach in the first place)
This was happening only in Safari, so we switched to always downloading the file instead of opening in a new window in Safari/mobile.
I would like to automate the process of visiting a website, clicking a button, and saving the file. The only way to download the file on this site is to click a button. You can't navigate to the file using a url.
I have been trying to use phantomjs and casperjs to automate this process, but haven't had any success.
I recently tried to use brandon's solution here
Grab the resource contents in CasperJS or PhantomJS
Here is my code for that
var fs = require('fs');
var cache = require('./cache');
var mimetype = require('./mimetype');
var casper = require('casper').create();
casper.start('http://www.example.com/page_with_download_button', function() {
});
casper.then(function() {
this.click('#download_button');
});
casper.on('resource.received', function (resource) {
"use strict";
for(i=0;i < resource.headers.length; i++){
if(resource.headers[i]["name"] == "Content-Type" && resource.headers[i]["value"] == "text/csv; charset-UTF-8;"){
cache.includeResource(resource);
}
}
});
casper.on('load.finished', function(status) {
for(i=0; i< cache.cachedResources.length; i++){
var file = cache.cachedResources[i].cacheFileNoPath;
var ext = mimetype.ext[cache.cachedResources[index].mimetype];
var finalFile = file.replace("."+cache.cacheExtension,"."+ext);
fs.write('downloads/'+finalFile,cache.cachedResources[i].getContents(),'b');
}
});
casper.run();
I think the problem could be caused by my cachePath being incorrect in cache.js
exports.cachePath = 'C:/Users/username/AppData/Local/Ofi Labs/PhantomJS';
Should I be using something in adition to the backslashes to define the path?
When I try
casperjs --disk-cache=true export_script.js
Nothing is downloaded. After a little debugging I have found that cache.cachedResources is always empty.
I would also be open to solutions outside of phantomjs/casperjs.
UPDATE
I am not longer trying to accomplish this with CasperJS/PhantomJS.
I am using the chrome extension Tampermonkey suggested by dandavis.
Tampermonkey was extremely easy to figure out.
I installed Tampermonkey, navigated to the page with the download link, and then clicked New Script under tampermonkey and added my javascript code.
document.getElementById("download_button").click();
Now every time I navigate to the page in my browser, the file is downloaded. I then created a batch script that looks like this
set date=%DATE:~10,4%_%DATE:~4,2%_%DATE:~7,2%
chrome "http://www.example.com/page-with-dl-button"
timeout 10
move "C:\Users\user\Downloads\export.csv" "C:\path\to\dir\export_%date%.csv"
I set that batch script to run nightly using the windows task scheduler.
Success!
Your button most likely issues a POST request to the server.
In order to track it:
Open Network tab in Chrome developer tools
Navigate to the page and hit the button.
Notice which request led to file download. Right click on it and copy as cURL
Run copied cURL
Once you have cURL working you can schedule downloads using cron or Task Scheduler depending on operation system you are using.
I am currently building a win-store app for a client, and I can't seem to figure out how to link to another app from within my current app.
I have seen plenty of documentation on how to open the default application from a URI or file type but nothing on opening a specific app.
Currently I am able to open my app with the function below, after adding a protocol to the declarations in my package.appxmanifest, but this isn't the preferred solution since this will not cause the app to open in full screen.
function openApp() {
var options = new Windows.System.LauncherOptions();
options.preferredApplicationPackageFamilyName = "packageFamilyName";
options.preferredApplicationDisplayName = "App Display Name";
var uri = new Windows.Foundation.Uri("linktomyapphere:");
Windows.System.Launcher.launchUriAsync(uri).then(
function (e) {},
function (err) {
console.log(err);
});
}
The best way is definitely URL activation (aka protocol activation). If you own the other app, you register a protocol for it - something like myapp://. That is done in the manifest. Then you follow the instructions on this page to activate that from your app. You can even pass URL parameters so you can pass some state in during activation.