The macosxhints Forums

The macosxhints Forums (http://hintsforums.macworld.com/index.php)
-   OS X Developer (http://hintsforums.macworld.com/forumdisplay.php?f=27)
-   -   screen capture package (http://hintsforums.macworld.com/showthread.php?t=104482)

tlarkin 08-19-2009 12:28 PM

screen capture package
 
Well,

I have been kind of asked to look into creating a package that will take screen shots every so often. So I want to do it with built in tools, but I have not really ever developed something into an application before for OS X.

I am looking at the screenshot binary in /usr/sbin/screencapture so this will be easy to script out. However, the documentation is really lacking.

So I would like to make some sort of installer, probably in a pkg that installs a script, and then sets a launchd item to run the script every 15 minutes (just tossing that number out there) and then starts logging screen shots into a specific folder that I choose.

This seems easy to do, but like I said, I have never really wrapped up launchd items and shell scripts into a package before, so I guess I may need some hand holding - you know in a completely platonic way of course :eek:

Also, if there is a better way to implement this other than creating a launchd item that runs a few liner script every so often and then dumps the screen shots in a specific folder let me know, I would love to hear it.

I think I would like the installer to allow the person installing it to also choose the output directory to which these screen shots are saved.

There is a product that does this, but it is like $40 per a license and well we have 6,000 macbooks and we aren't going to spend $40 x 6,000 for something like this when I can just write it myself.

Thanks in advance for any and all help~!

tom

regulus6633 08-19-2009 02:34 PM

I think that creating a launchd item that runs a script which uses the screencapture executable is the way to go. I can't think of a better way. Here's how I would implement it.

The easiest way to make an installer application is by writing an applescript application. Any files you need to install you just embed inside of the app, and then use applescript commands to copy them into the proper locations. For example, if you put your script in the Contents/Resources folder of the applescript then you can do the following in the applescript.
1. Create a folder inside the application support folder to hold anything you install (like the script)
Code:

set appFolderName to "myProgramName"
set applicationSupportFolder to path to application support folder from user domain as text
tell application "Finder"
        if not (exists folder (applicationSupportFolder & appFolderName)) then make new folder at folder applicationSupportFolder with properties {name:appFolderName}
end tell

2. copy the embedded script into that application support folder
Code:

set scriptPath to (path to me as text) & "Contents:Resources:myScriptName"
set appFolderName to "myProgramName"
set applicationSupportFolder to path to application support folder from user domain as text

tell application "Finder"
        duplicate file scriptPath to folder (applicationSupportFolder & appFolderName)
end tell

3. To get the location where the images should be saved, the applescript installer can ask the user to choose a folder, then you write that path to a text file also in that application support folder. Your screencapture script reads that text file when it runs to get the save path.
Code:

set textFileName to "textFile.txt"
set appFolderName to "myProgramName"
set applicationSupportFolder to path to application support folder from user domain as text

set imageFolderPath to choose folder with prompt "Please choose the folder where you want the images saved."
set posix_imageFolderPath to POSIX path of imageFolderPath

writeTo(posix_imageFolderPath, (applicationSupportFolder & appFolderName & ":" & textFileName), false, string)


on writeTo(this_data, target_file, append_data, mode) -- append_data is true or false, mode is string etc. (no quotes around either)
        try
                set target_file to target_file as Unicode text
                if target_file does not contain ":" then set target_file to POSIX file target_file as Unicode text
                set the open_target_file to open for access file target_file with write permission
                if append_data is false then set eof of the open_target_file to 0
                write this_data to the open_target_file starting at eof as mode
                close access the open_target_file
                return true
        on error
                try
                        close access file open_target_file
                end try
                return false
        end try
end writeTo

4. launchd runs the script from that location. Here's example applescript code which will create and run the launchd process...
http://macscripter.net/viewtopic.php?id=20949

tlarkin 08-19-2009 04:47 PM

Thanks for your help, yes I want to do it all via shell scripts and launchd

I also want to create an uninstaller that will wipe out what is installed as this will be installed on a case by case basis. Also since this is a case by case basis it will probably be needed to be added into /Library/Launchagents so it can run when a user logs in, and it will probably require a reboot...

I found this link kind of explaining the deployment of packages through installers

http://www.osxgnu.org/info/osxpackages.html

I haven't had a chance to read up on it yet, been too busy at work today making packages..

regulus6633 08-19-2009 06:19 PM

Maybe you're not too familiar with writing applescripts so you should probably stick with what you found. I gave you virtually all the applescript code you would need so you just need to put it together in one app. And if you also want it to be an uninstaller then you would just pop up a dialog box at launch of the applescript asking if the user wanted to install or uninstall stuff... and then go from there. But again, what seems easy to me isn't what's easy for you. However, if you decide to pursue the applescript methodology I'll be around to help more.

NovaScotian 08-19-2009 07:44 PM

Really slick, Hank.

tlarkin 08-20-2009 08:34 AM

Quote:

Originally Posted by regulus6633 (Post 547765)
Maybe you're not too familiar with writing applescripts so you should probably stick with what you found. I gave you virtually all the applescript code you would need so you just need to put it together in one app. And if you also want it to be an uninstaller then you would just pop up a dialog box at launch of the applescript asking if the user wanted to install or uninstall stuff... and then go from there. But again, what seems easy to me isn't what's easy for you. However, if you decide to pursue the applescript methodology I'll be around to help more.

I am OK with apple script I just use shell scripting a lot more, and am more familiar with it. Plus I can invoke shell scripts with in apple scripts and vice versa now, so I could end up using both.

However, I cannot have the end user see any of this. I work at a school district with a 1:1 program so every high school kid has a macbook. Some of the administration people want to be able to install this on kids who are causing problems with the laptops and they want to be able to produce evidence. As these kids are smart, they like to delete their data when they are about to get caught. One of the educational side people found this program that is 40 bucks a pop that takes screen shots every so often and runs in the background. Well, when I was poking around in BASH I saw there was built in binary so why pay for something that I can probably build myself.

Thank you for all your help, and once I get CS4 packaged and began pushing it out this is my next project to tackle. So hopefully, starting next week I will have the basics down.

Thanks again

Tom

tlarkin 08-20-2009 01:44 PM

Well I got the beta script running, it is quite simple:

Code:

#!/bin/bash

#set variables for file name and save path

thedate=`/bin/date -u`
name=`/usr/bin/logname`
path="/private/var/hadmin/Desktop/screenshots"

#execute screen shot

/usr/sbin/screencapture -x $path/"$thedate $name sreen.png"

echo "screen captured"

exit 0

*note this is my test script and I have hard coded the path to where my local admin account lives, but I want that path to be set by the installer by the user.

So I want the installer to install the script in /Library/Scripts/Screens/screenshot.sh for example, then I want it to make a folder called "screen shots" in the desired path the installer chooses, and then also let the person insalling the package set the name variable. Then I want that installer to create a new package with all that information they input so they can deploy it.

Then the installer will deploy the launchd item, create the directories to store the file in it, it will also launch the plist file via launchctl and then set the permissions and ownerships to all items installed to root:admin 770 so only admin and root can access them.

Then make a script that will uninstall everything that I just did in case they want to take it off. I also want to make the interval of the screen shots set up the initial installer. So it will pump out how often the launchd item runs.

I want to keep it as simple as possible with the least amount of code as possible. I think if it all works out I will publish it for free off my site.

Thoughts?

regulus6633 08-20-2009 02:13 PM

Quote:

So I want the installer to install the script in /Library/Scripts/Screens/screenshot.sh
Look at the #2 code item where I showed you how to copy the embedded shell script to a location.
Quote:

then I want it to make a folder called "screen shots" in the desired path the installer chooses
This is #3 from my code.
Quote:

then also let the person insalling the package set the name variable
This is a simple display dialog box in applescript.
Quote:

Then the installer will deploy the launchd item, create the directories to store the file in it, it will also launch the plist file via launchctl
This is #4.

You have most of the installer code if you decide to use the applescript technique. If you go that route, put it together and post the code and I'll help you with anything you're still missing.

tlarkin 08-20-2009 02:23 PM

Thank you very much for your help. I will try to mess around with it this weekend...

I am a Linux/Unix guy so I love using shell when I can, and I am a bit new to Apple Script but not afraid to give it a whirl.

I will try some of this code, but I guess I am kind of not totally grasping how to wrap it all up in an application?

regulus6633 08-20-2009 02:35 PM

Any shell commands you need to run, for example you want to set root:admin 770, you can do via applescript using:
do shell script "the shell command"

After you write the applescript code, just save the applescript as an applescript application bundle. An application bundle creates a universal binary application that will run natively on both PPC and Intel macs. You can right-click on that to show package contents in the Finder and manually place the screen capture script inside of the Contents/Resources folder and then you'll have a complete installer application.

tlarkin 08-20-2009 02:46 PM

Quote:

Originally Posted by regulus6633 (Post 547906)
Any shell commands you need to run, for example you want to set root:admin 770, you can do via applescript using:
do shell script "the shell command"

After you write the applescript code, just save the applescript as an applescript application bundle. An application bundle creates a universal binary application that will run natively on both PPC and Intel macs. You can right-click on that to show package contents in the Finder and manually place the screen capture script inside of the Contents/Resources folder and then you'll have a complete installer application.

Ok, sweet, so when the user runs it and inputs the variables they choose, how do I then make those variables into a "finished" package to deploy. I am looking at installing this probably via ARD Admin on machines remotely so it being in the pkg format will make it a cinch.

Thanks again

regulus6633 08-20-2009 02:51 PM

Quote:

how do I then make those variables into a "finished" package
In my code item #3 I showed you how you can write any variables to a text file. Then your screen capture script can just read them from the text file.

tlarkin 08-20-2009 03:20 PM

Quote:

Originally Posted by regulus6633 (Post 547913)
In my code item #3 I showed you how you can write any variables to a text file. Then your screen capture script can just read them from the text file.

Hmm, I guess I imagined it a different way. That would work too. Thanks. I may just build a simple GUI for it now that I think about it, and have that GUI build the PKG file if possible for deployment with it using your scripts to configure it. If that makes any sense. I am not a software developer, so sorry if I am sounding ignorant.

I am thinking down the road how to easily change things on the fly and be able to deploy the package over the network, since this is for my 6,000 mac laptops and about 3,000 ish mac desktops at the school district I work for.

Thanks again for all your help

regulus6633 08-20-2009 03:54 PM

Since I showed you how to write a text file, you could create everything on-the-fly. In other words the installer could get the variables as I showed with the dialog boxes, create the code for the screen capture script using those variables, then write the screen capture script to disk as a text file all with the variables included in the generated script. Then use do shell script commands to turn that text file into a unix executable file, and run it using launchd. This would eliminate the need to embed the screen capture script with the installer and would also eliminate the need for the text file to hold the variables.

Try this. Save this code into script editor and run it. It will ask you for the input variables, create the shell script on your desktop, and make the shell script executable. It will demonstrate what I mean.
Code:

-- get the input information for the script
set theName to text returned of (display dialog "Enter a base name for the images" default answer "ScreenImage" buttons {"Cancel", "Continue"} default button 2 with icon note)
set imageFolderPath to choose folder with prompt "Please choose the folder where you want the images saved."
set posix_imageFolderPath to POSIX path of imageFolderPath

-- write the script
set scriptLocationPath to (path to desktop folder as text) & "screenCapture.sh"
set scriptText to "#!/bin/bash

thedate=`/bin/date -u`
name=\"" & theName & "\"
path=\"" & posix_imageFolderPath & "\"

#execute screen shot
/usr/sbin/screencapture -x $path/\"$thedate $name.png\"

echo \"screen captured\"
exit 0"
writeTo(scriptText, scriptLocationPath, false, string)

-- make the script executable
do shell script "chmod a+x " & quoted form of POSIX path of scriptLocationPath


(*================== SUBROUTINES ==================*)
on writeTo(this_data, target_file, append_data, mode) -- append_data is true or false, mode is string etc. (no quotes around either)
        try
                set target_file to target_file as Unicode text
                if target_file does not contain ":" then set target_file to POSIX file target_file as Unicode text
                set the open_target_file to open for access file target_file with write permission
                if append_data is false then set eof of the open_target_file to 0
                write this_data to the open_target_file starting at eof as mode
                close access the open_target_file
                return true
        on error
                try
                        close access file open_target_file
                end try
                return false
        end try
end writeTo


NovaScotian 08-20-2009 04:11 PM

This is great stuff, Hank. Be the making for a really good tutorial.

Adam

tlarkin 08-20-2009 04:23 PM

WOW

Thank you a lot! I edited the script to change some things around I think I want the short name in the file name. I was just told this could be used as evidence in court from one of the higher ups and I guess they want to cut down on gang activity...

This should turn out to be a fun project. I am learning stuff on this one.

thanks

Tom

regulus6633 08-20-2009 04:28 PM

Quote:

Originally Posted by NovaScotian (Post 547936)
This is great stuff, Hank. Be the making for a really good tutorial.

Adam

Thanks Adam. I've actually done something similar before. I wanted my parents to install something on their computer that runs under launchd. I administer stuff for them and the launchd process made that easier for me. Anyway, I made the installer and it worked perfect.

Glad to help Tom. Applescript is really powerful in that you can do almost anything with it. When combined with being able to execute shell commands it's limitless. Now you just have to look into my #4 above to incorporate the launchd stuff and polish up the code a little.

tlarkin 08-24-2009 10:31 AM

I see what you mean, and it did work, but how do I wrap all that info up into an actual application after the user sets those things. This can be ran as a PKG file I assume?

I also still need to create the launchd item, then load it, then force a reboot so it runs at start.

tlarkin 08-24-2009 04:37 PM

I saved the script as an application and it does ask for user input, how do I input that info into an existing package so it edits those contents and then can just be ran and installs the script, and the launchd item?

I am going to read through some of the developer white pages this week to see what to do. I think the apple script is pretty sweet though.

regulus6633 08-24-2009 06:37 PM

There's an applescript forum where you can get help specifically on applescript. It sounds like you need more help than I can give you by myself, so post your questions there.
http://macscripter.net/viewforum.php?id=2

If you want to learn more about applescript that website has tutorials. Go here to search the forums and search for "applescript for beginners". These tutorials are short and will teach you the basics. It's how I learned applescript.
http://macscripter.net/search.php

tlarkin 08-25-2009 11:25 AM

Quote:

Originally Posted by regulus6633 (Post 548518)
There's an applescript forum where you can get help specifically on applescript. It sounds like you need more help than I can give you by myself, so post your questions there.
http://macscripter.net/viewforum.php?id=2

If you want to learn more about applescript that website has tutorials. Go here to search the forums and search for "applescript for beginners". These tutorials are short and will teach you the basics. It's how I learned applescript.
http://macscripter.net/search.php

Again, many thanks for your help.

-Tom

tlarkin 08-25-2009 11:32 AM

Oh and I had to edit my script, it seems that the binary logname only captures what user is running the current process and if installed via ARD admin it will log it as root user, so I had to change that variable, here it is:

Code:

#!/bin/bash

#set variables for file name and save path

thedate=`/bin/date -u`
name=`/bin/ls ‑l /dev/console | cut ‑d " " ‑f 4`
path="/private/var/hadmin/Desktop/screenshots"

#execute screen shot

/usr/sbin/screencapture -x $path/"$thedate $name sreen.png"

echo "screen captured"

exit 0



All times are GMT -5. The time now is 05:35 AM.

Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2014, vBulletin Solutions, Inc.
Site design © IDG Consumer & SMB; individuals retain copyright of their postings
but consent to the possible use of their material in other areas of IDG Consumer & SMB.