If you are like me and use a Mac as your primary system, you may have noticed launching a remote control program from the k1000 machine actions are next to impossible.


My environment is a mix of PC's and Mac's that we support with the Teamviewer 8.  Well this is quite easy to manage if my management system was a PC.  But I tend to like the BSD/Unix backbone of OS X.  So I did a ton of research in finding out how can I make this work...

Let me preface this article with the statement: "I am not a programmer"

Everything listed below are things I have found from other sites and information obtained from individuals.  I put the source of my information everywhere I could.

The target audience is anyone trying to use the k1000 "Machine Actions" with a Mac OS X system.  As stated above my example is to add a mechanism to launch TeamViewer 8 from one of those actions.  It can easily be adapted to launch pretty much anything on a Mac.  


I hope someone may find this useful.




1)  Since the Machine Actions are basically URL pointers I needed to find away to pass a URL to launch the application associated.  This was done by creating a custom URL Scheme.  I found a great deal of information and a how to from macosxautomation.com. 


            a) Use Applescript Editor to create a new Application.  I did this by opening Applescript Editor and typing a comment such as "--test" and then "Save as" and chose Application.

            b) Edit the Info.plist property list with "Textedit".  To access the info.plist file, right click on the .app you created and choose "Show Package Contents".  This will open a new window where you can open the "Contents" folder revealing the info.plist file.

            c) Add the following to the info.plist. The BLUE parts you can change to create the scheme:// that you want.






            <key> CFBundleURLTypes</key>




                                    <string>TeamViewer Launcher</string>








2) Now that we have told the Application about our new URL Scheme we need to write the script to perform the actions.  Here is the script I used to parse the URL info and call the correct program and pass the variable on.  I got most of my info here from Nik's Blog at http://nik.me


on run


       do shell script "/Applications/TeamViewer\\ 8/TeamViewer.app/Contents/MacOS/TeamViewer -i \\ " & ARG1


end run


on open location sURL

       set myURLObject to newURI(sURL)


       do shell script "/Applications/TeamViewer\\ 8/TeamViewer.app/Contents/MacOS/TeamViewer -i \\ " & location of myURLObject & return


--This calls the actual application and passes the variables (IP Address of host in this case)



end open location



(* newURI(): URI Object Initialization Script


   This returns a URL script object, containing properties for the URL scheme, location, and arguments, as passed through an HTML-encoded URL. *)


on newURI(u)

       script uriObject


              property rawURL : missing value

              property scheme : missing value

              property location : missing value

              property args : {}


              (* initialize()       

       This handler initializes the URL object, breaking it out into its constituent parts, and assigns them to the various script object properties. It will also replace and overwrite any existing URL properties on the script object *)


              on initialize(aURL)



                            set u to aURL

                            -- Break out the URL into its various components

                            set theSplitURL to splitURL(aURL)

                            log result

                            --Get the URI-Scheme from the URI

                            set scheme to item 1 of theSplitURL

                            -- Get the location from the URI

                            set location to (decode_text(item 2 of theSplitURL))


                            -- parse arguments

                            --if item 2 of theSplitURL is not missing value then

                            --     set args to argsToRecord(item 3 of theSplitURL)

                            --end if


                            -- All went well, let's reset our text item delimiters and send back the arguments

                            set AppleScript's text item delimiters to ""

                            return {scheme:scheme, location:location, args:args}


                     on error errMsg number errNum

                            display alert errMsg & " (" & errNum & ")"

                            error number -128

                     end try

              end initialize




              (* Convert a URL into a record set *)

              on splitURL(theURL)


                     set text item delimiters to ":"

                     set theURI to text item 1 of theURL

                     set text item delimiters to ""

                     set uriN to (count of characters of theURI) + 1 -- account for the ":"

                     -- Get rid of the url protocol string


                     set pN to offset of (theURI & "://") in theURL -- is it a mailto:// style?


                     if pN > 0 then -- a URI:// url

                            set theURL to text (uriN + 3) through (count of characters of theURL) of theURL

                     else -- or just a URI: url

                            set theURL to text (uriN + 1) through (count of characters of theURL) of theURL

                     end if


                     -- See if there's any arguments being passed, pass 'em back if there are

                     set aN to offset of "?" in theURL

                     if aN = 1 then -- no base url, just arguments

                            return {missing value, (text (aN + 1) through (count of characters of theURL) of theURL)}

                     else if aN > 1 then

                            return {theURI, (text 1 through (aN - 1) of theURL), (text (aN + 1) through (count of characters of theURL) of theURL)}


                            --return {theURI, theURL, theArgs} I have no need for extra Args

                            return {theURI, theURL}

                     end if


              end splitURL


              (* Splits ?key=value&key2=value2 type arguments from the URI and turns them into a {key:value,key2:value2} record set *)

              on argsToRecord(argString)

                     set rStringArray to {}

                     set text item delimiters to "&"

                     set splitArgs to text items of argString

                     set text item delimiters to "="


                     repeat with a in splitArgs

                            set ax to text items of a

                            set axKey to item 1 of ax

                            set axValue to my decode_text(item 2 of ax)

                            set rStringArray to rStringArray & {axKey & ":\"" & axValue & "\""}

                     end repeat

                     set text item delimiters to ","

                     run script ("return {" & rStringArray as string) & "}"

                     return result

              end argsToRecord


              (* Simple HTML decode routine *)

              on decode_text(encodedstring)

                     do shell script "echo " & quoted form of ¬

                            encodedstring & " | /usr/bin/ruby -r cgi -e \"print CGI.unescape(STDIN.read).gsub('+',' ')\""


              end decode_text


       end script

       tell uriObject to initialize(u)

       return uriObject

end newURI



3) Save the app.  Now that we have the main application script we can place the .app in the /Applications folder. 


4) I then edited the Machine Actions in the K1000 to pass "tvlaunch://KACE_HOST_IP"


This could be altered to pretty much launch anything from the K1000 Machine actions.  Please be cautious of risks however when launching Applescripts from a web browser.