Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows implementation of 'Goto annotation in pdf' #109

Closed
jlegewie opened this issue Jul 21, 2013 · 9 comments
Closed

Windows implementation of 'Goto annotation in pdf' #109

jlegewie opened this issue Jul 21, 2013 · 9 comments
Labels

Comments

@jlegewie
Copy link
Owner

No description provided.

@jlegewie
Copy link
Owner Author

someone watching who can help with this? I don't have windows so I need someone who can text code.

@jlegewie
Copy link
Owner Author

jlegewie commented Feb 7, 2014

Here are the relevant information if someone wants to help out. There are two important parts for making this work on Windows. The first part finds the path of Adobe Reader by accessing the registry and the second opens the pdf. Both can be tested independently by setting the path manually using the acrobat variable. If someone was some coding experience and wants to help out, you can fiddle with this code in the Scratchpad, Firefox's javascript console. You have to set the devtools.chrome.enabled preference to true using about:config to run this code (strangely, I had to constantly switch this setting around. When you get the Components.classes not defined error, play with this setting).

1) Getting the path for Adobe Reader
var wrk = Components.classes["@mozilla.org/windows-registry-key;1"]
                .createInstance(Components.interfaces.nsIWindowsRegKey);
wrk.open(wrk.ROOT_KEY_LOCAL_MACHINE,
         "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths", 
         wrk.ACCESS_READ);
if(wrk.hasChild('AcroRd32.exe')) {
    subkey = wrk.openChild('AcroRd32.exe', wrk.ACCESS_READ);
    acrobat = subkey.readStringValue('Path') + 'AcroRd32.exe';
}
wrk.close();
acrobat
2) Opening the pdf
// acrobat = 'C:\Program Files (x86)\Adobe\Reader 11.0\Reader\AcroRd32.exe'
path = '[PATH TO A PDF FILE]'
page = 2

// These two function should work so don't worry about them
createFile =  function(path) {
    try {
        var file = Components.classes["@mozilla.org/file/local;1"].
            createInstance(Components.interfaces.nsIFile);
            file.initWithPath(path);
        return(file);
    }
    catch (err) {
        return(-1);
    }
}

runProcess =  function(command, args, blocking) {
    // default arguments
    blocking = typeof blocking !== 'undefined' ? blocking : true;
    try {
        // set up process
        var cmd = createFile(command);
        var proc = Components.classes["@mozilla.org/process/util;1"].
                    createInstance(Components.interfaces.nsIProcess);
        proc.init(cmd);

        // run process
        proc.runw(blocking, args, args.length);
    }
    catch(err) {
        Components.utils.reportError(err);
        return (-1);
    }
}

// open pdf on page
// http://partners.adobe.com/public/developer/en/acrobat/PDFOpenParameters.pdf
if (page)
    args = ['/A', '"page=' + page + '"', '"' + path + '"'];
else
    args = ['/A', '"' + path + '"'];
// run process
runProcess(acrobat, args, false);

@aurimasv
Copy link
Contributor

aurimasv commented Feb 7, 2014

Is there a reason why you are set on using only Adobe Acrobat for this? Looking around, it seems that probably most PDF readers support the /A "page=..." flag (e.g. PDF-XChange and FoxIt), so it would seem to me that you would want to get the default PDF handler instead of defaulting to Adobe.

Looking around at how Windows Explorer figures this out on Windows 7 (this may be a bit different on XP), you want to follow the following steps:

  1. Query HKCU\.pdf\OpenWithProgIds (pdf may be stored as PDF, so you might need to query both) and get the name of the first Value under that key (I think there should only be one). That is the default handler (we'll call it <hanlder>). (I was trying to get to this result from HKCU\MIME\application/pdf, but I couldn't get it to lead to the correct handler)
  2. Query HKCU\<handler>\CurVer\(Default) Call it <handler> (if no CurVer exists, skip to step 3. <handler> remains the same)
  3. Query HKCU\<handler>\shell\Read\command\(Default) (shell appears to also be Shell sometimes) If no Read is present, query HKCU\<handler>\shell\Open\command\(Default). The contents are your command line arguments. e.g. "C:\Program Files (x86)\Adobe\Reader 10.0\Reader\AcroRd32.exe" "%1" You'd probably want to just take the first part and append your arguments or do some other clever manipulations to add the /A argument

Let me know if you need me to dig around some more

Edit: escaped some special chars

@jlegewie
Copy link
Owner Author

jlegewie commented Feb 7, 2014

I am not at all set on using Adobe Reader. I just have no idea about windows so it's good to know that other PDF readers support the /A "page=..." flag as well. Thanks for looking into getting the default pdf viewer. The problem is that I rarely have access to a windows pc. It would be great if you find the time to write a function that returns the path C:\Program Files (x86)\Adobe\Reader 10.0\Reader\AcroRd32.exe. Otherwise, I will give it a shot when I have access again.

@aurimasv
Copy link
Contributor

aurimasv commented Feb 7, 2014

This should do it. I'll have to test it on other machines though

function getPDFReader() {
    var wrk = Components.classes["@mozilla.org/windows-registry-key;1"]
                        .createInstance(Components.interfaces.nsIWindowsRegKey);

    //get handler for PDFs
    var success = false;
    var tryKeys = ['.pdf', '.PDF']
    for(var i=0; !success && i<tryKeys.length; i++) {
        try {
            wrk.open(wrk.ROOT_KEY_CLASSES_ROOT,
                 tryKeys[i],
                 wrk.ACCESS_READ);
            success = true;
        } catch(e) {}
    }

    if(!success) return;

    var progId = wrk.readStringValue('');

    //get version specific handler, if it exists
    try {
        wrk.open(wrk.ROOT_KEY_CLASSES_ROOT,
            progId + '\\CurVer',
            wrk.ACCESS_READ);
        progId = wrk.readStringValue('') || progId;
    } catch(e) {}

    //get command
    success = false;
    tryKeys = [progId + '\\shell\\Read\\command', progId + '\\Shell\\Read\\command', progId + '\\shell\\Open\\command', progId + '\\Shell\\Read\\command'];
    for(var i=0; !success && i<tryKeys.length; i++) {
        try {
            wrk.open(wrk.ROOT_KEY_CLASSES_ROOT,
                 tryKeys[i],
                 wrk.ACCESS_READ);
            success = true;
        } catch(e) {}
    }

    if(!success) return;

    var command = wrk.readStringValue('').match(/^(?:".+?"|[^"]\S+)/);
    if(!command) return;
    return command[0].replace(/"/g, '');
}

Edit: tiny fix. Don't overwrite progId if there's nothing to redirect to.

@jlegewie
Copy link
Owner Author

jlegewie commented Feb 7, 2014

Thanks, that is great! I just added the function to zotfile so that the links to certain pages in pdfs might now work. I wasn't able to test it though (the last version with adobe wasn't working anyway). I hope I can give it a shot soon though. Let me know how it works on your other pc.

@aurimasv
Copy link
Contributor

aurimasv commented Feb 7, 2014

Works on Windows XP also, but I have not tested this with PDF-XChange or FoxIt

@jlegewie
Copy link
Owner Author

jlegewie commented Feb 8, 2014

I fixed the last thing in zotfile, added some documentation and the whole process should work now. Thanks again for helping out! I think this is a very useful feature.

@jlegewie jlegewie closed this as completed Feb 8, 2014
@pauldavidson
Copy link

I mostly use PDFfiller to annotate my PDFs. Its not the same thing, but maybe someone needs it. It also allows you to fill, edit erase in a pdf, esign, efax, add logos and pics to pdfs. Its pretty easy to use and its pretty cheap. I think you can get a free week if you and a friend both register. Here is a link to the site's functionality http://goo.gl/rNcHzt.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants