win32-service 0.7.2 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGES +4 -0
- data/MANIFEST +2 -3
- data/README +75 -71
- data/Rakefile +7 -90
- data/doc/daemon.txt +7 -7
- data/doc/service.txt +8 -9
- data/examples/demo_daemon.rb +11 -11
- data/examples/demo_daemon_ctl.rb +3 -3
- data/examples/demo_services.rb +30 -30
- data/lib/win32/daemon.rb +345 -0
- data/lib/win32/service.rb +346 -434
- data/lib/win32/windows/constants.rb +137 -0
- data/lib/win32/windows/functions.rb +63 -0
- data/lib/win32/windows/helper.rb +41 -0
- data/lib/win32/windows/structs.rb +96 -0
- data/test/test_win32_daemon.rb +10 -13
- data/test/test_win32_service.rb +54 -48
- data/test/test_win32_service_configure.rb +19 -22
- data/test/test_win32_service_create.rb +129 -131
- data/test/test_win32_service_info.rb +8 -9
- data/test/test_win32_service_status.rb +2 -5
- data/win32-service.gemspec +5 -11
- metadata +61 -74
- data/ext/extconf.rb +0 -9
- data/ext/win32/daemon.c +0 -612
data/CHANGES
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
== 0.8.0 - ???
|
2
|
+
* Converted all code to use FFI. This includes the Daemon code, which means
|
3
|
+
that it also now works with JRuby.
|
4
|
+
|
1
5
|
== 0.7.2 - 7-Sep-2011
|
2
6
|
* Now works with mingw compiler by skipping __try and __finally if using
|
3
7
|
mingw, or using them with mingw if the seh.h header is found.
|
data/MANIFEST
CHANGED
@@ -5,15 +5,14 @@
|
|
5
5
|
* win32-service.gemspec
|
6
6
|
* doc/daemon.txt
|
7
7
|
* doc/service.txt
|
8
|
-
* ext/extconf.rb
|
9
|
-
* ext/win32/daemonc.c
|
10
8
|
* examples/demo_daemon.rb
|
11
9
|
* examples/demo_daemon_ctl.rb
|
12
10
|
* examples/demo_services.rb
|
13
11
|
* lib/win32/service.rb
|
12
|
+
* lib/win32/daemon.rb
|
14
13
|
* test/test_win32_daemon.rb
|
15
14
|
* test/test_win32_service_configure.rb
|
16
15
|
* test/test_win32_service_create.rb
|
17
16
|
* test/test_win32_service_info.rb
|
18
17
|
* test/test_win32_service_status.rb
|
19
|
-
* test/test_win32_service.rb
|
18
|
+
* test/test_win32_service.rb
|
data/README
CHANGED
@@ -1,71 +1,75 @@
|
|
1
|
-
== Description
|
2
|
-
The win32-service library allows you to control or create MS Windows services.
|
3
|
-
|
4
|
-
== Installation
|
5
|
-
gem install win32-service
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
1
|
+
== Description
|
2
|
+
The win32-service library allows you to control or create MS Windows services.
|
3
|
+
|
4
|
+
== Installation
|
5
|
+
gem install win32-service
|
6
|
+
|
7
|
+
== Synopsis
|
8
|
+
require 'win32/service'
|
9
|
+
|
10
|
+
# Iterate over the available services
|
11
|
+
Service.services do |service|
|
12
|
+
p service
|
13
|
+
end
|
14
|
+
|
15
|
+
== More Documentation
|
16
|
+
Please see the documentation in the 'doc' directory, or the gem documentation
|
17
|
+
that was installed when you installed this library as a gem.
|
18
|
+
|
19
|
+
== Known Issues
|
20
|
+
=== Problem:
|
21
|
+
Service.delete causes "Unable to delete: The specified service has been
|
22
|
+
marked for deletion."
|
23
|
+
|
24
|
+
=== Troubleshooting:
|
25
|
+
This can be caused by one of two things. Either you attempted to delete a
|
26
|
+
running service without stopping it first, or you have the Services
|
27
|
+
Administrative Tool (GUI) open. In the former case, the solution is to first
|
28
|
+
stop the service if it's running. In the latter, close the Services GUI
|
29
|
+
admin tool before deleting.
|
30
|
+
|
31
|
+
=== Problem:
|
32
|
+
Service.start causes, "The service did not respond to the start or control
|
33
|
+
request in a timely fashion."
|
34
|
+
|
35
|
+
=== Troubleshooting:
|
36
|
+
The best way to debug your services is to wrap your entire Daemon subclass
|
37
|
+
in a begin/end block and send error messages to a file. That should give a
|
38
|
+
good clue as to the nature of the problem. The most probable culprits are:
|
39
|
+
|
40
|
+
* You've tried to require a library that's not in your $LOAD_PATH. Make sure
|
41
|
+
that your require statements are inside the begin/rescue block so that you can
|
42
|
+
easily find those mistakes.
|
43
|
+
|
44
|
+
* Your have a bad binary path name. Be sure to use an absolute path name for
|
45
|
+
the binary path name, including the full path to the Ruby interpreter, e.g.
|
46
|
+
'c:\ruby\bin\ruby' instead of just 'ruby'.
|
47
|
+
|
48
|
+
* You've got a syntax error in your code somewhere.
|
49
|
+
|
50
|
+
== See Also
|
51
|
+
ruby-wmi
|
52
|
+
|
53
|
+
== Future Plans
|
54
|
+
Add service_session_change hook
|
55
|
+
|
56
|
+
== Copyright
|
57
|
+
(C) 2003-2013, Daniel J. Berger, All Rights Reserved
|
58
|
+
|
59
|
+
== License
|
60
|
+
Artistic 2.0
|
61
|
+
|
62
|
+
== Contributions
|
63
|
+
Although this library is free, please consider having your company
|
64
|
+
setup a gittip if used by your company professionally.
|
65
|
+
|
66
|
+
http://www.gittip.com/djberg96/
|
67
|
+
|
68
|
+
== Warranty
|
69
|
+
This package is provided "as is" and without any express or
|
70
|
+
implied warranties, including, without limitation, the implied
|
71
|
+
warranties of merchantability and fitness for a particular purpose.
|
72
|
+
|
73
|
+
== Authors
|
74
|
+
Daniel J. Berger
|
75
|
+
Park Heesob
|
data/Rakefile
CHANGED
@@ -2,105 +2,25 @@ require 'rake'
|
|
2
2
|
require 'rake/clean'
|
3
3
|
require 'rake/testtask'
|
4
4
|
require 'rbconfig'
|
5
|
-
include
|
5
|
+
include RbConfig
|
6
6
|
|
7
7
|
CLEAN.include(
|
8
|
-
'**/*.gem',
|
9
|
-
'**/*.rbc'
|
10
|
-
'**/*.o', # C object file
|
11
|
-
'**/*.log', # Ruby extension build log
|
12
|
-
'**/Makefile', # C Makefile
|
13
|
-
"**/*.so", # C shared object
|
14
|
-
"**/*.lib", # C build file
|
15
|
-
"**/*.def", # C build file
|
16
|
-
"**/*.pdb", # C build file
|
17
|
-
"**/*.exp", # C build file
|
18
|
-
"**/*.obj", # C build file
|
19
|
-
"**/*.log", # C build file
|
20
|
-
"lib/win32/ruby18", "lib/win32/ruby19", "lib/win32/daemon.rb"
|
8
|
+
'**/*.gem', # Gem files
|
9
|
+
'**/*.rbc' # Rubinius
|
21
10
|
)
|
22
11
|
|
23
|
-
desc "Build the win32-service library"
|
24
|
-
task :build => [:clean] do
|
25
|
-
make = CONFIG['host_os'] =~ /mingw|cygwin/i ? "make" : "nmake"
|
26
|
-
|
27
|
-
Dir.chdir('ext') do
|
28
|
-
ruby 'extconf.rb'
|
29
|
-
sh "#{make}"
|
30
|
-
FileUtils.cp('daemon.so', 'win32/daemon.so')
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
12
|
namespace 'gem' do
|
35
|
-
desc
|
13
|
+
desc "Create the win32-service gem"
|
36
14
|
task :create => [:clean] do
|
37
|
-
spec = eval(IO.read('win32-service.gemspec'))
|
15
|
+
spec = eval(IO.read('win32-service.gemspec'))
|
38
16
|
Gem::Builder.new(spec).build
|
39
17
|
end
|
40
18
|
|
41
|
-
desc
|
19
|
+
desc "Install the win32-service gem"
|
42
20
|
task :install => [:create] do
|
43
21
|
file = Dir['*.gem'].first
|
44
22
|
sh "gem install #{file}"
|
45
23
|
end
|
46
|
-
|
47
|
-
desc 'Build a binary gem'
|
48
|
-
task :binary => [:build] do
|
49
|
-
mkdir_p 'lib/win32'
|
50
|
-
mv 'ext/win32/daemon.so', 'lib/win32/daemon.so'
|
51
|
-
|
52
|
-
spec = eval(IO.read('win32-service.gemspec'))
|
53
|
-
spec.extensions = nil
|
54
|
-
spec.platform = Gem::Platform::CURRENT
|
55
|
-
|
56
|
-
spec.files = spec.files.reject{ |f| f.include?('ext') }
|
57
|
-
|
58
|
-
Gem::Builder.new(spec).build
|
59
|
-
end
|
60
|
-
|
61
|
-
# This is for me, not for you.
|
62
|
-
desc 'Create a gem with binaries for 1.8 and 1.9'
|
63
|
-
task :binaries => [:clean] do
|
64
|
-
make = CONFIG['host_os'] =~ /mingw|cygwin/i ? "make" : "nmake"
|
65
|
-
|
66
|
-
mkdir_p "lib/win32/ruby18"
|
67
|
-
mkdir_p "lib/win32/ruby19"
|
68
|
-
|
69
|
-
Dir.chdir('ext') do
|
70
|
-
# Ruby 1.8
|
71
|
-
sh "C:\\ruby187\\bin\\ruby extconf.rb"
|
72
|
-
sh "#{make}"
|
73
|
-
mv 'daemon.so', '../lib/win32/ruby18'
|
74
|
-
sh "#{make} distclean"
|
75
|
-
|
76
|
-
# Ruby 1.9
|
77
|
-
sh "C:\\ruby192\\bin\\ruby extconf.rb"
|
78
|
-
sh "#{make}"
|
79
|
-
mv 'daemon.so', '../lib/win32/ruby19'
|
80
|
-
end
|
81
|
-
|
82
|
-
File.open("lib/win32/daemon.rb", "w"){ |fh|
|
83
|
-
fh.puts "if RUBY_VERSION.to_f >= 1.9"
|
84
|
-
fh.puts " require 'win32/ruby19/daemon'"
|
85
|
-
fh.puts "else"
|
86
|
-
fh.puts " require 'win32/ruby18/daemon'"
|
87
|
-
fh.puts "end"
|
88
|
-
}
|
89
|
-
|
90
|
-
spec = eval(IO.read('win32-service.gemspec'))
|
91
|
-
spec.extensions = nil
|
92
|
-
spec.platform = Gem::Platform::CURRENT
|
93
|
-
|
94
|
-
spec.files = spec.files.reject{ |f| f.include?('ext') }
|
95
|
-
|
96
|
-
spec.files += [
|
97
|
-
'lib/win32/daemon.rb',
|
98
|
-
'lib/win32/ruby18/daemon.so',
|
99
|
-
'lib/win32/ruby19/daemon.so'
|
100
|
-
]
|
101
|
-
|
102
|
-
Gem::Builder.new(spec).build
|
103
|
-
end
|
104
24
|
end
|
105
25
|
|
106
26
|
namespace :example do
|
@@ -113,16 +33,13 @@ end
|
|
113
33
|
namespace 'test' do
|
114
34
|
desc 'Run all tests for the win32-service library'
|
115
35
|
Rake::TestTask.new('all') do |t|
|
116
|
-
task :all => :build
|
117
|
-
t.libs << 'ext'
|
118
36
|
t.verbose = true
|
119
37
|
t.warning = true
|
120
38
|
end
|
121
39
|
|
122
40
|
desc 'Run the tests for the Win32::Daemon class'
|
123
41
|
Rake::TestTask.new('daemon') do |t|
|
124
|
-
task :daemon
|
125
|
-
t.libs << 'ext'
|
42
|
+
task :daemon
|
126
43
|
t.verbose = true
|
127
44
|
t.warning = true
|
128
45
|
t.test_files = FileList['test/test_win32_daemon.rb']
|
data/doc/daemon.txt
CHANGED
@@ -128,21 +128,21 @@ Daemon::IDLE
|
|
128
128
|
|
129
129
|
= Known Bugs
|
130
130
|
None known. Please report any bugs you find on the Bug tracker at
|
131
|
-
|
131
|
+
https//github.com/djberg96/win32-service
|
132
132
|
|
133
133
|
= Future Plans
|
134
|
-
|
134
|
+
None at this time.
|
135
135
|
|
136
|
-
Suggestions welcome. Please
|
137
|
-
|
136
|
+
Suggestions welcome. Please post them on the github project page at
|
137
|
+
https//github.com/djberg96/win32-service
|
138
138
|
|
139
139
|
= Acknowledgements
|
140
140
|
Many thanks go to Patrick Hurley for providing the fix for the thread
|
141
|
-
blocking issue. Thanks also go to Kevin Burge for
|
142
|
-
service responsiveness issues.
|
141
|
+
blocking issue for the original C code. Thanks also go to Kevin Burge for
|
142
|
+
his patch that solved service responsiveness issues.
|
143
143
|
|
144
144
|
= Copyright
|
145
|
-
(C) 2003-
|
145
|
+
(C) 2003-2013 Daniel J. Berger, All Rights Reserved
|
146
146
|
|
147
147
|
= License
|
148
148
|
Artistic 2.0
|
data/doc/service.txt
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
An interface for MS Windows Services.
|
3
3
|
|
4
4
|
= Prerequisites
|
5
|
-
|
5
|
+
FFI 1.0 or later
|
6
6
|
|
7
7
|
This library is only supported for the Windows NT family of operating
|
8
8
|
systems, e.g. 2000, XP, 2003, etc. It is NOT supported (and won't
|
@@ -28,7 +28,7 @@
|
|
28
28
|
:dependencies => ['W32Time','Schedule']
|
29
29
|
:service_start_name => 'SomeDomain\\User',
|
30
30
|
:password => 'XXXXXXX',
|
31
|
-
:display_name => 'This is some service'
|
31
|
+
:display_name => 'This is some service'
|
32
32
|
)
|
33
33
|
|
34
34
|
# Configure a service that already exists
|
@@ -338,27 +338,26 @@ Service::ERROR_CRITICAL
|
|
338
338
|
There may be a failure in the test suite if the W32Time dependency is
|
339
339
|
not started.
|
340
340
|
|
341
|
-
If you find any bugs please log them on the
|
342
|
-
|
341
|
+
If you find any bugs please log them on the github project page at
|
342
|
+
https://github.com/djberg96/win32-service
|
343
343
|
|
344
344
|
= Acknowledgements
|
345
345
|
Many thanks go to Patrick Hurley for providing the fix for the thread
|
346
|
-
blocking issue. Thanks also go to Kevin Burge for
|
347
|
-
service responsiveness issues.
|
346
|
+
blocking issue in the original C code. Thanks also go to Kevin Burge for
|
347
|
+
his patch that solved service responsiveness issues.
|
348
348
|
|
349
349
|
= Future Plans
|
350
350
|
Add Tag_ID support.
|
351
351
|
Add ability to create or modify service failure actions.
|
352
|
-
Use RegisterServiceCtrlHandlerEx().
|
353
352
|
|
354
353
|
= Copyright
|
355
|
-
(C) 2003-
|
354
|
+
(C) 2003-2013, Daniel J. Berger, All Rights Reserved
|
356
355
|
|
357
356
|
= Warranty
|
358
357
|
This package is provided "as is" and without any express or
|
359
358
|
implied warranties, including, without limitation, the implied
|
360
359
|
warranties of merchantability and fitness for a particular purpose.
|
361
360
|
|
362
|
-
==
|
361
|
+
== Authors
|
363
362
|
* Daniel J. Berger
|
364
363
|
* Park Heesob
|
data/examples/demo_daemon.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
LOG_FILE = 'C:\\win32_daemon_test.log'
|
1
|
+
LOG_FILE = 'C:\\Tmp\\win32_daemon_test.log'
|
2
2
|
|
3
|
-
begin
|
3
|
+
begin
|
4
4
|
require 'rubygems'
|
5
5
|
require 'win32/daemon'
|
6
6
|
include Win32
|
@@ -17,7 +17,7 @@ begin
|
|
17
17
|
sleep 1
|
18
18
|
}
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
# This is the daemon's mainloop. In other words, whatever runs here
|
22
22
|
# is the code that runs while your service is running. Note that the
|
23
23
|
# loop is not implicit.
|
@@ -41,7 +41,7 @@ begin
|
|
41
41
|
# While we're in here the daemon is running.
|
42
42
|
while running?
|
43
43
|
if state == RUNNING
|
44
|
-
sleep 20
|
44
|
+
sleep 20
|
45
45
|
msg = 'Service is running as of: ' + Time.now.to_s
|
46
46
|
File.open(LOG_FILE, 'a'){ |f| f.puts msg }
|
47
47
|
else # PAUSED or IDLE
|
@@ -50,14 +50,14 @@ begin
|
|
50
50
|
end
|
51
51
|
|
52
52
|
# We've left the loop, the daemon is about to exit.
|
53
|
-
|
53
|
+
|
54
54
|
File.open(LOG_FILE, 'a'){ |f| f.puts "STATE: #{state}" }
|
55
|
-
|
55
|
+
|
56
56
|
msg = 'service_main left at: ' + Time.now.to_s
|
57
57
|
|
58
58
|
File.open(LOG_FILE, 'a'){ |f| f.puts msg }
|
59
59
|
end
|
60
|
-
|
60
|
+
|
61
61
|
# This event triggers when the service receives a signal to stop. I've
|
62
62
|
# added an explicit "exit!" here to ensure that the Ruby interpreter exits
|
63
63
|
# properly. I use 'exit!' instead of 'exit' because otherwise Ruby will
|
@@ -68,14 +68,14 @@ begin
|
|
68
68
|
File.open(LOG_FILE, 'a'){ |f| f.puts msg }
|
69
69
|
exit!
|
70
70
|
end
|
71
|
-
|
72
|
-
# This event triggers when the service receives a signal to pause.
|
71
|
+
|
72
|
+
# This event triggers when the service receives a signal to pause.
|
73
73
|
#
|
74
74
|
def service_pause
|
75
75
|
msg = 'Received pause signal at: ' + Time.now.to_s
|
76
76
|
File.open(LOG_FILE, 'a'){ |f| f.puts msg }
|
77
77
|
end
|
78
|
-
|
78
|
+
|
79
79
|
# This event triggers when the service receives a signal to resume
|
80
80
|
# from a paused state.
|
81
81
|
#
|
@@ -90,6 +90,6 @@ begin
|
|
90
90
|
#
|
91
91
|
DemoDaemon.mainloop
|
92
92
|
rescue Exception => err
|
93
|
-
File.open(LOG_FILE, 'a'){ |fh| fh.puts
|
93
|
+
File.open(LOG_FILE, 'a'){ |fh| fh.puts "Daemon failure: #{err}" }
|
94
94
|
raise
|
95
95
|
end
|