win32-service 0.7.2 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|