简体   繁体   中英

How to call a Win32API function from Ruby?

I want to lock a file as MS Office applications do from a Ruby program so that deletions won't be allowed because "the file is opened on another program".

The Ruby standard library does not seem to be able to do that - I just tried flock() - so I'm trying to invoke the LockFileEx function.

fd = File.open("locked.file", File::RDWR|File::CREAT, 0644)
fd.write "this file to be locked"
import_array = %w(p i i i i i)
wapi = Win32API.new('kernel32', 'LockFileEx', import_array, "i")
wapi.call(fd, 1, 0, 0, 0, 0)

The wapi.call fails with a TypeError exception "Can't convert File into String".

What should I use as first item in import_array to represent the file handle ?

How do I pack the file descriptor into a String ? Where do I get the file descriptor structure ?

I'm using Ruby 1.9.3.

First, you have to map the Ruby file descriptor to a C runtime file descriptor. I'm not familiar enough with Ruby source to know how to do that; it may be an identity transform.

Second, you have to map the C runtime descriptor to a Win32 file handle. For this, you need _get_osfhandle .

Third, you need to fix your call to LockFileEx so that you actually pass a valid OVERLAPPED structure; NULL will NOT work.

The Ruby file locking mechanism is co-operative and relies on all parties knowing the convention of the Ruby lock file. Microsoft Office will not co-operate.

Instead I suggest that you get the file system to enforce the lock. Simply open the file with an exclusive lock using standard Ruby file handling mechanisms.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM