PDF Explorer > Ideas/Suggestions

Extract file Checksum

<< < (3/4) > >>

RTT:

--- Quote from: Padanges on August 31, 2016, 11:55:57 AM ---The script always returns "extraction from archive failed" for the archives. As I understand - there's a problem with the getFileName() function.
We need to change the line:

--- Code: ---filename = fso.getFileName(filename); //get archived file name, by removig the archive name and any internal path
--- End code ---
to the line:

--- Code: ---filename = filename.substring(filename.indexOf('>')+1,filename.length); // remove the tag
--- End code ---

--- End quote ---
Indeed! I tested for the worst case (archive with folders), and forgot to test that fso.getFileName in the other, only file name, situation.


--- Quote ---Thanks for the explanation! So if I get it right, then the line:

--- Code: ---if (!EL) {
--- End code ---
is actually:

--- Code: ---if (typeof EL === 'undefined' || EL === null) {
--- End code ---
which optimizes the batch process by catching undeleted object.

--- End quote ---
Yes, that's the idea.

--- Quote ---It is interesting to note that ZIP archives return "(EL created)+HASH" despite "var El;" being either inside function scope, or outside, while RAR archives react to this as all the rest of files. I checked this with BatchInfoEdit tool, not the BatchRename tool though.

--- End quote ---
Weird! Something to check out.

Here I leave a fixed and enhanced (now also handles file paths longer than 260 characters) CalcHashJS.

--- Code: ---var fso = new ActiveXObject("Scripting.FileSystemObject");
var EL;

function CalcHashJS() {
    try {
        if (!EL) {
            var MSXML = new ActiveXObject("MSXML2.DOMDocument");
            EL = MSXML.createElement("tmp");
            EL.dataType = "bin.hex";
        }

        var filename = BatchFile.Filename;
        if (filename.indexOf('>') > 0) { //file is archived
            filename = fso.getFileName(filename.substr(filename.indexOf('>') + 1)); //get archived file name, by removig the archive name and any internal path
            filename = fso.BuildPath(fso.GetSpecialFolder(2 /*TemporaryFolder*/ ), filename);
            BatchFile.BookmarkRoot; //trick to trigger the file extraction from the archive to the system temporary folder
            if (!fso.FileExists(filename)) return "extraction from archive failed"
        } else if (filename.length + 1 > 260 /*MAX_PATH*/ ) {
            var f = fso.GetFile('\\\\?\\' + filename);
            filename = f.ShortPath.substr(4);
        }
        EL.nodeTypedValue = GetFileHash(filename, CurrentField.Value);
        return EL.text;
    } catch (err) {
        return err;
    }
}

var stream;

function GetFileStream(filename) {
    if (!stream) {
        stream = new ActiveXObject("ADODB.Stream");
        stream.Type = 1; //adTypeBinary
    }
    stream.Open();
    stream.LoadFromFile(filename);
    return stream
}

function GetFileHash(filename, hashtype) {
    var HasMethodProgID = "";
    switch (hashtype) {
    case BatchFile.Filename:
    case "md5":
        HasMethodProgID = "System.Security.Cryptography.MD5CryptoServiceProvider";
        break;
    case "sha1":
        HasMethodProgID = "System.Security.Cryptography.SHA1Managed";
        break;
    case "sha256":
        HasMethodProgID = "System.Security.Cryptography.SHA256Managed";
        break;
    case "sha384":
        HasMethodProgID = "System.Security.Cryptography.SHA384Managed";
        break;
    case "sha512":
        HasMethodProgID = "System.Security.Cryptography.SHA512Managed";
        break;
    case "ripemd160":
        HasMethodProgID = "System.Security.Cryptography.ripemd160Managed"
        break;
    }
    if (!HasMethodProgID) throw '"' + hashtype + '" is not a valid hash method.';
    try {
        if (GetFileStream(filename)) return ComputeHash(stream, HasMethodProgID)
    } catch (err) {
        throw err
    } finally {
        if (stream && stream.state == 1) stream.Close();
    }
}

function ComputeHash(stream, objectid) {
    var BlockSize = 65536;
    var HashObj = new ActiveXObject(objectid);
    try {
        var nBlocks = parseInt(stream.size / BlockSize);
        var block;
        for (var i = 1; i < nBlocks; i++) {
            block = stream.read(BlockSize);
            HashObj.TransformBlock(block, 0, BlockSize, block, 0);
        }
        var n = stream.size - stream.position;
        block = stream.read(n);
        HashObj.TransformFinalBlock(block, 0, n);
        return HashObj.Hash;
    } finally {
        HashObj.Clear
    }
}

--- End code ---

Padanges:
We have three test case files which fail to get Hash calculated:
1) long names, using "Only DB" option. I suppose only you can see this working if you have fixed this issue which was mentioned in some previous post. So, therefore, I need that update too ;)
2) for files inside archives. I guess it's the same case as previous because I was trying the "Only DB" option. Should we be able to change metadata for archived files? I suppose not.
3) "whatever.pDF" -- please note the letter case for extension. I would argue that extensions should always be case insensitive, for any checks, but haven't found the line which is responsible for this yet. Any hints?

I've also noticed that you have changed block size "var BlockSize = 65536 * 10;" - what was the reason for that? It gives slight calculation speed slowdown.

RTT:

--- Quote from: Padanges on September 01, 2016, 02:54:15 PM ---We have three test case files which fail to get Hash calculated:
1) long names, using "Only DB" option. I suppose only you can see this working if you have fixed this issue which was mentioned in some previous post.

--- End quote ---
Probably. Even so, I've updated the above last version of the script for some related issues. Try it again.

--- Quote --- So, therefore, I need that update too ;)
--- End quote ---
You will ;)
By the way. Why don't you register in the forum, and continue posting as a guest? Being registered has some advantages, such as being able to receive email notifications when a reply is posted to a topic you are following, attach files, send and receive personal messages, ...

--- Quote ---2) for files inside archives. I guess it's the same case as previous because I was trying the "Only DB" option. Should we be able to change metadata for archived files? I suppose not.

--- End quote ---
DB only when archived file, or file type without metadata edit support, being processed, even if DB Only option not checked.


--- Quote ---3) "whatever.pDF" -- please note the letter case for extension. I would argue that extensions should always be case insensitive, for any checks, but haven't found the line which is responsible for this yet. Any hints?

--- End quote ---
No idea. I made a quick test and worked in that situation. What's the full file path, so I can test here?


--- Quote ---I've also noticed that you have changed block size "var BlockSize = 65536 * 10;" - what was the reason for that? It gives slight calculation speed slowdown.

--- End quote ---
Still figuring out what's the best size. Probably this is dependent on the system (disk, ram, windows version,...)

Padanges:

--- Quote ---Why don't you register in the forum, and continue posting as a guest?
--- End quote ---
Here we go - now I'm a legit forum member :)


--- Quote ---DB only when archived file, or file type without metadata edit support, being processed, even if DB Only option not checked.
--- End quote ---
I'm not sure I have understood you correctly: you say that for files which have no metadata support (that includes archives as well) we work only with DB metadata by default, even without "DB Only" option checked/unchecked?


--- Quote ---I made a quick test and worked in that situation. What's the full file path, so I can test here?
--- End quote ---
I've made some other tests and was unable to duplicate this behaviour again but the initial issue persists. Strange. Then, the problem is on my side.


--- Quote ---I've updated the above last version of the script for some related issues. Try it again.
--- End quote ---
Thanks. Just a quick note: 260 is already out of SHORT_PATH bounds therefore you should write "> 259".

One more thing, if I try to RUN/DEGUB the updated code in Script Manager I get a warning "'Sample data' is not a valid hash method.". I suppose this means that in the Script Manager by default you run the line [CalcHashJS](Sample data). Is there a way to run a specific (CurrentField.Value) parameter string from within the Script Manager? Up to this point I used to have to close the Script Manager and change test strings from the "outside".

RTT:

--- Quote from: Padanges on September 02, 2016, 12:55:38 PM ---
--- Quote ---Why don't you register in the forum, and continue posting as a guest?
--- End quote ---
Here we go - now I'm a legit forum member :)

--- End quote ---
Now with all your previous posts reassigned to your user account.


--- Quote ---
--- Quote ---DB only when archived file, or file type without metadata edit support, being processed, even if DB Only option not checked.
--- End quote ---
I'm not sure I have understood you correctly: you say that for files which have no metadata support (that includes archives as well) we work only with DB metadata by default, even without "DB Only" option checked/unchecked?

--- End quote ---
Yes, that's the behavior I'm implementing now, in order to support other file types.


--- Quote ---Just a quick note: 260 is already out of SHORT_PATH bounds therefore you should write "> 259".
--- End quote ---
That's why the above code is filename.length+1>260. Let the compiler optimize the arithmetic. I prefer to read filename+null>MAX_PATH.


--- Quote ---One more thing, if I try to RUN/DEGUB the updated code in Script Manager I get a warning "'Sample data' is not a valid hash method.". I suppose this means that in the Script Manager by default you run the line [CalcHashJS](Sample data). Is there a way to run a specific (CurrentField.Value) parameter string from within the Script Manager? Up to this point I used to have to close the Script Manager and change test strings from the "outside".

--- End quote ---
Adding a parameters input field to the scripts manager, to manually set the value while testing/debugging, is a possibility to fix this. Meanwhile, manually adding a temporary, for debug proposes, CurrentField.Value=YouData line to the code is a easy solution.

Navigation

[0] Message Index

[#] Next page

[*] Previous page

Reply

Go to full version