The way to restrict a ruby program to just once occurrence o

I’m rewriting a vb app to ruby (in about a quarter of the code!). If I
ran
the same ruby program twice in parallel, the second instance should
exit.

In VB6 I could do this:

         If App.PrevInstance Then Exit Sub

Any ideas how this is done in ruby?

Ta muchly

Never mind, solved it (unless anybody knows a better way).

It’s a windows app, so:

require ‘Win32API’

SW_HIDE = 0
WS_OVERLAPPED = 0
WS_DISABLED = 0x08000000
WS_MINIMIZED = 0x20000000

def already_running
#
# Not sure of any other way to do this.
# Create a window with the title “i4FileProcessorHiddenWindow”.
When we come to run this program again,
# if there is already a window called
“i4FileProcessorHiddenWindow” then abort that instance.
# In this way, only one instance of the script should run.
#

findwindow = Win32API.new('user32','FindWindow', ['p','p'], 'L')
return true if findwindow.call("STATIC", 

“i4FileProcessorHiddenWindow”) != 0

createwindow = Win32API.new('user32', 'CreateWindowEx', ['l', 'p',

‘p’, ‘l’, ‘i’, ‘i’, ‘i’, ‘i’, ‘l’, ‘l’, ‘l’, ‘P’], ‘l’)
dwStyle = (WS_DISABLED | WS_MINIMIZED)
cw = createwindow.call( WS_OVERLAPPED, ‘STATIC’,
‘i4FileProcessorHiddenWindow’, dwStyle, 0, 0, 0, 0, 0, 0, 0, 0 )
show = Win32API.new(‘user32’, ‘ShowWindow’, [‘L’, ‘L’], ‘L’)
show.call(cw, SW_HIDE)

return false

end

On 07/11/06, Glenn S. [email protected] wrote:

Ta muchly

All the best
Glenn
Aylesbury, UK

Glenn S. wrote:

Ta muchly

------=_Part_1672_14945421.1162889756916–

Though not very “elegant”, here’s one approach…

When the script starts up, run the following line of code, within the
BEGIN block of a BEGIN…RESCUE…ENSURE construct.

def main()

begin
lockFile = File.new(“semaphore.lck”, File::CREAT|File::EXCL)

rescue Errno::EEXIST
puts(“Script is already running”)

rescue Exception => ex
puts(ex.message())

ensure
unless lockFile.nil?
lockFile.close()
File.delete(“semaphore.lck”)
end

end

end

main()

The first instance of the script will create and open the
“semaphore.lck” file. Running another instance of the script will cause
the preceeding line of code to throw a Errno::EEXIST error, which is
easy enough to trap. In that case, display a message to the user. The
ENSURE block will need to close and delete the semaphore file so that,
in the case of an abend, the file is not left hanging out there.
Otherwise, this will prevent the script from running again until
someone manually deletes the file.

You could also take a leaf out of unix tradition and simply write a
small file containing the current process ID into a temporary
directory. When your program starts, it checks for this file, and if a
corresponding running Ruby process is found then it can exit (perhaps
with a log message or something). If not, then the starting instance
would seem to be the only one.

  • james

Is it some kind of GUI app? I don’t know what toolkit you are using,
but I
do remember from my days as a wxPython jockey that the wxWidgets
toolkit
came with a api for doing exactly this: wx.SingleInstanceChecker. I
imagine
that there’s a win32 API that is used to do it, and that should be
available
to most other toolkits you might be using (e.g. I’m sure Java Swing has
something similar).

I imagine that such an API should be available even if it isn’t a GUI
app
(perhaps through Win32API) and I imagine that using this would be
slightly
cleaner than doing your own version.

Admittedly this isn’t much use as all I’m saying is, “yeah, there is a
way
to do this” without providing much details…

Sorry

Muz

I thought that, the problem being what if the other ruby program crashed
without removing the file? I guessed the file would remain. I suppose
the
check against whether or not the existing pid was a ruby program would
mostly remove this problem, but it seemed imperfect. Then again, who’s
to
say my solution is…!

On 07/11/06, James A. [email protected] wrote:

On 11/7/06, Murray S. [email protected] wrote:

Sorry

# if there is already a window called
dwStyle = (WS_DISABLED | WS_MINIMIZED)

I’m rewriting a vb app to ruby (in about a quarter of the
Any ideas how this is done in ruby?
Glenn

All the best
Glenn
Aylesbury, UK