Add an AppleScript commands for a scriptable application - objective-c

Is there any way to add additional AppleScript command, other than those listed in its documentation, to a scriptable application in mac os?
There are many events that application has but the script command for them is not listed. Is there any other way to send those commands to scriptable application?
I found ScriptingBridge framework, but it seems framework is only an objc wrapper to apple script.

No, to do this you would have to change the code of the application and of course you can't do that. How an application responds to applescript commands is hard-coded into the program. However there is another approach. You could use gui scripting which means you can simulate mouse clicks and stuff on menu items, buttons etc. which may give you the ability to applescript what you need. Without more info about your specific task it's hard to give a solid suggestion though.

Related

Is there a way to embed a debugger in a vb.net application?

There is a program/service running on different systems executing vb.net scripts.
The application running and managing the scripts is also written in vb.net.
I want to implement the option to debug the scripts directly on the different systems the scripts are running on.
So I am looking for a debugger that can be embedded in a vb.net application.
Ideally the solution would provide code highlighting, Watches, Stepping through the code,
a way to easily add libraries.
A colleague told me there is a way of embedding VS Code in an application, yet I have not found a way to implement the described requirements.

How can I use a UWP Class Library for scripting?

I have a UWP Class Library project (written in C#) with some useful utility classes and functions. I want to create a script that uses these classes and functions and runs a few times a day automatically. What is the best way to achieve this?
Should I create an app? If so how can I make it run a few times a day?
Should I create a classic console exe program and run it using a script? If yes, can console apps use UWP class libraries?
Should I create a Windows Runtime Component with background task?
Or some other solution?
Assuming that you're definition of "scripting" can be stretched to mean "run an app" there's lots you can do. If you want something that will be seen as a more traditional script then the best you can do is compile the code in a standard .Net class library (not a UWP one) and then call it from a PowerShell script. If you can run apps then there are a few options and the most appropriate will probably depend on the device they're running on, how often you want them to run, and what they actually do.
As you're talking about a UWP app we should allow for it running on different "device families". The easiest way to run on different devices (desktop & phone, etc.) is to have a periodic background task. At time intervals defined by you it will try and run. Subject to connectivity, power, etc.
Because you said a console app was an option then you're probably really only interested in a desktop/PC environment. That's where there's the most options.
Firstly, if your code uses UWP/Win10 specific APIs then compiling into a console app probably isn't possible without changing the code. I do many things like you describe in the question and use console apps for this as I find them the simplest to work with.
If you're going to change code, consider moving to using Portable Class Libraries as you'll then be able to link to that code from many different types of app--including traditional desktop and UWP apps.
I'd avoid creating a runtime component unless you really need to as there are lots of potential gotchas.
You can run any app from the Task Scheduler but launching UWP apps is tricky.
You can launch a regular app or script by setting the action of the task to be the exe. (or the exe and passing the script file as a parameter.)
Apps from the store don't have an EXE you can just launch so you need to do a bit more. They can only be launched by the Windows Shell. But, fortunately, there's a way to do this. Have your task start explorer.exe (You'll find it in C:\Windows) and then add the argument shell:AppsFolder\[app-PFN]!App.
Where [app-PFN] is the Product Family Name of the app. You can find the values of all the installed apps on your machine by looking at "C:\Users[username]\AppData\Local\Packages\"
So, you can use this to launch the store app.
shell:AppsFolder\Microsoft.WindowsStore_8wekyb3d8bbwe!App

How to launch and communicate with a window-less and console-less process from a cocoa app?

I am working with the QuickTime API and need to perform a few lengthy (as in hours) operations in the background. Unfortunately, it is not multi-thread friendly, so I am falling back to perform the tasks in a separate process, so all QuickTime related calls can happen in its main thread.
After launching it, I need a way of getting feedback on its progress, since the operations can take very long.
I am unsure of how to do this, specifically:
Should the separate process be compiled as another cocoa app or a command line tool?
How to launch it from the main cocoa app?
How to periodically get an object from it to get status information?
How to determine when it finished?
How to avoid showing a window/console when called?
How to have it part of the .app bundle so that it does not appear as a separate executable to the user?
These are really 6+ questions, but they are very related and very specific, and I think anyone needing to launch external processes (instead of spawning worker threads) can benefit from their answers. Generic code examples would be very helpful.
If it is possible, then implement the functionality in a command line tool, or another form of GUI-less application. For Cocoa applications it is possible to prevent them appearing on the Dock or in the Force Quit dialog, however a command line tool is a single binary file which does that anyway, so that would probably be a better way.
In terms of launching the tool, NSTask & NSPipe are your friends in this endeavour. The tool can definitely be kept inside your main Application's bundle, inside the Resources directory or some such, and then launched when needed. You can use the pipe to communicate back and forth.
I don't have any example code to hand, and its been a long while since I've had occasion to use either of these classes so the information I can give is limited, but it should be enough to point you in the right direction.

How is it possible to access function of app A from app B

I was wondering if and in how many way an app can access specific funcions of another app.
for example
open an url in safari/firefox/chrome
run a javascript in current browser-tab
play/pause itunes
rename selected files in Finder
I am aware of the existence of applescript but i was wondering if that's the only way i have to interact with those apps and others
thanks
There are three main ways an app exposes its function to the outside world.
One is by supporting an URL protocol. To open an URL, just use NSWorkspace. There are many methods; if an app registers a specific protocol like x-my-app://some-work, you can just do
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:#"x-my-app://some-work"] ];
If you want to open an URL whose protocol (say http) is supported by many apps and if you want to specify which app to use, use openURLs:withAppBundleIdentifier:options:additionalEventParamDescriptor:launchIdentifiers:
.
Another is the System Services. With this, an app can add entries in the Service menu and in the context menu of other apps; you can also call it programmatically.
Otherwise, it's via Apple events. Applescript is one way to deal with them, but not the only one. It's just a language to issue Apple events. There are many ways to deal with Apple events from Cocoa, see this detailed document by Apple.
Basically, an app can export its internal as an object-oriented manner (which is not just its Objective-C hierarchy; you can control how much of its internal objects and methods you expose, etc.) by an sdef file. Then, another app can use this object-oriented system via Apple events.
To send and receive Apple events, you can of course construct them by hand, but you can use higher-level objects like
Applescript via NSAppleScript
Scripting Bridge
or AppScript.
To learn what kind of aspects an app exposes, just open the AppleScript Editor and choose the menu File → Open Dictionary, and choose an app.
Now, it's rather hard to use features of an app which the app does not expose via any of these methods. You still have a few workaround.
UI Scripting. This is done by sending Apple Events to a headless app called System Events which is one of the core program in OS X. This way, you can programmatically emulate clicking a button, choosing a menu, etc. of another app. So, almost whatever you can do using GUI with another app can be done programmatically from another app. To see the hierarchy of UI objects accessible from UI scripting, use a utility which comes with XCode tools, at
/Developer/Applications/Utilites/Accessibility Tools/Accessibility Inspector.app
This is very rudimentary but does the job; if you regularly use UI scripting, consider obtaining UI browser, as Zygmunt suggests.
Finally, if you want to use a non-GUI non-exposed feature of another app, you can inject a code into another app.
Just expanding on Yuji's answer. If you were forced to go the UI scripting path, there's a nice application to analyze the interface - hxxp://pfiddlesoft.com/uibrowser/. However, the examples you mentioned should expose some APIs.
I might also recommend using Sikuli hxxp://groups.csail.mit.edu/uid/sikuli/ as an IDE to script around user interface robustly.
For some applications usually coming from GNU/Linux there is D-BUS hxxp://en.wikipedia.org/wiki/D-Bus - although I haven't used it on a Mac on my own yet. And let me also quote Wikipedia about Cocoa "It is one of five major APIs available for Mac OS X; the others are Carbon, POSIX (for the BSD environment), X11 and Java." hxxp://en.wikipedia.org/wiki/Cocoa_%28API%29 That's just a loose tip for further exploration as Yuji has already explained Apple events that are key to your question.

Programmatically accessing an application through its UI

Earlier I asked a question about command-line parameters to automate processing of a file in InfoPath. I'll probably get the Tumbleweed badge for that one.
Instead of attempting a batch solution through the command line, can someone suggest a good resource for developing a solution that will open an application and then perform actions through the application's user interface like opening a file, printing it, and closing the file?
I've seen a legacy application do this in the past where it would open Attachmate and perform I/O operations through Attachmate's interface - but I never saw the code.
One constraint is that the process will be initiated from an existing .NET solution (i.e. processing 10,000 files). I am also unable to rely on traditional Office macros like those found in Excel - InfoPath does not appear to support them.
One option for automating a GUI based application is to use AutoIT. It will allow you to script the actions that are necessary for clicking menu interfaces, working with dialogs, etc.
Depending on your needs, you can create an AutoIT script on your dev machine, compile it to a standard EXE, and deploy it with the .NET project's compiled artifacts. To pass data to it, either you have your AutoIT script take command line parameters, or you have the .NET solution write a to a file with all the input file parameters and have the AutoIT script read in the file to process it. Based on the number you have in the question, I'd go with the option of writing to a file.
Since you are already on .NET you might want to give the new UI Automation framework a try. I haven't tried it yet, but it is supposed to work with WPF and native Win32 applications.
MSDN also has some samples: UI Automation Control Pattern Samples
Attachmate has a scripting language, an API and all kinds of other stuff to help with automating it. So this may not have been a typical application.
On the other hand, Attachmate products are (IMO) horrible to the extreme and I will go to great lengths to avoid working with them in the first place.