Applescript variable not usable in other script - variables

I have made an applescript that sets variable 'msshutdown' to yes and then shuts down the computer. Now I have another script exported as an application added as a login item that starts up the program 'MainStage' if 'msshutdown' is set to yes and afterwards sets 'msshutdown' to no.
This is all because I want the computer to don't launch any apps at login, unless I shut it down using the first script.
But it seems the second script can't find the variable 'msshutdown'. How do I make the second script read thew status of the variable in the first script and then edit it?
First script:
set msshutdown to yes
tell application "Finder"
shut down
end tell
Second script:
if msshutdown is yes then
tell application "MainStage 3"
activate
end tell
set msshutdown to no
end if

Easiest solution is to write the variable to a file, then read it when needed. A simple text file will do the job.
First Script:
writeVar("yes")
tell application "Finder"
shut down
end tell
on writeVar(theVar)
do shell script "echo " & quoted form of (theVar as text) & " > ~/varFile.txt"
end writeVar
Second Script:
if readVar() is "yes" then
tell application "MainStage 3"
activate
end tell
writeVar("no")
end if
on writeVar(theVar)
do shell script "echo " & quoted form of theVar & " > ~/varFile.txt"
end writeVar
on readVar()
do shell script "cat ~/varFile.txt"
end readVar

Save the script below into the ~/Libraries/Script Libraries folder with the name shutdownStore
use AppleScript version "2.3"
use scripting additions
property shutDownCacheName : "shutdownStore"
property shutdownCache : missing value
to saveShutDownStatus(theShutDownStatus)
set cachePath to ((path to library folder from user domain as text) & "caches:" & "net.mcusr." & my shutDownCacheName)
set shutdown of my shutdownCache to theShutDownStatus
store script my shutdownCache in cachePath replacing yes
end saveShutDownStatus
on loadShutDownStatusFromScriptCache()
set cachePath to ((path to library folder from user domain as text) & "caches:" & "net.mcusr." & my shutDownCacheName)
local script_cache
try
set my shutdownCache to load script alias cachePath
on error
script newScriptCache
property shutdown : false
end script
set my shutdownCache to newScriptCache
end try
return shutdown of my shutdownCache
end loadShutDownStatusFromScriptCache
on getShutDownStatus()
set last_shutDownStatus to loadShutDownStatusFromScriptCache()
return last_shutDownStatus
end getShutDownStatus
Use this from your scripts like I have modified them:
First Script:
use AppleScript version "2.3"
use scripting additions
use mss : script "shutdownStore"
set msshutdown to yes
saveShutDownStatus(msshutdown) of mss
tell application "Finder"
shut down
end tell
Second Script:
use AppleScript version "2.3"
use scripting additions
use mss : script "shutdownStore"
set msshutdown to getShutDownStatus() of mss
if msshutdown is yes then
tell application "MainStage 3"
activate
end tell
set msshutdown to no
saveShutDownStatus(msshutdown) of mss
end if

Related

Using AppleScript to programmatically create an AppleScript file in plain text format

I have an AppleScript that is used to programmatically create a test script file in one of these Office 2016 app folders:
~/Library/Application Scripts/com.microsoft.Excel
~/Library/Application Scripts/com.microsoft.Word
~/Library/Application Scripts/com.microsoft.Powerpoint
This is the test.scpt file content which is programmatically generated:
on handlerTest(thisPhrase)
say thisPhrase
end handlerTest
This test.scpt file contains a single handler which speaks the phrase passed to it.
When the script is created in one of these folders, I cannot see the content of the script file in Finder and calling the handler from a Microsoft Office app using the new VBA AppleScriptTask causes the Office app to crash. I think the script is being created as a byte-compiled file because it cannot be viewed in Finder as plain text.
If I then copy the script file generated programmatically by my script creator script to the Documents folder, the plain-text content of the script is viewable in Finder.
Now, if I copy the script file from the Documents folder back to the corresponding com.microsoft folder (without modifying it), I can now see the plain-text content in Finder and calling the handler using the VBA AppleScriptTask function works as expected. I don't understand how the format is apparently changing due to copy/paste actions?
How can I programmatically create the script file in the com.microsoft.xyz folder in plain text format?
Here is my VBA procedure:
Sub TestScript()
AppleScriptTask "test.scpt", "handlerTest", "hello world"
End Sub
Here is my example script creator script which programmatically creates a test.scpt file in the com.microsoft.Powerpoint scripting folder: (kudos to eliteproxy for the original source script)
property theFolders : {"~/Library/'Application Scripts'/com.microsoft.Powerpoint"}
try
tell application "Finder" to set targetFolder to (target of the front window) as alias
on error -- no window
set targetFolder to (choose folder)
end try
# build a parameter string from the folder list
set {tempTID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, space}
set {theFolders, AppleScript's text item delimiters} to {theFolders as text, tempTID}
do shell script "cd " & quoted form of POSIX path of targetFolder & "; mkdir -p " & theFolders
--Write the Script file if it does not exist
if ExistsFile("~/Library/'Application Scripts'/com.microsoft.Powerpoint/test.scpt") is false then
tell application "Finder"
--GET THE WORKING DIRECTORY FOR FILE COPY OF SCRIPT
get folder of (path to me) as Unicode text
set workingDir to POSIX path of result
--Write the new script in the current working directory
set textFile to workingDir & "test.scpt"
--Delete script if it exists
set posixPath to POSIX path of textFile as string
do shell script "rm -rf \"" & posixPath & "\""
--Create Script Interface file for Microsoft PowerPoint VBA Applications
set fd to open for access textFile with write permission
-- Create test handler which speaks the passed phrase parameter
write "on handlerTest(thisPhrase)" & linefeed to fd as «class utf8» starting at eof
write "say thisPhrase" & linefeed to fd as «class utf8» starting at eof
write "end handlerTest" & linefeed to fd as «class utf8» starting at eof
close access fd
--Copy the script file into the MACOS-Specific 'safe' folder
set fromPath to quoted form of POSIX path of (workingDir) & "test.scpt"
set toPath to quoted form of "~/Library/'Application Scripts'/com.microsoft.Powerpoint"
do shell script "cp -R " & fromPath & space & "~/Library/'Application Scripts'/com.microsoft.Powerpoint" with administrator privileges
end tell
end if
--Delete the temp script file from the working directory
set posixPath to POSIX path of textFile as string
do shell script "rm -rf \"" & posixPath & "\""
--Provide confirmation
set theAlertTitle to "TEST"
set theAlertMsg to "The script has been successfully installed."
display alert theAlertTitle message theAlertMsg as informational buttons {"OK"} default button "OK" cancel button "OK"
--For use when checking if a file exists
on ExistsFile(filePath)
tell application "System Events" to return (exists disk item filePath) and class of disk item filePath = file
end ExistsFile
I could be wrong in my interpretation of your question, but it appears as if you are looking to create file “Test.scpt” with your handler “handlerTest” as the code, in a folder named “com.microsoft.Excel” (for example). If that is all you are looking to achieve, I believe this solution should work for you...
script theHandler
on handlerTest(thisPhrase)
say thisPhrase
end handlerTest
end script
storeScript()
on storeScript()
set thisScript to store script theHandler in (path to home folder as text) ¬
& "Library:Application Scripts:com.microsoft.Excel:Test.scpt" replacing yes
end storeScript

VBA - Execute or Run .bat File Inside Macro

I have been attempting to automate a series of administrative events for some of the users where I work by creating scripts and macro's and so on..
These scripts and macros work great, however, I would like to make a the process even easier for the users by running a single batch file that will systematically execute the scripts and macros.
The batch file I currently have, calls all the scripts one by one, and the very last script opens one of the xlsm workbooks which contains a few macro's in it - and here is where the issue is - There are still scripts to be executed but they can only be executed once this workbook has executed all its macros.
So my initial thought was to test if the workbook is open, if it is, delay the execution of the next script by a minute or so, then test again and again... until it is closed.. Then I thought perhaps it would be easier to execute the next set of scripts (also in a batch file) from within a macro.
So, I have this code:
Sub Run_BAT()
Set obj = CreateObject("Wscript.Shell")
obj.Run Chr(34) & "X:\Test\" & "Termination Reports Scripts\" & "Execute_Terminations.bat" & Chr(34), 0, True
Set obj = Nothing
End Sub
Which gives me an error:
Permission Denied
Then there's this code:
Sub WriteAndRunBatFile()
Call Shell("X:\Test\Termination Reports Scripts\Execute_Terminations.bat")
End Sub
Which gives me the error:
Invalid procedure call
Any and every single code sample that contains the "Shell" command gives this error.
Place your path to bat file in quotes:
Call Shell("cmd /c ""S:/somebatfile.bat""", vbNormalFocus)
Or
Call Shell("cmd.exe /C /K " & "ChDir X:\Test\Termination_Reports_Scripts && Execute_Terminations.bat", vbNormalFocus)
And yes, check permissions.
My theory is you're missing a reference in your application to the Windows Script Host Object Model.
In the VBA Editor, go to Tools, References, make sure that one's ticked.
It's not ticked by default for security reasons - imagine unintended access to the command prompt in every instance of a Microsoft Office application...!
(1) Check permission of user of that X directory.
(2) Test the code by removing spaces from directory name.
Also try the following code (Please try it by removing spaces from directory name).
Sub Button1_Click()
Call Shell("CMD.EXE /C " & "X:\Test\Termination_Reports_Scripts\Execute_Terminations.bat")
End Sub

Rest of AppleScript is ignored when I use a variable in posix path

I'm using AppleScript in Automator to copy a page's source and save it to a file. For some reason when I use a variable (titleVal) in the posix path, the rest of my code in my loop is ignored, including the file that never gets written.
I updated the code before with my full AppleScript in case it has to do with more than the few lines I had before. I'm using Automator with specified Finder items in this order: "urlList.txt" and fileList.txt".
on run {input, parameters}
set updateCount to 0
read (item 1 of input)
set ps to paragraphs of the result
set tot to count ps
set TLFile to (("Users:Admin:Desktop:download captions:") as text) & "fileList.txt"
set TLLines to paragraphs of (read file TLFile as «class utf8»)
tell application "Safari"
reopen
activate
end tell
repeat with i from 1 to tot
set p to item i of ps
if p is not "" then
try
tell application "Safari"
tell front window
set r to make new tab with properties {URL:"https://www.youtube.com/timedtext_editor?v=" & p & "&lang=en&name=&kind=&contributor_id=0&bl=vmp&action_view_track=1"}
set current tab to r
set titleVal to item i of TLLines
set updateCount to updateCount + 1
do shell script "echo The value: " & updateCount
delay 2
do JavaScript "document.getElementById('movie_player').outerHTML = ''" in current tab
do JavaScript "document.getElementById('creator-page-sidebar').outerHTML = ''" in current tab
do JavaScript "document.getElementById('footer').outerHTML = ''" in current tab
delay 3
do JavaScript "document.getElementsByClassName('yt-uix-button yt-uix-button-size-default yt-uix-button-default action-track-button flip yt-uix-menu-trigger')[0].click()" in current tab
delay 1
do JavaScript "document.getElementById('aria-menu-id-2').getElementsByTagName('ul')[0].getElementsByTagName('li')[5].getElementsByTagName('a')[0].click()" in current tab
delay 4
-- using a variable in path1 is where it screws up. try changing it to another variable value and it will have the same effect.
set myString to source of current tab
set path1 to "/Users/Admin/Desktop/download captions/downloadedCaptions/" & titleVal & ".srt"
say path1
set newFile to POSIX file path1
--set newFile to POSIX file "/Users/Admin/Desktop/download captions/downloadedCaptions/test.xml.srt"
open for access newFile with write permission
write myString to newFile
close access newFile
-- i have exit repeat here to only test the first loop
exit repeat
end tell
end tell
end try
end if
end repeat
end run
Without a variable works fine, but I need the variable to make the script work properly in a loop. I've checked the value of the var. I also tried "& quoted form of titleVal &".
Update: When I remove the try/end try as suggested to get the error, the error is:
The action “Run AppleScript” encountered an error: “Safari got an error: Can’t get POSIX file "/Users/Admin/Desktop/download captions/downloadedCaptions/test.srt" of window 1.”
The error occurs because you are going to write the file in the tell window block of Safari which cannot work.
I recommend to use a separate handler. Put the on writeFile handler outside of the on run handler. I added reliable error handling and the data are saved UTF-8 encoded.
on writeFile(theData, fileName)
set newFile to "/Users/Admin/Desktop/download captions/downloadedCaptions/" & fileName & ".srt"
try
set fileDescriptor to open for access newFile with write permission
write theData to fileDescriptor as «class utf8»
close access fileDescriptor
on error
try
close access newFile
end try
end try
end writeFile
and call it (replace the part of your code from delay 4 to the end)
delay 4
-- using a variable in path1 is where it screws up. try changing it to another variable value and it will have the same effect.
set myString to source of current tab
my writeFile(myString, titleVal)
exit repeat
end tell
end tell
end try
end if
end repeat
end run
This was fixed very easily by changing one line:
set newFile to POSIX file path1
to:
set newFile to (path1 as POSIX file)
But I don't know why. Seems like a bug since it worked without the variable. Please provide any details in the comments why this works over the original set newFile line.

Copy directory of current window to clipboard on Mac

Is it possible to copy the full directory of the current active window on Mac?
e.g. say I have example.txt open in Sublime Text, can I execute an Apple Script that will grab the full path of that file? (without going to Finder).
The result would be that /Users/Bob/Dropbox/example.txt would then be in my clipboard.
You could assign a shortcut to a script like this:
try
tell application (path to frontmost application as text)
set the clipboard to (path of document 1) as text
end tell
on error
try
tell application "System Events" to tell (process 1 where frontmost is true)
value of attribute "AXDocument" of window 1
end tell
do shell script "ruby -rcgi -e 'print CGI.unescape ARGV[0][16..-1]' " & quoted form of result
set the clipboard to result
end try
end try
The first method didn't work with Preview, TextMate 2, Sublime Text, or iChm, and the second method didn't work with Acorn.

How to tell the difference between a VBscript is run from command line or by clicking it in a window?

All I want to do is differentiate between the program being run by the command line or by clicking the test.vbs file in a window.
If you run the script by typing C:\testFolder\test.vbs in a command prompt, then I want the program to run differently than if you double clicked test.vbs in the testFolder.
Is there some system variable that I can use to differentiate between the two scenarios? I first attempted to use WScript.Fullname to determine if the pathname ended in cscript or wscript. But that didn't work so well.
Any ideas are greatly appreciated.
You could try something like this:
Set WshShell = CreateObject("WScript.Shell")
Set objEnv = WshShell.Environment("Process")
msgbox objenv("PROMPT")
In general PROMPT will be set to something like $P$G when run from a command prompt, but left blank when you run the .VBS file directly.
If you want to test against WScript.FullName, you can use InStr with vbTextCompare so that the match is case-insensitive.
If InStr(1, WScript.FullName, "cscript", vbTextCompare) Then
WScript.Echo "Console"
ElseIf InStr(1, WScript.FullName, "wscript", vbTextCompare) Then
WScript.Echo "Windows"
Else
WScript.Echo "???"
End If
i=(instrrev(ucase(WScript.FullName),"CSCRIPT")<>0)
returns -1 if running cscript, 0 if running wscript