Error retrieving max modification time before/after checking directories exist

So I’m working on an analysis that retrieves and compares modification times of prefetch files as a way of determining last run times. I have it working quite reliably for several different Adobe Creative Cloud applications, but my relevance for Acrobat DC is giving me grief because I have to check two different folders for subfolders rather than just one. So on some machines this:

if not exists (names of folders of folder "C:\Program Files\Adobe") whose (it = "Acrobat DC") and not exists (names of folders of folder "C:\Program Files (x86)\Adobe") whose (it = "Acrobat DC") then "Not Installed" else if exists (names of files of folder "C:\Windows\Prefetch\") whose (it starts with "ACROBAT.EXE") then ((year of it as string & "-" & month of it as two digits & "-" & day_of_month of it as two digits) of date (local time zone) of it) of modification time of files whose (name of it starts with "ACROBAT.EXE" AND modification time of it = (maximum of modification times of files whose (name of it starts with "ACROBAT.EXE") of folder "C:\Windows\Prefetch\")) of folders "C:\Windows\Prefetch\" else "Never Run"

Produces the date I want and on others it produces the date plus another line saying I have an error "singular expression refers to non-unique object’.

I had issues with that on a first draft where I didn’t constrain against a comparison of the max modification time, but unless there’s two files with the exact same time (why/how?) I don’t see why I would have this error. I have several other forms of this relevance for other apps that do only one folder existence check and they never error even though they have multiple files to compare. And the weird thing is that the relevance does produce the date I want, it’s just with an error tacked on… and I thought I had written this with only one output.

Any advice would be appreciated, thanks.

I think your problem is in the first section where you are trying to establish whether Acrobat DC exists.

A cleaner, more concise way to do this is

exists (folders "Acrobat DC" of folders "Adobe" of (program files x32 folders ; program files x64 folders))

That evaluates to False on my machine, so I can’t test the remainder - however I have looked through it and tried to make the choice of singular or plural relevance to return a single value (so the if/else always returns a single string)

 if
   not exists 
   (
     folders "Acrobat DC" of folders "Adobe" of 
     (
       program files x32 folders ; program files x64 folders
     )
   )
 then
   "Not Installed" 
 else
   if
     exists 
     (
       file "ACROBAT.EXE" of folder "C:\Windows\Prefetch\"
     )
   then
     (
       (
         year of it as string & "-" & month of it as two digits & "-" & day_of_month of it as two digits
       )
       of date 
       (
         local time zone
       )
       of it
     )
     of modification time of file 
     whose
     (
       name of it as uppercase starts with "ACROBAT.EXE" 
      AND
       modification time of it = 
       (
         maximum of modification times of files 
         whose
         (
           name of itas uppercase starts with "ACROBAT.EXE"
         )
         of folder "C:\Windows\Prefetch\"
       )
     )
     of folder "C:\Windows\Prefetch\" 
   else
     "Never Run"
1 Like

That is certainly more efficient, but unfortunately it’s not alleviating the error.

I’m pretty sure the key is somehow tied to the fact that I’m getting a date output AND the error rather than just the error. It’s like it’s generating two outputs just because it’s checking against two places, even though I’m only asking for one output and constraining for it. All other relevance I’ve written similar to this that checks only one directory produces no errors.

The most annoying part is although the dates appear along with the errors in the result of the analysis in BESConsole, but in reports the only output is “not set”

I don’t have Acrobat but if I used Acrobat reader DC as an alternative, and using and using your orginal expression I think the issue can be tracked back to cases where the prefetch has more than 1 file so the last modified date is a plural result with the same value (as you inspecting across multiple files)

Q: if not exists (names of folders of folder "C:\Program Files\Adobe") whose (it = "Acrobat Reader DC") and not exists (names of folders of folder "C:\Program Files (x86)\Adobe") whose (it = "Acrobat Reader DC") then "Not Installed" else if exists (names of files of folder "C:\Windows\Prefetch\") whose (it starts with "ACRORD32.EXE") then ((year of it as string & "-" & month of it as two digits & "-" & day_of_month of it as two digits) of date (local time zone) of it) of modification time of files whose (name of it starts with "ACRORD32.EXE" AND modification time of it = (maximum of modification times of files whose (name of it starts with "ACRORD32.EXE") of folder "C:\Windows\Prefetch\")) of folders "C:\Windows\Prefetch\" else "Never Run"
A: 2022-08-04
E: Singular expression refers to non-unique object.


Q: if exists (names of files of folder "C:\Windows\Prefetch\") whose (it starts with "ACRORD32.EXE") then ((year of it as string & "-" & month of it as two digits & "-" & day_of_month of it as two digits) of date (local time zone) of it) of modification times of files whose (name of it starts with "ACRORD32.EXE" AND modification time of it = (maximum of modification times of files whose (name of it starts with "ACRORD32.EXE") of folder "C:\Windows\Prefetch\")) of folders "C:\Windows\Prefetch\" else "Never Run"
A: 2022-08-04
A: 2022-08-04
T: 203.930 ms
I: plural string

I’m wondering if another approach might work for you. If Acrobat is a registered application then maybe this might be an option?

If installed
Q: if (exists regapp "acrord32.exe") then (((year of it as string & "-" & month of it as two digits & "-" & day_of_month of it as two digits) of date (local time zone) of it) of (maximum of modification times of files whose (name of it as lowercase starts with (name of regapp "acrord32.exe") as lowercase) of folder "C:\Windows\Prefetch\") | "Never Run") else ("Not Installed")
A: 2022-08-04
T: 263.186 ms
I: singular string

If not Installed
Q: if (exists regapp "acrord32.exe") then (((year of it as string & "-" & month of it as two digits & "-" & day_of_month of it as two digits) of date (local time zone) of it) of (maximum of modification times of files whose (name of it as lowercase starts with (name of regapp "acrord32.exe") as lowercase) of folder "C:\Windows\Prefetch\") | "Never Run") else ("Not Installed")
A: Not Installed
T: 0.177 ms
I: singular string

If no file in the prefetch folder
Q: if (exists regapp "acrord32.exe") then (((year of it as string & "-" & month of it as two digits & "-" & day_of_month of it as two digits) of date (local time zone) of it) of (maximum of modification times of files whose (name of it as lowercase starts with (name of regapp "acrord32.exe") as lowercase) of folder "C:\Windows\Prefetch\") | "Never Run") else ("Not Installed")
A: Never Run
T: 44.756 ms
I: singular string

2 Likes

Thanks that does work. It was just weird because having the max was enough constraint on all the other apps, of which many had multiple prefetch files.

I recommend keeping relevance plural as much as possible to avoid the issue.

This should give you the newest one, and always a singular result if present:

unique values of (year of it as string & "-" & month of it as two digits & "-" & day_of_month of it as two digits) of dates (local time zone) of maxima of modification times of files whose(name of it as uppercase starts with "ACROBAT.EXE") of folders "Prefetch" of windows folders

As written, this relevance will never give an error because if any part doesn’t exist, it will just return <none> which is the equivalent of NOTHINGS

If you write plural relevance this way, you don’t need to do If/Then/Else checking first to check for existence. It is also more efficient this way, plus the first item to return NOTHING stops execution, so it only processes as far as it can before stopping.

If you want to force a string result, you can make it singular from plural at the very end, then use the PIPE to provide an alternative string result:

( unique value of (year of it as string & "-" & month of it as two digits & "-" & day_of_month of it as two digits) of dates (local time zone) of maxima of modification times of files whose(name of it as uppercase starts with "ACROBAT.EXE") of folders "Prefetch" of windows folders ) | "DoesNotExist"

You can actually string together many statements like this:

if (not exists regapps "acrord32.exe") then "Not Installed" else NULL | ( unique value of (year of it as string & "-" & month of it as two digits & "-" & day_of_month of it as two digits) of dates (local time zone) of maxima of modification times of files whose(name of it as uppercase starts with "ACROBAT.EXE") of folders "Prefetch" of windows folders ) | "Never Run"

The advantage of this is the detection of if acrobat is NOT installed is fully independent from the detection of when it was last run, but the relevance to detect when it was last run will only be evaluated if it is installed.

2 Likes

Thank you, that’s very good advice.

1 Like

I think this will throw an error on Windows x32 bit installs, which should not be a concern really these days, but something to make note of.

This can be avoided by doing the following instead:

exists folders "Acrobat DC" of folders "Adobe" of (program files folders ; native program files folders)

On 64bit windows, this will check both program files folders. On 32bit windows, which again, shouldn’t really exist anymore, it will check the same program files folder twice, which is a slight concern in terms of evaluation loop / disk access, but minimal.

If you had Windows XP or Netbooks, then 32bit Windows was a more significant concern. I hope no one has that to contend with today.

If program files x64 folders does NOT cause an error on 32bit windows, in that case, (program files x32 folders ; program files x64 folders) would be the most efficient approach on 32bit windows, but it must be plural, not singular.

2 Likes