hta/ javascript How to execute an application with relative path - javascript

I'm building a .hta (with javascript) from which i want to launch several applications.
But when i execute my .hta i get the error message can't find file
this is the code:
<script type="text/javascript" language="javascript">
function RunFile(path) {
var relpath = window.location.href;
var fullpath = relpath + path;
WshShell = new ActiveXObject("WScript.Shell");
WshShell.Run(fullpath, 1, false);
}
RunFile("\file.exe");
</script>

window.location.href includes filename and protocol too. Try this:
var relpath = window.location.pathname.replace(/\\/g,'/').split('/');
relpath.pop();// JScript: relpath.length = relpath.length - 1;
relpath = relpath.join('/') + '/';
Notice use of / instead \, and it's also handy to end up relpath with /, so you don't need to add it to function argument.
EDIT
I'm not sure what you mean with getting location without file, maybe this (citation from Windows Sripting Technologies (unfortunately broken now):
"The CurrentDirectory returns a string that contains the fully qualified path of
the current working directory of the active process."
The active process is for example the running HTA, so this will give the local path of the HTA file (without filename).
currentDirectory is a property of WScript.Shell, so you can use it with WshShell in your code, also to set working directory.

Related

replace entire variable line using partially matched regex in javascript from an external file

I've two files. Lets call them first.js and second.js.
Since second.js is called by html, I cant use require. So I am trying to modify a parameter in second.js from first.js.
First is running on a node.js server. I need to replace/update ipAddress variable value from second.js every-time I run first.js
So in first.js , I am trying to use external replacemodule (any other way is ok as well).
First I open external file (second.js) from first.js, then search for
var ipaddress = "192.168.0.10"
This ip address changes everytime. So I am trying to search on var ipaddress and need to to replace it with variable ipaddr.
Here is what I have so far.
Partial contents of first.js.
function replaceIP(ipaddress){
var replace = require("replace");
replace({
regex: "^var ipAddress.*$",
replacement: "var ipAddress = " + ipaddr,
paths: ['./second.js'],
recursive: false,
silent: false,
});
}
This is not working.
If I just use hardcoded value for iPAddress , like
var ipAddress = 'XXXX';
And the replace 'XXXX'. Its working fine.
So I know it has to be with RegEx and not 'Replace' Module.
EDIT:
Also problem is second.js ipAddress variable will store different value for every login session , Hence I cant grab onto entire string since I dont know what it will be, Hence I am grabbing onto starting portion (^var ipAddress) of declaration statement.
e.g first login : var ipAddress = '192.168.0.10';
second login session: var ipAddress = '192.168.0.12';
third login session: var ipAddress = '192.168.0.18';
and so on.
Here is an example that replaces entire line in python based on partial match of string.
Can I do something like this in javascript?
Any ideas?
PS: I looked at few other Q & A on SO, and it does not seem to address the issue.
Thanks.
I was able to solve above using shell.js which offers straigt-forward unix like shell commands across platform. Really impressed with its ease of use.
I guess the key was searchPattern = /^.*var ipAddr =.*$/;
function replaceIP(ipAddr) {
var shell = require("shelljs");
var searchPattern = /^.*var ipAddr =.*$/;
var replacePattern = "var ipAddr = '" + ipAddr + "';";
var cwd = shell.pwd().stdout;
var file = cwd + '/second.js';
shell.sed('-i', searchPattern, replacePattern, file);
console.log("replacing " + ipAddr + " in file " + file);
}
Then call using,
replaceIP(ipAddr)

Access to particular URL for file reading in JS

I am trying to read a file in Java script. I am using XAMPP server, all the files are in the htdocs folder. But when I try to read a file from other directory its not working.
Error:
NS_ERROR_DOM_BAD_URI: Access to restricted URI denied
request.send(null);
JavaScript:
<!DOCTYPE html>
<html>
<body>
<textarea id="box" rows="4" cols="50"> </textarea>
<script>
//get the contents of the text file START
//Make sure in the JsonData.txt file, after each line there should not be any space ie when you click RIGHT arrow at the end of each line the cursor should go to next line beginning.
function FileHelper()
{}
{
FileHelper.readStringFromFileAtPath = function(pathOfFileToReadFrom)
{
var request = new XMLHttpRequest();
request.open("GET", pathOfFileToReadFrom, false);
request.send(null);
var returnValue = request.responseText;
return returnValue;
}
}
var pathOfFileToRead = "file://d:/sampleData.txt";
var contentsOfFileAsString = FileHelper.readStringFromFileAtPath
(
pathOfFileToRead
);
var contents_value = contentsOfFileAsString;
alert(contents_value);
document.getElementById("box").value = contents_value;
//document.getElementById("demo").innerHTML = contents_value;
//get the contents of the text file STOP
</script>
</body>
</html>
In the JS 'pathOfFileToRead=filepath' if I keep the file in the same htdocs directory its working fine, but not working if I give local directory path like I have given in the above JS.
You're using javascript running in the browser. You can't use the file:// protocol to read your file, and you can't use drive letters.
You can still do what you want to do though. You need to reference your file with an url and call it with http://. (You know the difference ?! An url has a domain name or ip address pointing to a web root, then perhaps a port number, then forward slashes separating each folder below the web root. A windows path has a drive letter, then backslashes separating each folder.)
There are tons of litte things to improve in your script. I would start with removing the pair of empty braces on line 2. Then, I don't think anyone uses xmlhttp in synchronous mode. You should really be using asynch with callbacks, and checking for success (200) before doing your business.

How to handle links in Phonegap + JQM app?

I am building an app with Phonegap and jQuerymobile. The app roughly works like this:
1) The app downloads a ZIP file from a public server and then unzips them to a local folder. I got the local folder path from fileSystem.root.toNativeURL() (in OS, it's something like this: file://var/mobile/Container/Data/Application/xxxx/Documents/)
2) App redirects to HTML that was unzipped in local folder (ex: file://var/mobile/Container/Data/Application/xxxx/Documents/index.html)
I am now facing issues b/c inside the index.html file, all the links are absolute path (ex: Link). This breaks all the links since (I assume) they are all now pointing to file://content/index2.html instead of file://var/mobile/Container/Data/Application/xxxx/Documents/content/index2.html.
My question is, how should I handle the links? I am thinking i should just rewrite all the links to force prepend the local folder URL in front of it. Is there a better way?
And if rewriting links is the way to go, how can I do this with jQuerymobile? I did this in jQuery which seems to work http://jsfiddle.net/jg4ouqc5/ but this code doesn't work in my app (jQueryMobile)
When you are loading index.html, you are getting file://some_path/..../index.html as your base URL. Any links which will be encountered now own-wards can be resolved in relation to the base URL.
You would know your scenario better. There could be multiple ways in which this can be fixed.
Have a contract with the CMS/Code generator. Links should always be generated either Relative to the base URL or Absolute. The links you are getting in the page are wrong - Link it ideally should be Link or fully qualified like https://www.google.com.
If you want to change the URL then you can use native code to change it after unzipping the content. It will be really straight forward.
If you want to change the URL in browser then you will have to persist the base url and then take care of couple of things:
a. absolute urls - In your case you can just check the window.location.protocol, if it starts with 'http' and then skip it.
b. sub-directories
Here is a small I have written:
Note: I have not tried this code and you might have to change it according to your need.
$(document).ready(function(){
var base_file_name = window.location.pathname.substring(window.location.pathname.lastIndexOf('/') + 1);
//In index.html (persist this value in native)
var baseUrl = window.location.href.replace(base_file_name, "");
$("a").each(function () {
this.href = baseUrl + this.pathname;
$(this).click(function (e) {
e.preventDefault();
alert(this.pathname);
window.location.href = this.href;
});
});
});
The example you linked should work, make sure you have the <base> set correctly and that you are using the correct string to replace.
Yeah, your going to have to normalize all URL's when your page loads. I can't test with phonegap right now, but your basePath will need to be one of the following:
The file path as you described in your answer (not likely)
window.location.origin (optionally including window.location.pathname)
CODE:
// mini dom ready - https://github.com/DesignByOnyx/mini-domready
(function(e,t,n){var r="attachEvent",i="addEventListener",s="DOMContentLoaded";if(!t[i])i=t[r]?(s="onreadystatechange")&&r:"";e[n]=function(r){/in/.test(t.readyState)?!i?setTimeout(function(){e[n](r)},9):t[i](s,r,false):r()}})
(window,document,"domReady");
domReady(function () {
var anchors = document.getElementsByTagName['a'],
basePath = /* get your base path here, without a trailing slash */;
Array.prototype.forEach.call(anchors, function( anchor ){
anchor.setAttribute('href', basePath + anchor.getAttribute('href'));
});
});
Remove the forward slash from the beginning of your links.
href="content/index2.html">

How do I use jQuery in Windows Script Host?

I'm working on some code that needs to parse numerous files that contain fragments of HTML. It seems that jQuery would be very useful for this, but when I try to load jQuery into something like WScript or CScript, it throws an error because of jQuery's many references to the window object.
What practical way is there to use jQuery in code that runs without a browser?
Update: In response to the comments, I have successfully written JavaScript code to read the contents of files using new ActiveXObject('Scripting.FileSystemObject');. I know that ActiveX is evil, but this is just an internal project to get some data out of some files that contain HTML fragments and into a proper database.
Another Update: My code so far looks about like this:
var fileIo, here;
fileIo = new ActiveXObject('Scripting.FileSystemObject');
here = unescape(fileIo.GetParentFolderName(WScript.ScriptFullName) + "\\");
(function() {
var files, thisFile, thisFileName, thisFileText;
for (files = new Enumerator(fileIo.GetFolder(here).files); !files.atEnd(); files.moveNext()) {
thisFileName = files.item().Name;
thisFile = fileIo.OpenTextFile(here + thisFileName);
thisFileText = thisFile.ReadAll();
// I want to do something like this:
s = $(thisFileText).find('input#txtFoo').val();
}
})();
Update: I posted this question on the jQuery forums as well: http://forum.jquery.com/topic/how-to-use-jquery-without-a-browser#14737000003719577
Following along with your code, you could create an instance of IE using Windows Script Host, load your html file in to the instance, append jQuery dynamically to the loaded page, then script from that.
This works in IE8 with XP, but I'm aware of some security issues in Windows 7/IE9. IF you run into problems you could try lowering your security settings.
var fileIo, here, ie;
fileIo = new ActiveXObject('Scripting.FileSystemObject');
here = unescape(fileIo.GetParentFolderName(WScript.ScriptFullName) + "\\");
ie = new ActiveXObject("InternetExplorer.Application");
ie.visible = true
function loadDoc(src) {
var head, script;
ie.Navigate(src);
while(ie.busy){
WScript.sleep(100);
}
head = ie.document.getElementsByTagName("head")[0];
script = ie.document.createElement('script');
script.src = "http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js";
head.appendChild(script);
return ie.document.parentWindow;
}
(function() {
var files, thisFile, win;
for (files = new Enumerator(fileIo.GetFolder(here).files); !files.atEnd(); files.moveNext()) {
thisFile = files.item();
if(fileIo.GetExtensionName(thisFile)=="htm") {
win = loadDoc(thisFile);
// your jQuery reference = win.$
WScript.echo(thisFile + ": " + win.$('input#txtFoo').val());
}
}
})();
This is pretty easy to do in Node.js with the cheerio package. You can read in arbitrary HTML from whatever source you want, parse it with cheerio and then access the parsed elements using jQuery style selectors.

~/ equivalent in javascript

Any smart way of doing a "root" based path referencing in JavaScript, just the way we have ~/ in ASP.NET?
Have your page generate a tag with something like:
<link rel="home" id="ApplicationRoot" href="http://www.example.com/appRoot/" />
Then, have a function in JavaScript that extracts the value such as:
function getHome(){
return document.getElementById("ApplicationRoot").href;
}
Use base tag:
<head>
<base href="http://www.example.com/myapp/" />
</head>
...
from now any link use on this page, no matter in javascript or html, will be relative to the base tag, which is "http://www.example.com/myapp/".
You could also use the asp.net feature VirtualPathUtility:
<script>
var basePath = '<%=VirtualPathUtility.ToAbsolutePath("~/")%>';
</script>
Notice: I don't encode the path to a JSON-string (escape quotes, control characters etc). I don't think this is a big deal (quotes for example aren't allowed unescaped in an URL), but one never knows...
I usually create a variable at the top of the js file and assign it the root path. Then I use that variable when referencing a file.
var rootPath = "/";
image.src = rootPath + "images/something.png";
~/ is the application root and not a literal root, it interpets ~/ to mean <YourAppVirtualDir>/
To do a literal root in JavaScript it's just /, i.e "/root.html". There's no way of getting an application level path like that in JavaScript.
You could hack it in the ASPX file and output it in a tag but I would consider the security implications of that.
Kamarey's answer can be improved to support a dynamic base path:
<head>
<base href="http://<%= Request.Url.Authority + Request.ApplicationPath%>/" />
</head>
This will ensure a correct root path regardless of deployment configuration.
To be fair, this doesn't answer the original question, but it elimiates most needs for getting the root path from javascript. Simply use relative URL's everywhere, without prefixing with slash.
Should you still need to access it from javascript, add an id attribute and use document.getElementFromId() as MiffTheFox suggested - but on the base-tag.
Another option that's a bit simpler and more universal would be to take the following:
<script src="/assets/js/bootstrap.min.js"><script>
and use Page.ResolveClientUrl like so:
<script src='<%=ResolveClientUrl("~/assets/js/bootstrap.min.js")%>'></script>
then regardless of what subdirectory the urls will always be rendered correctly.
The following function will calculate the root of the currently running application. I use it to locate the absolute location of resources, when called from somewhere deep within the application tree.
function AppRoot() {
//
// Returns the root of the currently running ASP application.
// in the form: "http://localhost/TRMS40/"
//
// origin: "http://localhost"
// pathname: "/TRMS40/Test/Test%20EMA.aspx"
//
// usage:
// window.open( AppRoot() + "CertPlan_Editor.aspx?ID=" + ID);
//
var z = window.location.pathname.split('/');
return window.location.origin + "/" + z[1] + "/";
}
In the PreRender of your .NET base page, add this:
protected override void
OnPreRender(EventArgs e) {
base.OnPreRender(e);
if (Page.Header != null)
{
//USED TO RESOLVE URL IN JAVASCRIPT
string baseUrl = String.Format("var baseUrl='{0}';\n",
HttpContext.Current.Request.ApplicationPath);
Page.Header.Controls.Add(new LiteralControl(String.Format(Consts.JS_TAG,
baseUrl)));
}
}
Then in your global JavaScript function, add the following:
function resolveUrl(url) {
if (url.indexOf("~/") == 0) {
url = baseUrl + url.substring(2);
}
return url; }
Now you can use it like this:
document.getElementById('someimage').src = resolveUrl('~/images/protest.jpg');
May be a little much for some projects, but works great for full fledged applications.
Solution for ASP.NET MVC applications
This works when using IIS and also IIS Express in VS.
Put this snippet before all scripts load, in order to have the root url variable "approot".
at your service in the scripts:
<script>
var approot = "#Url.Content("~")";
</script>
--> other scripts go here or somewhere later in the page.
Then use it in your script or page script.
Example:
var sound_root_path = approot + "sound/";
var img_root_path = approot + "img/";
the approot variable will be something either:
"/YourWebsiteName/" <-- IIS
or just:
"/" <-- IIS Express
For ASP.net MVC Razor pages, Create a base tag like below in the <Head> tag
<base href="http://#Request.Url.Authority#Request.ApplicationPath" />
and in all your relative javascript URLs, make sure to start without a slash(/) otherwise it will refer from the root.
For ex. create all your urls like
"riskInfo": { url: "Content/images/RiskInfo.png", id: "RI" },
or
$http.POST("Account/GetModelList", this, request, this.bindModelList);
If you want to use it in HTML Still you can use ~, see this
href = #Url.Content("~/controllername/actionName")
See the check box click event in my MVC Application
#Html.CheckBoxFor(m=>Model.IsChecked,
new {#onclick=#Url.Content("~/controller/action("+ #Model.Id + ", 1)"),
#title="Select To Renew" })

Categories