win32-service 0.7.1 → 0.7.2
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 +7 -0
- data/README +4 -7
- data/Rakefile +73 -33
- data/doc/daemon.txt +79 -79
- data/doc/service.txt +230 -231
- data/examples/demo_daemon.rb +82 -76
- data/examples/demo_services.rb +12 -5
- data/ext/extconf.rb +4 -0
- data/ext/win32/daemon.c +359 -358
- data/lib/win32/service.rb +5 -2
- data/test/test_win32_daemon.rb +11 -8
- data/test/test_win32_service.rb +3 -3
- data/win32-service.gemspec +2 -3
- metadata +40 -16
data/CHANGES
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
== 0.7.2 - 7-Sep-2011
|
2
|
+
* Now works with mingw compiler by skipping __try and __finally if using
|
3
|
+
mingw, or using them with mingw if the seh.h header is found.
|
4
|
+
* The binary gem now contains binaries for both Ruby 1.8.7 and 1.9.2 using
|
5
|
+
a simple wrapper.
|
6
|
+
* Updated some Rake tasks.
|
7
|
+
|
1
8
|
== 0.7.1 - 9-Feb-2010
|
2
9
|
* Compatibility fixes for 1.9.x.
|
3
10
|
* Fixed a bug where the controls_accepted struct member was always nil. This
|
data/README
CHANGED
@@ -2,7 +2,8 @@
|
|
2
2
|
The win32-service library allows you to control or create MS Windows services.
|
3
3
|
|
4
4
|
== Installation
|
5
|
-
gem install win32-service
|
5
|
+
gem install win32-service # Build from source
|
6
|
+
gem install win32-service --platform x86-mingw32 # Install binary
|
6
7
|
|
7
8
|
== Synopsis
|
8
9
|
require 'win32/service'
|
@@ -24,7 +25,7 @@
|
|
24
25
|
=== Troubleshooting:
|
25
26
|
This can be caused by one of two things. Either you attempted to delete a
|
26
27
|
running service without stopping it first, or you have the Services
|
27
|
-
|
28
|
+
Administrative Tool (GUI) open. In the former case, the solution is to first
|
28
29
|
stop the service if it's running. In the latter, close the Services GUI
|
29
30
|
admin tool before deleting.
|
30
31
|
|
@@ -47,10 +48,6 @@
|
|
47
48
|
|
48
49
|
* You've got a syntax error in your code somewhere.
|
49
50
|
|
50
|
-
== Possible test failures
|
51
|
-
The 'test_service_start_stop' test in the test_win32_service.rb file may
|
52
|
-
fail. This will happen if your W32Time service isn't running.
|
53
|
-
|
54
51
|
== See Also
|
55
52
|
ruby-wmi
|
56
53
|
|
@@ -59,7 +56,7 @@
|
|
59
56
|
Add service_session_change hook
|
60
57
|
|
61
58
|
== Copyright
|
62
|
-
(C) 2003-
|
59
|
+
(C) 2003-2011, Daniel J. Berger, All Rights Reserved
|
63
60
|
|
64
61
|
== License
|
65
62
|
Artistic 2.0
|
data/Rakefile
CHANGED
@@ -4,46 +4,33 @@ require 'rake/testtask'
|
|
4
4
|
require 'rbconfig'
|
5
5
|
include Config
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
7
|
+
CLEAN.include(
|
8
|
+
'**/*.gem', # Gem files
|
9
|
+
'**/*.rbc', # Rubinius
|
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"
|
21
|
+
)
|
22
|
+
|
23
|
+
desc "Build the win32-service library"
|
20
24
|
task :build => [:clean] do
|
25
|
+
make = CONFIG['host_os'] =~ /mingw|cygwin/i ? "make" : "nmake"
|
26
|
+
|
21
27
|
Dir.chdir('ext') do
|
22
28
|
ruby 'extconf.rb'
|
23
|
-
sh
|
29
|
+
sh "#{make}"
|
24
30
|
FileUtils.cp('daemon.so', 'win32/daemon.so')
|
25
31
|
end
|
26
32
|
end
|
27
33
|
|
28
|
-
desc "Install the win32-service library (non-gem)"
|
29
|
-
task :install => [:build] do
|
30
|
-
Dir.chdir('ext') do
|
31
|
-
sh 'nmake install'
|
32
|
-
end
|
33
|
-
install_dir = File.join(CONFIG['sitelibdir'], 'win32')
|
34
|
-
Dir.mkdir(install_dir) unless File.exists?(install_dir)
|
35
|
-
FileUtils.cp('lib/win32/service.rb', install_dir, :verbose => true)
|
36
|
-
end
|
37
|
-
|
38
|
-
desc 'Uninstall the win32-service library (non-gem)'
|
39
|
-
task :uninstall do
|
40
|
-
service = File.join(CONFIG['sitelibdir'], 'win32', 'service.rb')
|
41
|
-
FileUtils.rm(service, :verbose => true) if File.exists?(service)
|
42
|
-
|
43
|
-
daemon = File.join(CONFIG['sitearchdir'], 'win32', 'daemon.so')
|
44
|
-
FileUtils.rm(daemon, :verbose => true) if File.exists?(daemon)
|
45
|
-
end
|
46
|
-
|
47
34
|
namespace 'gem' do
|
48
35
|
desc 'Build the gem'
|
49
36
|
task :create => [:clean] do
|
@@ -70,6 +57,57 @@ namespace 'gem' do
|
|
70
57
|
|
71
58
|
Gem::Builder.new(spec).build
|
72
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
|
+
end
|
105
|
+
|
106
|
+
namespace :example do
|
107
|
+
desc "Run the services example program."
|
108
|
+
task :services do
|
109
|
+
sh "ruby -Ilib examples/demo_services.rb"
|
110
|
+
end
|
73
111
|
end
|
74
112
|
|
75
113
|
namespace 'test' do
|
@@ -137,3 +175,5 @@ namespace 'test' do
|
|
137
175
|
Rake.application[:clean].execute
|
138
176
|
end
|
139
177
|
end
|
178
|
+
|
179
|
+
task :default => 'test:all'
|
data/doc/daemon.txt
CHANGED
@@ -1,156 +1,156 @@
|
|
1
1
|
= Description
|
2
|
-
|
3
|
-
|
2
|
+
The Daemon class is a wrapper class that allows you to run your code as a
|
3
|
+
Windows service.
|
4
4
|
|
5
5
|
= Synopsis
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
end
|
6
|
+
class Daemon
|
7
|
+
def service_main
|
8
|
+
while running?
|
9
|
+
sleep 3
|
10
|
+
File.open("c:\\test.log", "a"){ |f| f.puts "service is running" }
|
12
11
|
end
|
13
|
-
|
12
|
+
end
|
13
|
+
end
|
14
14
|
|
15
|
-
|
15
|
+
Daemon.mainloop
|
16
16
|
|
17
|
-
=
|
17
|
+
= Singleton Methods
|
18
18
|
Daemon.mainloop
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
This is the method that actually puts your code into a loop and allows it
|
20
|
+
to run as a service. The code that is actually run while in the mainloop
|
21
|
+
is what you defined in the Daemon#service_main method.
|
22
22
|
|
23
23
|
= Instance Methods
|
24
24
|
Daemon#running?
|
25
|
-
|
26
|
-
|
25
|
+
Returns whether or not the daemon is running. This is just a shortcut
|
26
|
+
for checking if the state is RUNNING, PAUSED or IDLE.
|
27
27
|
|
28
|
-
|
29
|
-
|
30
|
-
|
28
|
+
This is typically used within your service_main method. See the
|
29
|
+
demo_daemon.rb file in the 'examples' directory for an example of how it's
|
30
|
+
used in practice.
|
31
31
|
|
32
32
|
Daemon#service_init
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
33
|
+
Any code defined defined within this method occurs before service_main is
|
34
|
+
reached. Any initialization code that takes more than two seconds to
|
35
|
+
execute should be placed here. Otherwise, your service may timeout when
|
36
|
+
you try to start it.
|
37
37
|
|
38
38
|
Daemon#service_main(*args)
|
39
|
-
|
40
|
-
|
41
|
-
|
39
|
+
You are expected to define your own service_main() method. The code
|
40
|
+
defined in this method is the code that will run while running as a
|
41
|
+
service.
|
42
42
|
|
43
|
-
|
43
|
+
Any +args+ passed to Service.start are passed to this method.
|
44
44
|
|
45
45
|
Daemon#state
|
46
|
-
|
47
|
-
|
46
|
+
Returns the current state of the Daemon. For a list of valid states, see
|
47
|
+
the Constants section below.
|
48
48
|
|
49
49
|
= Signal Event Hooks
|
50
|
-
|
51
|
-
|
50
|
+
These methods are called if defined within your Daemon class, and the
|
51
|
+
appropriate signal is received by your service.
|
52
52
|
|
53
53
|
Daemon#service_stop
|
54
|
-
|
55
|
-
|
54
|
+
Called if the service receives a SERVICE_CONTROL_STOP signal. This is
|
55
|
+
what the Service.stop() method sends.
|
56
56
|
|
57
57
|
Daemon#service_pause
|
58
|
-
|
59
|
-
|
58
|
+
Called if the service receives a SERVICE_CONTROL_PAUSE signal. This is
|
59
|
+
what the Service.pause() method sends.
|
60
60
|
|
61
61
|
Daemon#service_resume
|
62
|
-
|
63
|
-
|
62
|
+
Called if the service receives a SERVICE_CONTROL_CONTINUE signal. This
|
63
|
+
is what the Service.resume() method sends.
|
64
64
|
|
65
65
|
Daemon#service_interrogate
|
66
|
-
|
67
|
-
|
68
|
-
|
66
|
+
Called if the service receives a SERVICE_CONTROL_INTERROGATE signal. This
|
67
|
+
notifies a service that it should report its current status information to
|
68
|
+
the service control manager.
|
69
69
|
|
70
70
|
Daemon#service_shutdown
|
71
|
-
|
71
|
+
Called if the service receives a SERVICE_CONTROL_SHUTDOWN signal.
|
72
72
|
|
73
73
|
Daemon#service_netbindadd
|
74
|
-
|
75
|
-
|
74
|
+
Called if the service receives a SERVICE_CONTROL_NETBINDADD signal. This
|
75
|
+
notifies a network service that there is a new component for binding.
|
76
76
|
|
77
77
|
Daemon#service_netbinddisable
|
78
|
-
|
79
|
-
|
80
|
-
|
78
|
+
Called if the service receives a SERVICE_CONTROL_NETBINDDISABLE signal.
|
79
|
+
This notifies a network service that one of its bindings has been
|
80
|
+
disabled.
|
81
81
|
|
82
82
|
Daemon#service_netbindenable
|
83
|
-
|
84
|
-
|
83
|
+
Called if the service receives a SERVICE_CONTROL_NETBINDENABLE signal.
|
84
|
+
This Notifies a network service that a disabled binding has been enabled.
|
85
85
|
|
86
86
|
Daemon#service_netbindremove
|
87
|
-
|
88
|
-
|
89
|
-
|
87
|
+
Called if the service receives a SERVICE_CONTROL_NETBINDREMOVE signal.
|
88
|
+
This notifies a network service that that a component for binding has
|
89
|
+
been removed.
|
90
90
|
|
91
91
|
Daemon#service_paramchange
|
92
|
-
|
93
|
-
|
92
|
+
Called if the service receives a SERVICE_CONTROL_PARAMCHANGE signal.
|
93
|
+
This notifies a service that its startup parameters have changed.
|
94
94
|
|
95
95
|
= Constants
|
96
96
|
|
97
97
|
=== Service state constants
|
98
98
|
Daemon::CONTINUE_PENDING
|
99
|
-
|
99
|
+
The service continue is pending.
|
100
100
|
|
101
101
|
Daemon::PAUSE_PENDING
|
102
|
-
|
102
|
+
The service pause is pending.
|
103
103
|
|
104
104
|
Daemon::PAUSED
|
105
|
-
|
105
|
+
The service is paused (but not STOPPED).
|
106
106
|
|
107
107
|
Daemon::RUNNING
|
108
|
-
|
108
|
+
The service is running.
|
109
109
|
|
110
110
|
Daemon::START_PENDING
|
111
|
-
|
111
|
+
The service is starting (but is not yet in a RUNNING state).
|
112
112
|
|
113
113
|
Daemon::STOP_PENDING
|
114
|
-
|
114
|
+
The service is stopping (but is not yet in a STOPPED state).
|
115
115
|
|
116
116
|
Daemon::STOPPED
|
117
|
-
|
117
|
+
The service is not running.
|
118
118
|
|
119
119
|
Daemon::IDLE
|
120
|
-
|
121
|
-
|
120
|
+
The service is running, in an idle state. This is a custom state that
|
121
|
+
we added that gets around a thread blocking issue.
|
122
122
|
|
123
123
|
= Notes
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
124
|
+
You must create a service before you can actually run it. Look in the
|
125
|
+
examples directory for the files 'demo_daemon.rb' and 'demodaemon_ctl.rb'.
|
126
|
+
They're small and straightforward examples of how to control, install and
|
127
|
+
setup your own Daemon.
|
128
128
|
|
129
129
|
= Known Bugs
|
130
|
-
|
131
|
-
|
130
|
+
None known. Please report any bugs you find on the Bug tracker at
|
131
|
+
http://rubyforge.org/projects/win32utils.
|
132
132
|
|
133
133
|
= Future Plans
|
134
|
-
|
134
|
+
Rewrite the Daemon class in pure Ruby.
|
135
135
|
|
136
|
-
|
137
|
-
|
136
|
+
Suggestions welcome. Please log them on the Feature Request tracker at
|
137
|
+
http://rubyforge.org/projects/win32utils
|
138
138
|
|
139
139
|
= Acknowledgements
|
140
|
-
|
141
|
-
|
142
|
-
|
140
|
+
Many thanks go to Patrick Hurley for providing the fix for the thread
|
141
|
+
blocking issue. Thanks also go to Kevin Burge for his patch that solved
|
142
|
+
service responsiveness issues.
|
143
143
|
|
144
144
|
= Copyright
|
145
|
-
|
145
|
+
(C) 2003-2011 Daniel J. Berger, All Rights Reserved
|
146
146
|
|
147
147
|
= License
|
148
|
-
|
148
|
+
Artistic 2.0
|
149
149
|
|
150
150
|
= Warranty
|
151
|
-
|
152
|
-
|
153
|
-
|
151
|
+
This package is provided "as is" and without any express or
|
152
|
+
implied warranties, including, without limitation, the implied
|
153
|
+
warranties of merchantability and fitness for a particular purpose.
|
154
154
|
|
155
155
|
= Author(s)
|
156
156
|
* Daniel J. Berger
|
data/doc/service.txt
CHANGED
@@ -1,364 +1,363 @@
|
|
1
1
|
= Description
|
2
|
-
|
2
|
+
An interface for MS Windows Services.
|
3
3
|
|
4
4
|
= Prerequisites
|
5
|
-
|
5
|
+
Ruby 1.8.2 or later.
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
This library is only supported for the Windows NT family of operating
|
8
|
+
systems, e.g. 2000, XP, 2003, etc. It is NOT supported (and won't
|
9
|
+
work) for any version of DOS or Windows 95/98/ME. It is also not
|
10
|
+
supported on NT 4, as that platform is defunct.
|
11
11
|
|
12
|
-
|
13
|
-
|
12
|
+
It should work on Windows XP Home, but is not officially supported for
|
13
|
+
that platform.
|
14
14
|
|
15
15
|
= Synopsis
|
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
|
-
Service.get_display_name("Schedule") # "Task Scheduler"
|
45
|
-
Service.get_service_name("ClipBook") # "ClipSrv"
|
16
|
+
require "win32/service"
|
17
|
+
include Win32
|
18
|
+
|
19
|
+
# Create a new service
|
20
|
+
Service.create(
|
21
|
+
:service_name => 'some_service',
|
22
|
+
:service_type => Service::WIN32_OWN_PROCESS,
|
23
|
+
:description => 'A custom service I wrote just for fun'
|
24
|
+
:start_type => Service::AUTO_START,
|
25
|
+
:error_control => Service::ERROR_NORMAL,
|
26
|
+
:binary_path_name => 'C:\path\to\some_service.exe',
|
27
|
+
:load_order_group => 'Network',
|
28
|
+
:dependencies => ['W32Time','Schedule']
|
29
|
+
:service_start_name => 'SomeDomain\\User',
|
30
|
+
:password => 'XXXXXXX',
|
31
|
+
:display_name => 'This is some service',
|
32
|
+
)
|
33
|
+
|
34
|
+
# Configure a service that already exists
|
35
|
+
Service.configure(:display_name => "My Bar Service")
|
36
|
+
|
37
|
+
Service.start("foo")
|
38
|
+
Service.pause("foo")
|
39
|
+
Service.resume("foo")
|
40
|
+
Service.stop("foo")
|
41
|
+
|
42
|
+
Service.delete("foo")
|
46
43
|
|
47
|
-
|
44
|
+
Service.get_display_name("Schedule") # "Task Scheduler"
|
45
|
+
Service.get_service_name("ClipBook") # "ClipSrv"
|
46
|
+
|
47
|
+
Service.status('W32Time') => <struct Struct::ServiceStatus ...>
|
48
48
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
}
|
49
|
+
# Enumerate over all services, inspecting each struct
|
50
|
+
Service.services{ |s|
|
51
|
+
puts s.inspect
|
52
|
+
}
|
54
53
|
|
55
54
|
= Class Methods
|
56
55
|
Service.new(options={})
|
57
|
-
|
58
|
-
|
56
|
+
Creates a new service. The +options+ parameter is a hash that can
|
57
|
+
contain any of the following parameters, and their default values:
|
59
58
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
59
|
+
KEY DEFAULT
|
60
|
+
* service_name => nil (mandatory)
|
61
|
+
* host => nil
|
62
|
+
* display_name => service_name
|
63
|
+
* desired_access => Service::ALL_ACCESS
|
64
|
+
* service_type => Service::WIN32_OWN_PROCESS|Service::INTERACTIVE_PROCESS
|
65
|
+
* start_type => Service::DEMAND_START
|
66
|
+
* error_control => Service::ERROR_NORMAL
|
67
|
+
* binary_path_name => nil
|
68
|
+
* load_order_group => nil
|
69
|
+
* dependencies => nil
|
70
|
+
* service_start_name => nil
|
71
|
+
* password => nil
|
72
|
+
* description => nil
|
73
73
|
|
74
74
|
Service.configure(options={})
|
75
|
-
|
76
|
-
|
75
|
+
Configures an existing service. The +options+ parameter is a hash that can
|
76
|
+
contain any of the following parameters:
|
77
77
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
78
|
+
* service_name (mandatory)
|
79
|
+
* host
|
80
|
+
* service_type
|
81
|
+
* start_type
|
82
|
+
* error_control
|
83
|
+
* binary_path_name
|
84
|
+
* load_order_group
|
85
|
+
* dependencies
|
86
|
+
* service_start_name
|
87
|
+
* password (used with service_start_name)
|
88
|
+
* display_name
|
89
|
+
* description
|
90
90
|
|
91
91
|
Service.config_info(service, host=nil)
|
92
|
-
|
93
|
-
|
92
|
+
Returns a ServiceConfigInfo struct containing the configuration information
|
93
|
+
about +service+ on +host+, or the local host if no host is specified.
|
94
94
|
|
95
95
|
Service.create
|
96
|
-
|
96
|
+
Alias for Service.new
|
97
97
|
|
98
98
|
Service.delete(service, host=nil)
|
99
|
-
|
100
|
-
|
99
|
+
Deletes the specified +service+ on +host+. If no host is given,
|
100
|
+
then it deletes it on the local machine.
|
101
101
|
|
102
102
|
Service.exists?(service)
|
103
|
-
|
103
|
+
Returns true if the specified service exists, false otherwise.
|
104
104
|
|
105
105
|
Service.pause(service, host=nil)
|
106
|
-
|
107
|
-
|
106
|
+
Pauses the specified +service+ on +host+, or the local machine if
|
107
|
+
no host is provided.
|
108
108
|
|
109
109
|
Service.resume(service, host=nil)
|
110
|
-
|
111
|
-
|
110
|
+
Resumes the specified +service+ on +host+, or the local machine if
|
111
|
+
no host is specified.
|
112
112
|
|
113
113
|
Service.services(host=nil, group=nil){ |struct| ... }
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
114
|
+
Enumerates over a list of service types on host, or the local
|
115
|
+
machine if no host is specified, yielding a Win32Service struct for each
|
116
|
+
service.
|
117
|
+
|
118
|
+
If a 'group' is specified, then only those services that belong to
|
119
|
+
that group are enumerated. If an empty string is provided, then only
|
120
|
+
services that do not belong to any group are enumerated. If this parameter
|
121
|
+
is nil, group membership is ignored and all services are enumerated.
|
122
122
|
|
123
|
-
|
124
|
-
|
125
|
-
|
123
|
+
The 'group' option is only available on Windows 2000 or later, and only
|
124
|
+
if compiled with VC++ 7.0 or later, or the .NET SDK. The Win32Service
|
125
|
+
struct contains the following members:
|
126
126
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
127
|
+
* service_name
|
128
|
+
* display_name
|
129
|
+
* service_type
|
130
|
+
* current_state
|
131
|
+
* controls_accepted
|
132
|
+
* win32_exit_code
|
133
|
+
* service_specific_exit_code
|
134
|
+
* check_point
|
135
|
+
* wait_hint
|
136
|
+
* binary_path_name
|
137
|
+
* start_type
|
138
|
+
* error_control
|
139
|
+
* load_order_group
|
140
|
+
* tag_id
|
141
|
+
* start_name
|
142
|
+
* dependencies
|
143
|
+
* description
|
144
|
+
* interactive?
|
145
|
+
* pid (Win2k or later)
|
146
|
+
* service_flags (Win2k or later)
|
147
147
|
|
148
|
-
|
149
|
-
|
150
|
-
|
148
|
+
Note that the 'pid' and 'service_flags' members are only available on
|
149
|
+
Windows 2000 or later, and only if built with VC++ 7.0 or later (or the
|
150
|
+
.NET SDK).
|
151
151
|
|
152
152
|
Service.start(service, host=nil, *args)
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
153
|
+
Starts the specified +service+ on +host+, or the local machine if no
|
154
|
+
host is specified. Any +args+ passed here are passed as start parameters
|
155
|
+
to the service.
|
156
|
+
|
157
157
|
Service.status(service)
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
158
|
+
Returns a Win32ServiceStatus struct for the specified service (or
|
159
|
+
raises a Win32::ServiceError if not found). The Win32ServiceStatus
|
160
|
+
struct contains the following members.
|
161
|
+
|
162
|
+
* service_type
|
163
|
+
* current_state
|
164
|
+
* controls_accepted
|
165
|
+
* win32_exit_code
|
166
|
+
* service_specific_exit_code
|
167
|
+
* check_point
|
168
|
+
* wait_hint
|
169
|
+
* interactive?
|
170
170
|
|
171
171
|
Service.stop(service, host=nil)
|
172
|
-
|
173
|
-
|
172
|
+
Stops the specified +service+ on +host+, or the local machine if no
|
173
|
+
host is specified.
|
174
174
|
|
175
175
|
= Create and configure options
|
176
176
|
binary_path_name
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
177
|
+
The binary to be used for the service. The path must be the fully
|
178
|
+
qualified path name. A path that contains a space must be quoted so that
|
179
|
+
it is correctly interpreted. The path may also include arguments to the
|
180
|
+
service entry point (typically the 'main' function).
|
181
181
|
|
182
182
|
dependencies
|
183
|
-
|
184
|
-
|
183
|
+
Any dependencies the service has in order to run. This can be a string
|
184
|
+
or an array of strings.
|
185
185
|
|
186
186
|
description
|
187
|
-
|
187
|
+
A text string describing the service.
|
188
188
|
|
189
189
|
display_name
|
190
|
-
|
191
|
-
|
192
|
-
|
190
|
+
The display name to be used by user interface programs to identify the
|
191
|
+
service. The string has a maximum length of 256 characters. Case
|
192
|
+
sensitivity is preserved.
|
193
193
|
|
194
|
-
|
195
|
-
|
194
|
+
The default is to set the display name to the same string as the
|
195
|
+
service name.
|
196
196
|
|
197
197
|
error_control
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
198
|
+
The error control for the service. The default is Service::ERROR_NORMAL.
|
199
|
+
|
200
|
+
See the "Error Control Contants" section for available options and their
|
201
|
+
meanings.
|
202
202
|
|
203
203
|
load_order_group
|
204
|
-
|
205
|
-
|
204
|
+
The load order group, a string that names the load ordering group of
|
205
|
+
which this service is a member. The default is nil.
|
206
206
|
|
207
207
|
password
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
208
|
+
Sets the passsword to the account name specified in the Service#start_name
|
209
|
+
method. By default, this value is set to nil, which is appropriate if
|
210
|
+
the account has no password or if the service runs in the
|
211
|
+
'LocalService', 'NetworkService', or 'LocalSystem' account.
|
212
212
|
|
213
|
-
|
213
|
+
Note that passwords are ignored for driver services.
|
214
214
|
|
215
215
|
service_name
|
216
|
-
|
217
|
-
|
216
|
+
The service name for the service. This value must be set in order
|
217
|
+
to create a service. The string has a maximum length of 256 characters.
|
218
218
|
|
219
219
|
service_type
|
220
|
-
|
221
|
-
|
220
|
+
The service type for the service. The default is
|
221
|
+
Service::WIN32_OWN_PROCESS | Service::INTERACTIVE_PROCESS.
|
222
222
|
|
223
|
-
|
224
|
-
|
223
|
+
See the "Service Type Contants" section for available options and their
|
224
|
+
meanings.
|
225
225
|
|
226
226
|
start_name
|
227
|
-
|
228
|
-
|
227
|
+
Sets the name of the account under which the service should run.
|
228
|
+
By default the 'LocalSystem' account is used.
|
229
229
|
|
230
230
|
start_type
|
231
|
-
|
231
|
+
The start type for the service. The default is Service::DEMAND_START.
|
232
232
|
|
233
|
-
|
234
|
-
|
233
|
+
See the "Start Type Contants" section for available options and their
|
234
|
+
meanings.
|
235
235
|
|
236
236
|
= Constants
|
237
237
|
|
238
238
|
=== Standard Constants
|
239
239
|
VERSION
|
240
|
-
|
240
|
+
The current version number of this package, returned as a string.
|
241
241
|
|
242
242
|
=== Desired Access Constants
|
243
243
|
Service::MANAGER_ALL_ACCESS
|
244
|
-
|
245
|
-
|
244
|
+
Includes STANDARD_RIGHTS_REQUIRED, in addition to all access rights
|
245
|
+
in the table.
|
246
246
|
|
247
247
|
Service::MANAGER_CREATE_SERVICE
|
248
|
-
|
249
|
-
|
248
|
+
Required to call the CreateService function to create a service object
|
249
|
+
and add it to the database.
|
250
250
|
|
251
251
|
Service::MANAGER_CONNECT
|
252
|
-
|
252
|
+
Required to connect to the service control manager.
|
253
253
|
|
254
254
|
Service::MANAGER_ENUMERATE_SERVICE
|
255
|
-
|
256
|
-
|
255
|
+
Required to call the EnumServicesStatus function to list the services
|
256
|
+
that are in the database.
|
257
257
|
|
258
258
|
Service::MANAGER_LOCK
|
259
|
-
|
260
|
-
|
259
|
+
Required to call the LockServiceDatabase function to acquire a lock on the
|
260
|
+
database.
|
261
261
|
|
262
262
|
Service::MANAGER_BOOT_CONFIG
|
263
|
-
|
264
|
-
|
263
|
+
Required to call the NotifyBootConfigStatus() (internal) function. Not
|
264
|
+
defined with all compilers.
|
265
265
|
|
266
266
|
Service::MANAGER_QUERY_LOCK_STATUS
|
267
|
-
|
268
|
-
|
267
|
+
Required to call the QueryServiceLockStatus() (internal) function to
|
268
|
+
retrieve the lock status information for the database.
|
269
269
|
|
270
270
|
=== Service Type Constants
|
271
271
|
Service::FILE_SYSTEM_DRIVER
|
272
|
-
|
272
|
+
File system driver service.
|
273
273
|
|
274
274
|
Service::KERNEL_DRIVER
|
275
|
-
|
275
|
+
Driver service.
|
276
276
|
|
277
277
|
Service::WIN32_OWN_PROCESS
|
278
|
-
|
278
|
+
Service that runs in its own process.
|
279
279
|
|
280
280
|
Service::WIN32_SHARE_PROCESS
|
281
|
-
|
281
|
+
Service that shares a process with one or more other services.
|
282
282
|
|
283
283
|
Service::INTERACTIVE_PROCESS
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
284
|
+
The service can interact with the desktop. This can only be used if
|
285
|
+
either SERVICE_WIN32_OWN_PROCESS or SERVICE_WIN32_SHARE_PROCESS is
|
286
|
+
specified as well, and the service is running in the context of the
|
287
|
+
LocalSystem account (which is the default for this module, btw).
|
288
288
|
|
289
289
|
=== Start Type Constants
|
290
290
|
Service::AUTO_START
|
291
|
-
|
292
|
-
|
291
|
+
A service started automatically by the service control manager during
|
292
|
+
system startup.
|
293
293
|
|
294
294
|
Service::BOOT_START
|
295
|
-
|
296
|
-
|
295
|
+
A device driver started by the system loader. This value is valid only
|
296
|
+
for driver services.
|
297
297
|
|
298
298
|
Service::DEMAND_START
|
299
|
-
|
300
|
-
|
299
|
+
A service started by the service control manager when a process calls
|
300
|
+
the StartService() function.
|
301
301
|
|
302
302
|
Service::DISABLED
|
303
|
-
|
304
|
-
|
303
|
+
A service that cannot be started. Attempts to start the service result
|
304
|
+
in an error.
|
305
305
|
|
306
306
|
Service::SYSTEM_START
|
307
|
-
|
308
|
-
|
307
|
+
A device driver started by the IoInitSystem() function. This value is
|
308
|
+
valid only for driver services.
|
309
309
|
|
310
310
|
=== Error Control Constants
|
311
311
|
Service::ERROR_IGNORE
|
312
|
-
|
312
|
+
The startup program logs the error but continues the startup operation.
|
313
313
|
|
314
314
|
Service::ERROR_NORMAL
|
315
|
-
|
316
|
-
|
315
|
+
The startup program logs the error and puts up a message box pop-up but
|
316
|
+
continues the startup operation.
|
317
317
|
|
318
318
|
Service::ERROR_SEVERE
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
319
|
+
The startup program logs the error. If the last-known-good configuration
|
320
|
+
is being started, the startup operation continues. Otherwise, the system
|
321
|
+
is restarted with the last-known-good configuration.
|
322
|
+
|
323
323
|
Service::ERROR_CRITICAL
|
324
|
-
|
325
|
-
|
326
|
-
|
324
|
+
The startup program logs the error, if possible. If the last-known-good
|
325
|
+
configuration is being started the startup operation fails. Otherwise,
|
326
|
+
the system is restarted with the last-known-good configuration.
|
327
327
|
|
328
328
|
= Notes
|
329
|
-
|
330
|
-
http://www.msdn.com
|
329
|
+
See the MSDN API with regards to CreateService(), etc at http://www.msdn.com.
|
331
330
|
|
332
|
-
|
333
|
-
|
331
|
+
Some API ideas taken (or not) from both Python's win32serviceutil.py and
|
332
|
+
Perl's Win32::Service module.
|
334
333
|
|
335
|
-
|
336
|
-
|
334
|
+
I don't truly understand how to allow a tag_id in the create_service()
|
335
|
+
method, so for now it's set to NULL automatically. Suggestions welcome.
|
337
336
|
|
338
337
|
= Known Bugs
|
339
|
-
|
340
|
-
|
338
|
+
There may be a failure in the test suite if the W32Time dependency is
|
339
|
+
not started.
|
341
340
|
|
342
|
-
|
343
|
-
|
341
|
+
If you find any bugs please log them on the bug tracker. You can find it
|
342
|
+
on the project page at http://www.rubyforge.org/projects/win32utils.
|
344
343
|
|
345
344
|
= Acknowledgements
|
346
|
-
|
347
|
-
|
348
|
-
|
345
|
+
Many thanks go to Patrick Hurley for providing the fix for the thread
|
346
|
+
blocking issue. Thanks also go to Kevin Burge for his patch that solved
|
347
|
+
service responsiveness issues.
|
349
348
|
|
350
349
|
= Future Plans
|
351
|
-
|
352
|
-
|
353
|
-
|
350
|
+
Add Tag_ID support.
|
351
|
+
Add ability to create or modify service failure actions.
|
352
|
+
Use RegisterServiceCtrlHandlerEx().
|
354
353
|
|
355
354
|
= Copyright
|
356
|
-
|
355
|
+
(C) 2003-2011, Daniel J. Berger, All Rights Reserved
|
357
356
|
|
358
357
|
= Warranty
|
359
|
-
|
360
|
-
|
361
|
-
|
358
|
+
This package is provided "as is" and without any express or
|
359
|
+
implied warranties, including, without limitation, the implied
|
360
|
+
warranties of merchantability and fitness for a particular purpose.
|
362
361
|
|
363
362
|
== Author(s)
|
364
363
|
* Daniel J. Berger
|