Get the current working directory of process with a pid programmatically on OS X - objective-c

Is there a way to get the current working directory of a process using it's PID programmatically on OS X?
Cocoa, Carbon, or AppleScript are all acceptable.
It is not acceptable to send "pwd" to the current terminal window/tab (Do not want to affect the workspace).
The linux command "pwdx" also is also unacceptable (just in case you read over the "Cocoa" part)

On 10.5 and later:
lsof -a -p $PID -d cwd -Fn
(Prefix with sudo if the process is owned by root.)

The following AppleScript is a partial solution for your problem. Given the UNIX pid in the variable thePID it first gets the name of the process. It then sends the do shell script command to the application process which will result in a child shell process being spawned. The child process inherits the current directory which can then be determined by running the pwd command.
tell application "System Events"
set theName to name of first process whose unix id is thePID
end tell
tell application theName
do shell script "/bin/pwd"
end tell
The script does not work for processes that do not link to the AppleEvent framework (e.g., pure POSIX processes).

Related

Run Method everyday at certain time

I am writing a menu bar application, I need to run a method every day at a certian time. I would like it to run even if the user is not logged in. I know I need to create a helper tool registering it with launchd. Is there a good tutorial on this? I'm not new to programing but I am new to using helper tools and launched. I have been doing some reading and came across SMJob, and I know I can use it to create helper tools just not how to use it. I just need some direction with this.
Take a look at Daemons and Services Programming Guide
The solution is to create some command line utility, make launchd plist file in the /Library/LaunchDaemons directory (note that it must be owned by root:wheel and have 0644 mode) and load job via command sudo launchctl load -w /Library/LaunchDaemons/your.plist (flag -w forces your job to launch at every boot). For the running your job periodically set StartInterval or StartCalendarInterval key in your plist (see "Creating Launch Daemons and Agents" -> "Creating a launchd Property List File" -> "Running a Job Periodically" in the guide for the example")

How to set default application for specific file types in Mac OS X?

In Mac OSX lion, I'm trying to set default application for specific file types.
Using the below apple script, we can set the default application for the specific "file.abc".
tell application "System Events"
set default application of file "/Users/test/Desktop/file.abc" to "/Applications/TextEdit.app"
end tell
But I want to set the same application as default for all the files having the filetype or extension as "abc".
I have tried the following to get it done. It added an entry in <HOME>/Library/Preferences/com.apple.LaunchServices.plist. But the files are not opened with the specified application.
defaults write com.apple.LaunchServices LSHandlers -array-add "<dict><key>LSHandlerContentTag</key><string>abc</string><key>LSHandlerContentTagClass</key><string>public.abc</string><key>LSHandlerRoleAll</key><string>com.apple.textedit</string></dict>"
Hope somebody knows what i m missing to achieve it.
Answer Found :
defaults write com.apple.LaunchServices LSHandlers -array-add "<dict><key>LSHandlerContentTag</key><string>ugurugu</string><key>LSHandlerContentTagClass</key><string>public.filename-extension</string><key>LSHandlerRoleAll</key<string>org.videolan.vlc</string></dict>"
/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -kill -r -domain local -domain system -domain user
Maybe you're doing nothing wrong but that the com.apple.launchservices file just needs to be reloaded. You can logout, wait a few minutes or force launchservices to restart. In the following example I say that public.comma-separated-values-text files (note:This doesn't mean that every CSV file is this content-type) must be opened with TextEdit instead of Excel.
do shell script "defaults write com.apple.LaunchServices LSHandlers -array-add '{ LSHandlerContentType = \"public.comma-separated-values-text\"; LSHandlerRoleAll = \"com.apple.TextEdit\"; }'"
do shell script "/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -kill -r -domain local -domain system -domain user"
I'm not sure if you're only trying to do this programmatically. Are you?
Otherwise:
On the file, choose "get info", and under "open with" select the name of the application.
Click on the button "Change All"
You might want to take a look at RCDefaultApp and its source code. It's a program that lets you set which file types are opened by which apps in Launch Services.

Detect file in use by other process

On windows and such I used to use a trick to find out of a file is currently in use (written specifically).
I use to open the file for writing and if it failed most likey another process is busy accessing it.
Sadly these trick (using C OPEN with exclusive lock for writing) doesn't work on my Mac. While my curl in a terminal is still writing my -fileBusy() check fails.
fcnt call on the fd with F_GETLK doesn't reveal any locking as well.
Is there any chance for me to detect if a file is in use by another process?
Ps> listening for fsevents can't be done because my app launches after the is created by the other app / process.
Apple confirmed via email that the solution described in the link below is a valid one and not considered a private API.
More information:
http://lists.apple.com/archives/cocoa-dev/2010/May/msg01455.html
You could try running the following shell command using NSTask:
lsof -Fc path/to/thefile
That will give you the process ID and name of any process(es) that have thefile open.

applescript utility problems/bash/ process detection

I made a small automator app to help me launch and end apache ( another for mysql), so that I don't have to go to the terminal and do it ( yes I'm that lazy).
now here is the applescript I use for it:
on run {input, parameters}
set apache2state to (do shell script "/bin/ps -arx |/usr/bin/grep apache2 |wc -l")
repeat until apache2state does not start with " "
set apache2state to text 2 thru -1 of apache2state
end repeat
if apache2state is equal to "3" then
do shell script "/opt/local/bin/port load apache2" with administrator privileges
else
do shell script "/opt/local/bin/port unload apache2" with administrator privileges
end if
end run
Now this works, except for the fact that I'm actually comparing to integer values that are relative to the number of processes that apache is running.. so it's not really reliable.
Is there a better way to test if apache (and mysql, I have another script just the same) is running. Problem is that when they are shut off the shell command will return an integer value just the same ( and not just a 1 for the grep process..)
thanks
EDITED to specify thatthe solution up here worked badly because the grep would return any instance of the apache threads and any other process that said apache ( like tail -r /var/log/apache2/error.log for instance).
The running state of a service can be tested with the following command:
/sbin/service --test-if-configured-on "org.apache.httpd"
This however might not work for services installed with MacPorts.
Also see the answer to the this question.
Since the command service is deprecated under Snow Leopard, you can alternatively use launchctl to obtain the running state of a service. The command can be invoked from AppleScript in the following way:
try
do shell script "/bin/launchctl list | grep -q org.apache.httpd" with administrator privileges
set apache2Running to true
on error
set apache2Running to false
end try

PSExec: How can I show a JPG file on a remote computer?

I need to start a document on a remote computer instead of an executable file, using PSExec.
I tried to provide the file name of a jpg file to psexec associated with the -c command to copy the file, but the message returned for documents (and not executables) is always "The system cannot find the file specified."
Anyone any ideas what the command-line for psexec should be?
Try to use the command:
cmd.exe /c START c:\path\to\document.jpg
Document must be on the remote computer, so you have to copy it there by other command before calling psexec.
Pick a program on that other machine that can show the JPEG and execute that, passing to it the path and name to the file you want to show.
As you've noticed, file associations doesn't work with remote execution like that, so you need to invoke the correct program instead.
In order to open a remote program and not only activate its process you have to use PSEXEC
with the -i (Interactive Mode) and MUST define the session number.
For example:
Usually on a Win7 host:
Console = Session 0
System = Session 1
User = Session 2
In order to activate and open notepad.exe on this remote Win 7 host use the following syntax:
psexec -i 2 \\ComputerName -u User -p Pass notepad.exe
Regards,
Shai Ziv
shaix.ziv#intel.com
This is the way that worked for me:
I've logged on to the via RDP:
I've copied a picture to the to "C:\Users<MyUserName>\Pictures\smiley.png"
I've opened a new powershell-window, typed "tasklist" and found out my windows session id (I simple took the highest session id I've found)
Back on my own PC:
I've downloaded PSTOOLS from https://download.sysinternals.com/files/PSTools.zip
I've unpacked PSTOOLS and placed it in "C:\Program Files\PSTools"
I've opened a new powershell-window and typed: cd "C:\Program Files\PSTools"
Finally i've started the remote PAINT with:
"C:\Program Files\PSTools\psexec" -s -i 4 "\\[RemoteComputerName]" "C:\Windows\system32\mspaint.exe" "C:\Users\[MyUserName]\Pictures\smiley.png"
P.S.: Don't forget to replace [RemoteComputerName] and [MyUserName]