2013-09-17 2 views
0

Я хочу заблокировать файл, как приложения MS Office, из программы Ruby, так что удаления не будут разрешены, потому что «файл открывается в другой программе».Как вызвать функцию Win32API из Ruby?

Стандартная библиотека Ruby, похоже, не в состоянии это сделать - я просто попробовал flock() - поэтому я пытаюсь вызвать функцию LockFileEx.

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) 

Ошибка wapi.call с исключением TypeError «Невозможно преобразовать файл в строку».

Что следует использовать в качестве первого элемента в import_array для представления дескриптора файла?

Как упаковать дескриптор файла в строку? Где я могу получить структуру дескриптора файла?

Я использую Ruby 1.9.3.

+1

Гораздо проще открыть файл для записи, с эксклюзивным режимом совместного доступа, а затем не писать на него. Вы можете сделать это со стандартной обработкой файлов Ruby. Абсолютно не нужно совать с Win32API низкоуровневым материалом. Просто используйте стандартный код Ruby для открытия файла (не знаю, что это такое, не знаете Ruby). В конечном итоге это будет отображаться до вызова функции API Win32 CreateFile. Вы не можете ожидать, что 'flock' будет работать, поскольку это кооперативный механизм. И не ожидайте, что Office поймет файлы блокировки Ruby. –

+0

@ DavidHeffenan Цель состоит в том, чтобы имитировать поведение MS Office, в системе, где она недоступна (и ни MS Journal), чтобы написать тест. Открытие файла в режиме эксклюзивного совместного использования 'File :: EXCL' делает трюк. Пожалуйста, напишите ответ. Благодарю. – philant

+0

@DavidHeffernan пропустил «r» на ваше имя, извините. – philant

ответ

2

Механизм блокировки файлов Ruby является кооперативным и полагается на все стороны, зная соглашение с файлом блокировки Ruby. Microsoft Office не будет сотрудничать.

Вместо этого я предлагаю вам заставить файловую систему обеспечить блокировку. Просто откройте файл с помощью эксклюзивной блокировки, используя стандартные механизмы обработки файлов Ruby.

2

Во-первых, вам необходимо сопоставить дескриптор файла Ruby с дескриптором файла времени выполнения C. Я не достаточно хорошо знаком с источником Ruby, чтобы знать, как это сделать; это может быть преобразованием идентичности.

Во-вторых, вам нужно сопоставить дескриптор времени выполнения C с дескриптором файла Win32. Для этого вам нужно _get_osfhandle.

В-третьих, вам нужно исправить свой звонок LockFileEx, чтобы вы фактически передали действительную структуру OVERLAPPED; NULL НЕ будет работать.

+0

1) да или объект дескриптора файла Ruby должен разрешить доступ к нему. 2) ОК 3) да, пропущено это на данный момент. спасибо – philant

Смежные вопросы