Is there any way to get the current opened tab in a browser (firefox at least) using bash .
In other words, the url of the tab that called the bash script from the file browser (incorporated in that page)
Firefox changed the way it stores urls on the hard drive in version 33.
I wrote this php script to search for opened tabs. I used php, so you'll need php5-cli (or newer) package installed.
You'll need to ajust the $displayOnlyLastActiveUrl to fit your needs: set to false to display all opened url, true for last active opened URL
the script might need to be improved, but it fits my needs.
known limitations:
migth not look in the good profile if you have multiple profiles set in firefox.
might takes up to 10 seconds to update
if you choose to output all urls, some closed tabs may appear
just create a php file with the above content and run it within shell with php yourfile.php
<?php
//
// Display curent opened URLs in firefox.
// Author: Julien Marin (malinuxtele[AT]tuxfamily[DOT]org)
// Licence: GPL 3
//
$displayOnlyLastActiveUrl=true; //set to false to display all opened url, true for last active opened URL
//Search for restore.js (might need to be improved for multiprofiles environement...)
if (!$profileIniContents=fopen(getenv("HOME")."/.mozilla/firefox/profiles.ini", "r")) trigger_error("unable to open profiles file", E_USER_ERROR);
$profile="";
$ar_match=array();
while ($ligne=fgets($profileIniContents))
if (preg_match("/Path=([^.]*)[.]default/", $ligne, $ar_match))
$profile=$ar_match[1];
//Open recovery.js file
if(! $recoveryFileHandle=fopen(getenv("HOME")."/.mozilla/firefox/$profile.default/sessionstore-backups/recovery.js", "r")) trigger_error("unable to open recovery.js file", E_USER_ERROR);
$recoveryData=json_decode(fread($recoveryFileHandle, 4000000), true);
//parse data
$ar_tabs=array();
foreach ($recoveryData["windows"] as $actWindow)
foreach ($actWindow["tabs"] as $actTabGroup)
{
$lastAccess=$actTabGroup["lastAccessed"];
foreach ($actTabGroup["entries"] as $actTabEntry)
if(!$displayOnlyLastActiveUrl) echo($actTabEntry["url"]."\n");
else $ar_tabs[$lastAccess]=$actTabEntry["url"];
}
//search last URL
if ($displayOnlyLastActiveUrl)
{
ksort($ar_tabs);
echo array_pop($ar_tabs);
}
?>
I've found this by chance :
#!/bin/bash
for var in "$#"
do
#
#
done
$# contains the url of the tab.
Related
I am new to Firefox extensions and i would like you to help me pack one extension that i build and send it to some friends to test it.
My Extension is about to "block" some URLs. Which means that if someone tries to join "facebook.com" my extension should redirect him to "www.google.com"
the code is below.
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import('resource://gre/modules/Services.jsm');
var urls_block = [
//If URLs contain any of these elements they will be blocked or redirected,
// your choice based on code in observer line 17
'www.facebook.com',
'www.apple.com'
];
var redir_obj = {
'www.facebook.com': 'http://www.google.com/',
'www.apple.com': 'http://www.samsung.com'
}
var observers = {
'http-on-modify-request': {
observe: function (aSubject, aTopic, aData) {
console.info('http-on-modify-request: aSubject = '
+ aSubject + ' | aTopic = ' + aTopic + ' | aData = ' + aData);
var httpChannel = aSubject.QueryInterface(Ci.nsIHttpChannel);
var requestUrl = httpChannel.URI.spec.toLowerCase();
for (var i=0; i<urls_block.length; i++) {
if (requestUrl.indexOf(urls_block[i]) > -1) {
//httpChannel.cancel(Cr.NS_BINDING_ABORTED); //this aborts the load
//Can redirect with this next line, if don't want to redirect and
// just block, then comment this line and uncomment the line above:
httpChannel.redirectTo(Services.io.newURI(redir_obj[urls_block[i]],
null, null));
break;
}
}
},
reg: function () {
Services.obs.addObserver(observers['http-on-modify-request'],
'http-on-modify-request', false);
},
unreg: function () {
Services.obs.removeObserver(observers['http-on-modify-request'],
'http-on-modify-request');
}
}
};
function install() {}
function uninstall() {}
function startup() {
for (var o in observers) {
observers[o].reg();
}
}
function shutdown(aData, aReason) {
if (aReason == APP_SHUTDOWN) return;
for (var o in observers) {
observers[o].unreg();
}
}
Big thanks to #Noitidart for his enormous help.
So i want to pack this code for Firefox Extension.
Could someone show me how to do it or any example?
Thanks a lot for your time helping me here.
At a minimum, you will need to create an install.rdf file and a chrome.manifest file. Go through those links, you are going to need to make some choices (e.g. what to call your extension, an <em:id>, etc.).
In addition, it appears that you are making a bootstrap/restartless add-on and should call the file containing the code you included in the question: bootstrap.js
.xpi file format (Extension Packaging):
The .xpi files that are used as containers for Mozilla (Firefox, Thunderbird, etc.) extensions are merely zip compressed archives that have had the file extension changed to .xpi. The files start in the root directory of the zip compressed archive (i.e. there is first level directory to contain the files). The files must either be uncompressed, or compressed using the "Deflate" algorithm. Using other compression algorithms will result in your .xpi file not loading and a popup being shown that the add-on is corrupt.
The contents of the archive could be only a few files to any number of files. At a minimum, you have an install.rdf and a chrome.manifest file. There will almost always be at least one additional file (if not many additional files).
My very simple Bootstrap/Restartless extension, Print Button is Print (changes the print button to print instead of print preview), has the following structure:
Archive contains:
bootstrap.js
chrome/
chrome/content/
chrome/content/options.xul
chrome/skin/
chrome/skin/printer-typeC128.png
chrome/skin/printer-typeC32.png
chrome/skin/printer-typeC48.png
chrome/skin/printer-typeC64.png
chrome.manifest
install.rdf
license.txt
Total 12 entries (42360 bytes)
There are the required install.rdf and chrome.manifest files.
The file bootstrap.js is required for Bootstrap/Restartless extensions. It contains the code that is run when the extension is installed, removed, enabled, disabled, or upon Firefox startup or shutdown. This extension is simple enough such that all the JavaScript code is contained in bootstrap.js.
There is a file chrome/content/options.xul which is a XUL definition of the options dialog.
The license.txt just explains that the extension was released under the Mozilla Public License, v2.0.
The .png files are the icon for this extension at various resolutions.
The install.rdf file for Print Button is Print is (all instances of PrintButtonIsPrint should be changed to something for your extension which you define in your chrome.manifest file; All of them you could just delete from the instal.rdf file if you wanted to as you have no options dialog, or icons defined (yet).):
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>PrintButtonIsPrint#makyen.foo</em:id> <!-- MUST be unique to your extension. -->
<em:version>1.0.1</em:version>
<em:type>2</em:type>
<em:name>Print Button is Print</em:name> <!-- Should be unique to your extension. -->
<em:bootstrap>true</em:bootstrap> <!-- Indicate that the extension is restartless -->
<em:unpack>false</em:unpack>
<em:description>Makes the Print Button print the page instead of presenting a print preview. Adds the option of using shift-left-click and/or ctrl-left-click for Print Preview (both enabled by default).</em:description>
<em:creator>Makyen</em:creator>
<!-- No about.
<em:aboutURL>chrome://PrintButtonIsPrint/content/about.xul</em:aboutURL>
-->
<em:optionsURL>chrome://PrintButtonIsPrint/content/options.xul</em:optionsURL>
<em:iconURL>chrome://PrintButtonIsPrint/skin/printer-typeC48.png</em:iconURL>
<em:icon64URL>chrome://PrintButtonIsPrint/skin/printer-typeC64.png</em:icon64URL>
<!--Firefox-->
<em:targetApplication>
<Description>
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
<em:minVersion>29.0</em:minVersion>
<em:maxVersion>37.*</em:maxVersion>
</Description>
</em:targetApplication>
</Description>
</RDF>
The chrome.manifest is (both instances of PrintButtonIsPrint should be changed to something for your extension):
content PrintButtonIsPrint chrome/content/
skin PrintButtonIsPrint classic/1.0 chrome/skin/
To create the .xpi file I use a batch file, which uses a combination of DOS and Unix/Linux (actually Cygwin) commands:
mkxpi.bat:
rm -f PrintButtonIsPrint#makyen.foo.xpi
zip -1 -r PrintButtonIsPrint#makyen.foo.xpi * -x#xpi.ignore
pause
This removes any old version of the .xpi file. It then creates a new .xpi file using, -1, minimal compression (speed of access is more important than saving space) and containing all files and subdirectories ** but ignoring all the files in the xpi.ignore text file -x#xpi.ignore. Ignoring files is used because I have other things in the directory (e.g. .git directory, .bak files auto-created from editor, etc.). Once the .xpi file is created the script executes pause so that I can verify which files were included, that there were no errors, etc. instead of just having the window disappear and assuming that everything is fine.
My xpi.ignore file is a bit long, as it accumulates cruft from various projects and is rarely cleaned out:
*.com
*.class
*.dll
*.exe
*.o
*.so
*.7z
*.dmg
*.gz
*.iso
*.jar
*.rar
*.tar
*.zip
*.log
*.sql
*.sqlite
*.svg
*/.DS_Store
*/.DS_Store?
*/._*
._*
*/.Spotlight-V100
.Spotlight-V100
*/.Trashes
.Trashes
*/ehthumbs.db
*/Thumbs.db
*.ORIG
*.bak
*OLD*
OLD/*
*/OLD/*
*.OLD
*.OLD[0-9]
*/OLD/*
*/OLD[0-9]/*
*.unknown
*.unknown[0-9]
*.updated
*.updated[0-9]
*/Copy *
*/OLD
*/OLD*
*/OLD[0-9]
*/OLD[0-9][0-9]
*/test/*
*/not in xpi/*
*/tmp
*.tmp
*/foo
*.foo
*checkpoint
.git
*/.git
.gitignore
*/.gitignore
xpi.ignore
mkclean.bat
mkclean.bat.DONTRUN
mkxpi.bat
*.xpi
*/devtools-toolbox-window.ico
*/devtools-webconsole.ico
*/JSConsoleWindow.ico
*/main-window.ico
*/places.ico
*/viewSource.ico
Installing extensions:
As to installing extensions (i.e. the .xpi file), it can be a simple matter of dragging and dropping it onto a Firefox window running the profile in which you desire it installed. For development/testing, you can have the extension be in a directory on your local drive by using a Firefox extension proxy file (create a file named as the extension's <em:id> in the profile's extensions directory containing one line with the complete path to the directory containing the extension's files). Depending on what your goal is (one profile, all profiles, all users, which OS, etc.), there are other options as to how to install extensions.
This answer was mostly copied from my answer here.
I am writing a simple file uploader in CodeIgniter 2.0.2. Pasting code below.
Under certain conditions the browser hangs during this upload and I get "waiting for localhost" in the browser status bar (identical behavior in FF and Chrome).
I have verified that the file is being uploaded to the Windows temporary folder (the complete file), but the process gets stuck after that.
It appears that the condition for the bug is file size. But my php.ini has all the right settings for uploading files, and I still get the hang with a 700k file.
This bug occurs only when I run it on Windows 7 Apache, not on an Ubuntu box.
The suggested to me that some paths in the php.ini may be incorrectly set.
Apache log files have not been much help here because there is no error thrown.
I have tried using Chrome developer panel to debug but haven't turned up anything useful.
I am currently trying to get XDebug working, but since no error is thrown and the process doesn't complete, my expectations are low.
Any suggestions for how to trace this bug?
If there are specific php.ini settings you'd like to see, let me know, don't want to do the big dump.
Controller:
function do_upload_sql(){
// create directory
if (! is_dir(BACKUP_DIR)) {
mkdir(BACKUP_DIR, 0777);
}
// or if it exists and has restricted file permissions, change them
elseif(fileperms(BACKUP_DIR)!=0777){
chmod(BACKUP_DIR, 0777);
}
$config['upload_path'] = BACKUP_DIR;
$config['allowed_types'] = 'backup'; // an SQL backup file type
$config['overwrite'] = TRUE;
$this->load->library('upload', $config);
if ( ! $this->upload->do_upload()) // this is the native CI function, probably where the problem is. I can provide some of that code if anyone wants.
{
$data['action'] = 'c_backup_restore/do_upload_sql';
$tab_error = array('error' => $this->upload->display_errors());
$data['error'] = $tab_error['error'];
$this->load->view('common/header');
$this->load->view('v_upload_sql', $data);
}
else
{
echo "success"; // yes it's getting here, but i get no file!
$data = array('upload_data' => $this->upload->data());
$file_upload = $data["upload_data"];
$this->restore_backup($file_upload); // go do something useful with the file
}
}
View:
<p>Select the backup file</p>
<div class="not_success"><?php echo $error;?></div>
<?php echo form_open_multipart($action);?>
<input type="file" name="userfile" size="30" />
<input type="submit" value="Upload" />
</form>
If your error only occurs on windows 7 apache, I think that your issue may be with the "is_dir()" "mkdir()" and "chmod()" commands -- these terminal commands are linux specific and will not work so great on a windows system.
I looked up the documentation on the mkdir() function in the PHP.net Manual at:
http://us.php.net/manual/en/function.mkdir.php
I found this in the comments section:
kendsnyder at gmail dot com 04-May-2007 08:17
When creating directories in Windows, trailing periods (".") are ignored. for example:
<?php
mkdir('c:/Buck Jr.',0755); // on Windows creates "c:/Buck Jr"
mkdir('c:/Elipses...',0755); // on Windows creates "c:/Elipses"
mkdir('c:/php.com',0755); // on Windows creates "c:/php.com"
?>
This is a Window's quirk, not a php shortcoming--meaning that you get the same results from a Window's command prompt.
So it seems it will work... but you are likely to have to futz with it to find the flavor that Windows systems prefer. Also it seems that you must specify the root drive on which to make the directory, e.g.: 'c:\somedir'
Also of interest, I did a quick google search and discovered that PHP has published a bug around the functionality you are using, specifically related to forward vs. back slashes of the windows vs. linux systems:
https://bugs.php.net/bug.php?id=29797
Here is a StackOverflow post related to your question:
PHP mkdir(), chmod() and Windows
So to summarize:
On a windows based web server, include the drive that the directory will be placed on
File Permissions on Windows are different from Linux (Windows doesn't have a chmod or file permissions structure like Linux!) Although from what I can tell Windows is supposed give a folder the equivalent of a 777 permissions level -- but this functionality seems buggy and error prone. But this also means that using the chmod() function on a windows system, you will get unpredictable results. For more info consult the PHP Manual: http://php.net/manual/en/function.chmod.php
Remember to use backslashes rather than forward slashes for the directory path, as Windows systems use back slashes, whereas Linux uses forward slashes.
When PHP creates a directory it uses the permissions that were granted to the user account that PHP is running under, which means that you may have to dig into windows to find what user permissions level your windows 7 Apache/PHP is running under and make that change there. I know, what a pain, right?
One final thing: mkdir() function returns true if the directory creation was successful and false if not -- you may want to be testing for that condition before proceeding with the rest of your code, because if the directory doesn't properly get created, all the rest of your code that relies on that directory existing is going to fail. Ultimately I think your browser is hanging upon submit because it is trying to access a function through PHP which there is no support for on Windows (chmod). Perform the function calls within a "Try/Catch" block to catch any exceptions that occur so that you can print them to screen or a log file if necessary:
$proceed = false;
try
{
// create directory
if (! is_dir(BACKUP_DIR)) {
$proceed = mkdir(BACKUP_DIR, 0777);
}
// or if it exists and has restricted file permissions, change them
elseif(fileperms(BACKUP_DIR)!=0777){
$proceed = chmod(BACKUP_DIR, 0777);
}
}
catch(Exception $e)
{
echo $e->message;
}
if($proceed == TRUE)
{
/*Proceed with your code*/
}
else
{
/*Gracefully fail*/
}
Good luck man, this is why I prefer Linux Boxes for web servers!
Cheers!
I tried the instructions - I am using Firefox on Lubuntu (Openbox). But I get the error
"Firefox doesn't know how to open this address, because the protocol (org-protocol) isn't associated with any program".
How should I fix this?
The following steps for setting up org-protocol work with Ubuntu 16.04 (Xenial Xerus) and presumably later versions. Org-mode is assumed to have already been set-up (and installed using apt-get install org-mode or via the ELPA repository).
Set-up
Add .desktop file
Create and save a file called org-protocol.desktop to ~/.local/share/applications containing:
[Desktop Entry]
Name=org-protocol
Exec=emacsclient %u
Type=Application
Terminal=false
Categories=System;
MimeType=x-scheme-handler/org-protocol;
Then run:
$ update-desktop-database ~/.local/share/applications/
This step makes Firefox aware that "org-protocol" is a valid scheme-handler or protocol (by updating ~/.local/share/applications/mimeinfo.cache), and causes Firefox to prompt for a program to use when opening these kinds of links.
Add config settings to ~/.emacs.d/init.el (or ~/.emacs) file
Have the following settings in your Emacs configuration file:
(server-start)
(require 'org-protocol)
Also add some template definitions to the configuration file, for example:
(setq org-protocol-default-template-key "l")
(setq org-capture-templates
'(("t" "Todo" entry (file+headline "/path/to/notes.org" "Tasks")
"* TODO %?\n %i\n %a")
("l" "Link" entry (file+olp "/path/to/notes.org" "Web Links")
"* %a\n %?\n %i")
("j" "Journal" entry (file+datetree "/path/to/journal.org")
"* %?\nEntered on %U\n %i\n %a")))
Now run Emacs.
Create your notes.org file
Assuming you use the capture templates defined in step 2, you will need to prepare a notes.org file at the location you specified in step 2. You must create this file -- if it is not created along with the headlines specified in step 2, org-mode will just give a warning when you try to capture web-pages. So, given the capture templates from step 2, notes.org should contain the following:
* Tasks
* Web Links
Add bookmarklet(s) to Firefox
Save bookmark to toolbar containing something like the following as the location:
javascript:location.href='org-protocol://capture?template=l&url='+encodeURIComponent(location.href)+'&title='+encodeURIComponent(document.title)+'&body='+encodeURIComponent(window.getSelection())
If you are using an older version of org-mode, you may need to use the following instead:
javascript:location.href='org-protocol://capture://l/'+encodeURIComponent(location.href)+'/'+encodeURIComponent(document.title)+'/'+encodeURIComponent(window.getSelection())
Notice the 'l' (lowercase L) in the above URL -- this is what chooses the capture template (automatically) -- it is the key one would normally have to press when capturing with org-mode via C-c c.
When you click on this bookmarklet, Firefox will ask what program to use to handle the "org-protocol" protocol. You can simply choose the default program that appears ("org-protocol").
Using it
(Optionally) select some text on a webpage you're viewing in Firefox. When you click on the bookmarklet, the link and selected text will be placed in the Emacs capture buffer. Go to Emacs, modify the capture buffer as desired, and press C-c C-c to save it.
Add protocol handler
Create file ~/.local/share/applications/org-protocol.desktop containing:
[Desktop Entry]
Name=org-protocol
Exec=emacsclient %u
Type=Application
Terminal=false
Categories=System;
MimeType=x-scheme-handler/org-protocol;
Note: Each line's key must be capitalized exactly as displayed, or it will be an invalid .desktop file.
Then update ~/.local/share/applications/mimeinfo.cache by running:
On GNOME:
update-desktop-database ~/.local/share/applications/
On KDE:
kbuildsycoca4
Configure Emacs
Init file
Add to your Emacs init file:
(server-start)
(require 'org-protocol)
Capture template
You'll probably want to add a capture template something like this:
("w" "Web site"
entry
(file+olp "/path/to/inbox.org" "Web")
"* %c :website:\n%U %?%:initial")
Note: Using %:initial instead of %i seems to handle multi-line content better.
This will result in a capture like this:
\* [[http://orgmode.org/worg/org-contrib/org-protocol.html][org-protocol.el – Intercept calls from emacsclient to trigger custom actions]] :website:
[2015-09-29 Tue 11:09] About org-protocol.el
org-protocol.el is based on code and ideas from org-annotation-helper.el and org-browser-url.el.
Configure Firefox
Expose protocol-handler
On some versions of Firefox, it may be necessary to add this setting. You may skip this step and come back to it if you get an error saying that Firefox doesn't know how to handle org-protocol links.
Open about:config and create a new boolean value named network.protocol-handler.expose.org-protocol and set it to true.
Note: If you do skip this step, and you do encounter the error, Firefox may replace all open tabs in the window with the error message, making it difficult or impossible to recover those tabs. It's best to use a new window with a throwaway tab to test this setup until you know it's working.
Make bookmarklet
Make a bookmarklet with the location:
javascript:location.href='org-protocol://capture://w/'+encodeURIComponent(location.href)+'/'+encodeURIComponent(document.title)+'/'+encodeURIComponent(window.getSelection())
Note: The w in the URL chooses the corresponding capture template. You can leave it out if you want to be prompted for the template.
When you click on this bookmarklet for the first time, Firefox will ask what program to use to handle the org-protocol protocol. If you are using Ubuntu 12.04 (Precise Pangolin), you must add the /usr/bin/emacsclient program, and choose it. With Ubuntu 12.10 (Quantal Quetzal) or later, you can simply choose the default program that appears (org-protocol).
You can select text in the page when you capture and it will be copied into the template, or you can just capture the page title and URL.
Tridactyl
If you're using Tridactyl, you can map key sequences something like this:
bind cc js location.href='org-protocol://capture://w/'+encodeURIComponent(content.location.href)+'/'+encodeURIComponent(content.document.title)+'/'+encodeURIComponent(content.document.getSelection())
You might also want to add one for the `store-link` sub-protocol, like:
bind cl js location.href='org-protocol://store-link://'+encodeURIComponent(content.location.href)+'/'+encodeURIComponent(content.document.title)
Capture script
You may want to use this script to capture input from a terminal, either as an argument or piped in:
#!/bin/bash
if [[ $# ]]
then
data="$#"
else
data=$(cat)
fi
if [[ -z $data ]]
then
exit 1
fi
encoded=$(python -c "import sys, urllib; print urllib.quote(' '.join(sys.argv[1:]), safe='')" "${data[#]}")
# "link" and "title" are not used, but seem to be necessary to get
# $encoded to be captured
emacsclient "org-protocol://capture://link/title/$encoded"
Then you can capture input from the shell like this:
tail /var/log/syslog | org-capture
org-capture "I can capture from a terminal!"
These instructions are more up-to-date than the ones in Mark's answer.
I'm currently developing a Web app for the iPad.
So I created the whole "application", with my different html files, my css, my pictures.
Now the next step for me is to be able to cache the files to use the "application" offline.
I follow the advices I found on different websites, with the manifest file and everything.
It seems I'm the only one with this issue, because I searched on Internet an answer to my issue, but I didn't find anything.
So I created my manifest file (ipad.manifest) which looks like this :
$CACHE MANIFEST
$/WebApp/home-start.htm
$/WebApp/accommodation.htm
$/WebApp/accommodation2.htm
$/WebApp/dining.htm
$/WebApp/entertainment.htm
$/WebApp/general.htm
$/WebApp/home.htm
$/WebApp/shopping.htm
$/WebApp/sights.htm
$/WebApp/sports.htm
$/WebApp/css/screen3.css
$/WebApp/Player/CanalVenetian.mp4
$/WebApp/Player/DancingWater.mp4
$/WebApp/Player/NaCha.mp4
$/WebApp/Player/NaCha2.mp4
$/WebApp/Player/Opening.mp4
$/WebApp/Player/previewhome.jpg
$/WebApp/Player/previewsights.jpg
$/WebApp/Player/previewvenetian.jpg
$/WebApp/Player/Venetian.mp4
$/WebApp/Player/video.js
$/WebApp/Player/Zaia.mp4
$/WebApp/iPad/startup.png
$/WebApp/iPad/pixel.gif
$/WebApp/iPad/asktt-ipad-accommodation2.jpg
$/WebApp/iPad/asktt-ipad-camera.jpg
$....
I tried with both, relative and absolute links, and it's still not working.
And in every html files I added :
$<!DOCTYPE html>
$<html manifest="ipad.manifest">
$<head>
When I go to the website with the iPad and click on "add to home screen", it adds the icon on the home screen but didn't download the content. So each time I open the application it starts to load everything....
When I tried on desktop browsers it didn't ask me to cache the content on my computer.
I added an header "content/type : text/manifest" for my mime type files on my server.
But I don't understand why it doesn't cache anything, or doesn't even ask me if I want to cache the files???
Does someone have an idea ? Or had the same issue ?
try with this, put it on the root of your app and name it manifest.php and add it to your html web app with
php file start here
$hashes="";
$dir = new RecursiveDirectoryIterator(".");
foreach(new RecursiveIteratorIterator($dir) as $file){
if ($file->IsFile() &&
$file != "./manifest.php" &&
substr($file->getFilename(),0,1) != ".")
{
echo $file . "\n";
$hashes .= md5_file($file);
}
}
echo "# Hash:" . md5($hashes) . "\n";
?>
php file ends here
How do I register a custom protocol with Windows so that when clicking a link in an email or on a web page my application is opened and the parameters from the URL are passed to it?
Go to Start then in Find type regedit -> it should open Registry editor
Click Right Mouse on HKEY_CLASSES_ROOT then New -> Key
In the Key give the lowercase name by which you want urls to be called (in my case it will be testus://sdfsdfsdf) then Click Right Mouse on testus -> then New -> String Value and add URL Protocol without value.
Then add more entries like you did with protocol ( Right Mouse New -> Key ) and create hierarchy like testus -> shell -> open -> command and inside command change (Default) to the path where .exe you want to launch is, if you want to pass parameters to your exe then wrap path to exe in "" and add "%1" to look like: "c:\testing\test.exe" "%1"
To test if it works go to Internet Explorer (not Chrome or Firefox) and enter testus:have_you_seen_this_man this should fire your .exe (give you some prompts that you want to do this - say Yes) and pass into args testus://have_you_seen_this_man.
Here's sample console app to test:
using System;
namespace Testing
{
class Program
{
static void Main(string[] args)
{
if (args!= null && args.Length > 0)
Console.WriteLine(args[0]);
Console.ReadKey();
}
}
}
Hope this saves you some time.
The MSDN link is nice, but the security information there isn't complete. The handler registration should contain "%1", not %1. This is a security measure, because some URL sources incorrectly decode %20 before invoking your custom protocol handler.
PS. You'll get the entire URL, not just the URL parameters. But the URL might be subject to some mistreatment, besides the already mentioned %20->space conversion. It helps to be conservative in your URL syntax design. Don't throw in random // or you'll get into the mess that file:// is.
If anyone wants a .reg file for creating the association, see below:
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\duck]
"URL Protocol"=""
[HKEY_CLASSES_ROOT\duck\shell]
[HKEY_CLASSES_ROOT\duck\shell\open]
[HKEY_CLASSES_ROOT\duck\shell\open\command]
#="\"C:\\Users\\duck\\source\\repos\\ConsoleApp1\\ConsoleApp1\\bin\\Debug\\net6.0\\ConsoleApp1.exe\" \"%1\""
Pasted that into notepad, the file -> save as -> duck.reg, and then run it. After running it, when you type duck://arg-here into chrome, ConsoleApp1.exe will run with "arg-here" as an argument. Double slashes are required for the path to the exe and double quotes must be escaped.
Tested and working on Windows 11 with Edge (the chrome version) and Chrome
There is an npm module for this purpose.
link :https://www.npmjs.com/package/protocol-registry
So to do this in nodejs you just need to run the code below:
First Install it
npm i protocol-registry
Then use the code below to register you entry file.
const path = require('path');
const ProtocolRegistry = require('protocol-registry');
console.log('Registering...');
// Registers the Protocol
ProtocolRegistry.register({
protocol: 'testproto', // sets protocol for your command , testproto://**
command: `node ${path.join(__dirname, './index.js')} $_URL_`, // $_URL_ will the replaces by the url used to initiate it
override: true, // Use this with caution as it will destroy all previous Registrations on this protocol
terminal: true, // Use this to run your command inside a terminal
script: false
}).then(async () => {
console.log('Successfully registered');
});
Then suppose someone opens testproto://test
then a new terminal will be launched executing :
node yourapp/index.js testproto://test
It also supports all other operating system.