win32-service 0.6.1 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES CHANGED
@@ -1,3 +1,24 @@
1
+ == 0.7.0 - 30-Jun-2009
2
+ * INTERFACE CHANGE: The Service.new and Service.configure methods now accept
3
+ a single hash argument only. The :service_name key is mandatory, while the
4
+ :host key is optional.
5
+ * Fixed a bug in the Service.services method where a segfault would occur if
6
+ the binary_path_name was greater than 260 characters. The buffer size has
7
+ been increased to 1024 characters. Thanks go to Dan Daniels for the spot.
8
+ * Altered the Daemon class so that the Ruby interpreter was not invoked within
9
+ the Service_Main function. The functions that close stdin, stdout and stderr
10
+ are now called within the mainloop method. Thanks go to Tim Hanson for the
11
+ spot and the patch.
12
+ * Eliminated a minor build warning in daemon.c
13
+ * License changed to Artistic 2.0, with corresponding gemspec update.
14
+ * Added an uninstall rake task.
15
+ * Updated the service_stop method in the demo_daemon.rb file, and added some
16
+ additional comments.
17
+ * The test files were renamed.
18
+ * Several tests were updated and refactored to use Test::Unit 2.x. That
19
+ library is now a dependency.
20
+ * The 'uninstall' Rakefile task is now more verbose.
21
+
1
22
  == 0.6.1 - 1-Jan-2008
2
23
  * The Service.services method now handles the scenario where a particular
3
24
  service may still exist, but its underlying registry entry has been deleted.
data/MANIFEST CHANGED
@@ -11,8 +11,9 @@
11
11
  * examples/demo_daemon_ctl.rb
12
12
  * examples/demo_services.rb
13
13
  * lib/win32/service.rb
14
- * test/tc_daemon.rb
15
- * test/tc_service_create.rb
16
- * test/tc_service_info.rb
17
- * test/tc_service_status.rb
18
- * test/tc_service.rb
14
+ * test/test_win32_daemon.rb
15
+ * test/test_win32_service_configure.rb
16
+ * test/test_win32_service_create.rb
17
+ * test/test_win32_service_info.rb
18
+ * test/test_win32_service_status.rb
19
+ * test/test_win32_service.rb
data/README CHANGED
@@ -41,4 +41,5 @@ will happen if your W32Time service isn't running.
41
41
 
42
42
  = Future Plans
43
43
  * Pure Ruby Daemon class
44
- * Add service_session_change hook
44
+ * Add service_session_change hook
45
+ * Add a WMI variant of the Service class.
data/Rakefile ADDED
@@ -0,0 +1,128 @@
1
+ require 'rake'
2
+ require 'rake/clean'
3
+ require 'rake/testtask'
4
+ require 'rbconfig'
5
+ include Config
6
+
7
+ desc "Cleans up the C related files created during the build"
8
+ task :clean do
9
+ Dir.chdir('ext') do
10
+ if File.exists?('daemon.o') || File.exists?('daemon.so')
11
+ sh 'nmake distclean'
12
+ end
13
+ File.delete('win32/daemon.so') if File.exists?('win32/daemon.so')
14
+ end
15
+ end
16
+
17
+ desc "Builds, but does not install, the win32-service library"
18
+ task :build => [:clean] do
19
+ Dir.chdir('ext') do
20
+ ruby 'extconf.rb'
21
+ sh 'nmake'
22
+ FileUtils.cp('daemon.so', 'win32/daemon.so')
23
+ end
24
+ end
25
+
26
+ desc "Install the win32-service library (non-gem)"
27
+ task :install => [:build] do
28
+ Dir.chdir('ext') do
29
+ sh 'nmake install'
30
+ end
31
+ install_dir = File.join(CONFIG['sitelibdir'], 'win32')
32
+ Dir.mkdir(install_dir) unless File.exists?(install_dir)
33
+ FileUtils.cp('lib/win32/service.rb', install_dir, :verbose => true)
34
+ end
35
+
36
+ desc 'Install the win32-service library as a gem'
37
+ task :install_gem => [:clean] do
38
+ ruby 'win32-service.gemspec'
39
+ file = Dir['win32-service*.gem'].first
40
+ sh "gem install #{file}"
41
+ end
42
+
43
+ desc 'Uninstall the (non-gem) win32-service library.'
44
+ task :uninstall do
45
+ service = File.join(CONFIG['sitelibdir'], 'win32', 'service.rb')
46
+ FileUtils.rm(service, :verbose => true) if File.exists?(service)
47
+
48
+ daemon = File.join(CONFIG['sitearchdir'], 'win32', 'daemon.so')
49
+ FileUtils.rm(daemon, :verbose => true) if File.exists?(daemon)
50
+ end
51
+
52
+ desc "Build a binary gem"
53
+ task :build_binary_gem => [:build] do
54
+ if File.exists?('lib/win32/daemon.rb')
55
+ mv 'lib/win32/daemon.rb', 'lib/win32/daemon.orig'
56
+ end
57
+
58
+ cp 'ext/win32/daemon.so', 'lib/win32/daemon.so'
59
+
60
+ task :build_binary_gem => [:clean]
61
+
62
+ spec = Gem::Specification.new do |gem|
63
+ gem.name = 'win32-service'
64
+ gem.version = '0.7.0'
65
+ gem.authors = ['Daniel J. Berger', 'Park Heesob']
66
+ gem.email = 'djberg96@gmail.com'
67
+ gem.license = 'Artistic 2.0'
68
+ gem.homepage = 'http://www.rubyforge.org/projects/win32utils'
69
+ gem.platform = Gem::Platform::CURRENT
70
+ gem.summary = 'An interface for MS Windows services'
71
+ gem.test_files = Dir['test/test*.rb']
72
+ gem.has_rdoc = true
73
+ gem.files = Dir['**/*'].delete_if{ |f|
74
+ f.include?('CVS') || f.include?('ext') || f.include?('daemon.orig')
75
+ }
76
+
77
+ gem.extra_rdoc_files = [
78
+ 'CHANGES',
79
+ 'README',
80
+ 'MANIFEST',
81
+ 'doc/service.txt',
82
+ 'doc/daemon.txt',
83
+ 'ext/win32/daemon.c'
84
+ ]
85
+
86
+ gem.rubyforge_project = 'win32utils'
87
+ gem.required_ruby_version = '>= 1.8.2'
88
+
89
+ gem.add_dependency('windows-pr', '>= 1.0.5')
90
+ gem.add_dependency('test-unit', '>= 2.0.2')
91
+
92
+ gem.description = <<-EOF
93
+ The win32-service library provides a Ruby interface to services on
94
+ MS Windows. You can create new services, or control, configure and
95
+ inspect existing services.
96
+
97
+ In addition, you can create a pure Ruby service by using the Daemon
98
+ class that is included as part of the library.
99
+ EOF
100
+ end
101
+
102
+ Gem::Builder.new(spec).build
103
+ end
104
+
105
+ desc "Run the test suite for the win32-service library"
106
+ Rake::TestTask.new do |t|
107
+ task :test => :build
108
+ t.libs << 'ext'
109
+ t.verbose = true
110
+ t.warning = true
111
+ end
112
+
113
+ desc "Run the test suite for the Win32::Daemon class (only)"
114
+ Rake::TestTask.new('test_daemon') do |t|
115
+ task :test_daemon => :build
116
+ t.libs << 'ext'
117
+ t.verbose = true
118
+ t.warning = true
119
+ t.test_files = FileList['test/test_win32_daemon.rb']
120
+ end
121
+
122
+ task :test do
123
+ Rake.application[:clean].execute
124
+ end
125
+
126
+ task :test_daemon do
127
+ Rake.application[:clean].execute
128
+ end
data/doc/daemon.txt CHANGED
@@ -7,7 +7,7 @@
7
7
  def service_main
8
8
  while running?
9
9
  sleep 3
10
- File.open("c:\\test.log","a+"){ |f| f.puts "service is running" }
10
+ File.open("c:\\test.log", "a"){ |f| f.puts "service is running" }
11
11
  end
12
12
  end
13
13
  end
@@ -131,6 +131,8 @@ Daemon::IDLE
131
131
  http://rubyforge.org/projects/win32utils.
132
132
 
133
133
  = Future Plans
134
+ Rewrite the Daemon class in pure Ruby.
135
+
134
136
  Suggestions welcome. Please log them on the Feature Request tracker at
135
137
  http://rubyforge.org/projects/win32utils
136
138
 
@@ -140,10 +142,10 @@ Daemon::IDLE
140
142
  service responsiveness issues.
141
143
 
142
144
  = Copyright
143
- (C) 2003-2008 Daniel J. Berger, All Rights Reserved
145
+ (C) 2003-2009 Daniel J. Berger, All Rights Reserved
144
146
 
145
147
  = License
146
- Ruby's
148
+ Artistic 2.0
147
149
 
148
150
  = Warranty
149
151
  This package is provided "as is" and without any express or
data/doc/service.txt CHANGED
@@ -17,7 +17,8 @@
17
17
  include Win32
18
18
 
19
19
  # Create a new service
20
- Service.create('some_service', nil,
20
+ Service.create(
21
+ :service_name => 'some_service',
21
22
  :service_type => Service::WIN32_OWN_PROCESS,
22
23
  :description => 'A custom service I wrote just for fun'
23
24
  :start_type => Service::AUTO_START,
@@ -52,11 +53,12 @@
52
53
  }
53
54
 
54
55
  = Class Methods
55
- Service.new(service_name, host=nil, options={})
56
- Creates a new service with +service_name+ on +host+, or the local host
57
- if no host is specified. The +options+ parameter is a hash that can
56
+ Service.new(options={})
57
+ Creates a new service. The +options+ parameter is a hash that can
58
58
  contain any of the following parameters, and their default values:
59
59
 
60
+ * service_name => nil (mandatory)
61
+ * host => nil
60
62
  * display_name => service_name
61
63
  * desired_access => Service::ALL_ACCESS
62
64
  * service_type => Service::WIN32_OWN_PROCESS | Service::INTERACTIVE_PROCESS
@@ -69,11 +71,12 @@ Service.new(service_name, host=nil, options={})
69
71
  * password => nil
70
72
  * description => nil
71
73
 
72
- Service.configure(service_name, host=nil, options={})
73
- Configures the named +service_name+ on +host+, or the local host if no
74
- host is specified. The +options+ parameter is a hash that can contain any
75
- of the following parameters:
74
+ Service.configure(options={})
75
+ Configures an existing service. The +options+ parameter is a hash that can
76
+ contain any of the following parameters:
76
77
 
78
+ * service_name (mandatory)
79
+ * host
77
80
  * service_type
78
81
  * start_type
79
82
  * error_control
@@ -350,10 +353,10 @@ Service::ERROR_CRITICAL
350
353
  Use RegisterServiceCtrlHandlerEx().
351
354
 
352
355
  = Copyright
353
- (C) 2003-2008, Daniel J. Berger, All Rights Reserved
356
+ (C) 2003-2009, Daniel J. Berger, All Rights Reserved
354
357
 
355
358
  = License
356
- Ruby's
359
+ Artistic 2.0
357
360
 
358
361
  = Warranty
359
362
  This package is provided "as is" and without any express or
@@ -0,0 +1,122 @@
1
+ ############################################################################
2
+ # demo_daemon_ctl.rb
3
+ #
4
+ # This is a command line script for installing and/or running a small
5
+ # Ruby program as a service. The service will simply write a small bit
6
+ # of text to a file every 20 seconds. It will also write some text to the
7
+ # file during the initialization (service_init) step.
8
+ #
9
+ # It should take about 10 seconds to start, which is intentional - it's a test
10
+ # of the service_init hook, so don't be surprised if you see "one moment,
11
+ # start pending" about 10 times on the command line.
12
+ #
13
+ # The file in question is C:\test.log. Feel free to delete it when finished.
14
+ #
15
+ # To run the service, you must install it first.
16
+ #
17
+ # Usage: ruby demo_daemon_ctl.rb <option>
18
+ #
19
+ # Note that you *must* pass this program an option
20
+ #
21
+ # Options:
22
+ # install - Installs the service. The service name is "DemoSvc"
23
+ # and the display name is "Demo".
24
+ # start - Starts the service. Make sure you stop it at some point or
25
+ # you will eventually fill up your filesystem!.
26
+ # stop - Stops the service.
27
+ # pause - Pauses the service.
28
+ # resume - Resumes the service.
29
+ # uninstall - Uninstalls the service.
30
+ # delete - Same as uninstall.
31
+ #
32
+ # You can also used the Windows Services GUI to start and stop the service.
33
+ #
34
+ # To get to the Windows Services GUI just follow:
35
+ # Start -> Control Panel -> Administrative Tools -> Services
36
+ ############################################################################
37
+ require 'win32/service'
38
+ require 'rbconfig'
39
+ include Win32
40
+ include Config
41
+
42
+ # Make sure you're using the version you think you're using.
43
+ puts 'VERSION: ' + Service::VERSION
44
+
45
+ SERVICE_NAME = 'DemoSvc'
46
+ SERVICE_DISPLAYNAME = 'Demo'
47
+
48
+ # Quote the full path to deal with possible spaces in the path name.
49
+ ruby = File.join(CONFIG['bindir'], 'ruby').tr('/', '\\')
50
+ path = ' "' + File.dirname(File.expand_path($0)).tr('/', '\\')
51
+ path += '\demo_daemon.rb"'
52
+ cmd = ruby + path
53
+
54
+ # You must provide at least one argument.
55
+ raise ArgumentError, 'No argument provided' unless ARGV[0]
56
+
57
+ case ARGV[0].downcase
58
+ when 'install'
59
+ Service.new(
60
+ :service_name => SERVICE_NAME,
61
+ :display_name => SERVICE_DISPLAYNAME,
62
+ :description => 'Sample Ruby service',
63
+ :binary_path_name => cmd
64
+ )
65
+ puts 'Service ' + SERVICE_NAME + ' installed'
66
+ when 'start'
67
+ if Service.status(SERVICE_NAME).current_state != 'running'
68
+ Service.start(SERVICE_NAME, nil, 'hello', 'world')
69
+ while Service.status(SERVICE_NAME).current_state != 'running'
70
+ puts 'One moment...' + Service.status(SERVICE_NAME).current_state
71
+ sleep 1
72
+ end
73
+ puts 'Service ' + SERVICE_NAME + ' started'
74
+ else
75
+ puts 'Already running'
76
+ end
77
+ when 'stop'
78
+ if Service.status(SERVICE_NAME).current_state != 'stopped'
79
+ Service.stop(SERVICE_NAME)
80
+ while Service.status(SERVICE_NAME).current_state != 'stopped'
81
+ puts 'One moment...' + Service.status(SERVICE_NAME).current_state
82
+ sleep 1
83
+ end
84
+ puts 'Service ' + SERVICE_NAME + ' stopped'
85
+ else
86
+ puts 'Already stopped'
87
+ end
88
+ when 'uninstall', 'delete'
89
+ if Service.status(SERVICE_NAME).current_state != 'stopped'
90
+ Service.stop(SERVICE_NAME)
91
+ end
92
+ while Service.status(SERVICE_NAME).current_state != 'stopped'
93
+ puts 'One moment...' + Service.status(SERVICE_NAME).current_state
94
+ sleep 1
95
+ end
96
+ Service.delete(SERVICE_NAME)
97
+ puts 'Service ' + SERVICE_NAME + ' deleted'
98
+ when 'pause'
99
+ if Service.status(SERVICE_NAME).current_state != 'paused'
100
+ Service.pause(SERVICE_NAME)
101
+ while Service.status(SERVICE_NAME).current_state != 'paused'
102
+ puts 'One moment...' + Service.status(SERVICE_NAME).current_state
103
+ sleep 1
104
+ end
105
+ puts 'Service ' + SERVICE_NAME + ' paused'
106
+ else
107
+ puts 'Already paused'
108
+ end
109
+ when 'resume'
110
+ if Service.status(SERVICE_NAME).current_state != 'running'
111
+ Service.resume(SERVICE_NAME)
112
+ while Service.status(SERVICE_NAME).current_state != 'running'
113
+ puts 'One moment...' + Service.status(SERVICE_NAME).current_state
114
+ sleep 1
115
+ end
116
+ puts 'Service ' + SERVICE_NAME + ' resumed'
117
+ else
118
+ puts 'Already running'
119
+ end
120
+ else
121
+ raise ArgumentError, 'unknown option: ' + ARGV[0]
122
+ end
@@ -0,0 +1,23 @@
1
+ #######################################################################
2
+ # demo_services.rb
3
+ #
4
+ # Test script for general futzing that shows off the basic
5
+ # capabilities of this library. Modify as you see fit.
6
+ #######################################################################
7
+ require 'win32/service'
8
+ include Win32
9
+
10
+ puts "VERSION: " + Service::VERSION
11
+
12
+ p Service.exists?("ClipSrv")
13
+ p Service.exists?("foo")
14
+
15
+ status = Service.status("ClipSrv")
16
+ p status
17
+
18
+ info = Service.config_info("ClipSrv")
19
+ p info
20
+
21
+ Service.services{ |struct|
22
+ p struct
23
+ }
data/ext/extconf.rb CHANGED
@@ -1,5 +1,5 @@
1
- require 'mkmf'
2
-
3
- dir_config('win32-daemon')
4
- have_func('RegisterServiceCtrlHandlerEx')
5
- create_makefile('win32/daemon', 'win32')
1
+ require 'mkmf'
2
+
3
+ dir_config('win32-daemon')
4
+ have_func('RegisterServiceCtrlHandlerEx')
5
+ create_makefile('win32/daemon', 'win32')
data/ext/win32/daemon.c CHANGED
@@ -5,7 +5,7 @@
5
5
  #include <malloc.h>
6
6
  #include <tchar.h>
7
7
 
8
- #define WIN32_SERVICE_VERSION "0.6.1"
8
+ #define WIN32_SERVICE_VERSION "0.7.0"
9
9
 
10
10
  static VALUE cDaemonError;
11
11
 
@@ -66,34 +66,23 @@ void WINAPI Service_Main(DWORD dwArgc, LPTSTR *lpszArgv)
66
66
  {
67
67
  // Obtain the name of the service.
68
68
  LPTSTR lpszServiceName = lpszArgv[0];
69
-
69
+
70
70
  // Args passed to Service.start
71
71
  if(dwArgc > 1){
72
- int i;
72
+ unsigned int i;
73
73
  Argc = dwArgc - 1;
74
74
  Argv = malloc(sizeof(VALUE)*Argc);
75
-
76
- for(i=1;i<dwArgc;i++)
75
+
76
+ for(i=1; i < dwArgc; i++)
77
77
  Argv[i-1] = rb_str_new2(lpszArgv[i]);
78
78
  }
79
79
 
80
80
  // Register the service ctrl handler.
81
81
  ssh = RegisterServiceCtrlHandler(lpszServiceName,
82
82
  (LPHANDLER_FUNCTION)Service_Ctrl);
83
-
84
- // Redirect STDIN, STDOUT and STDERR to the NUL device if they're still
85
- // associated with a tty. This helps newbs avoid Errno::EBADF errors.
86
- if(rb_funcall(rb_stdin, rb_intern("isatty"), 0) == Qtrue)
87
- rb_funcall(rb_stdin, rb_intern("reopen"), 1, rb_str_new2("NUL"));
88
-
89
- if(rb_funcall(rb_stdout, rb_intern("isatty"), 0) == Qtrue)
90
- rb_funcall(rb_stdout, rb_intern("reopen"), 1, rb_str_new2("NUL"));
91
-
92
- if(rb_funcall(rb_stderr, rb_intern("isatty"), 0) == Qtrue)
93
- rb_funcall(rb_stderr, rb_intern("reopen"), 1, rb_str_new2("NUL"));
94
83
 
95
84
  // no service to stop, no service handle to notify, nothing to do but exit
96
- if(ssh == (SERVICE_STATUS_HANDLE)0)
85
+ if(ssh == (SERVICE_STATUS_HANDLE)0)
97
86
  return;
98
87
 
99
88
  // The service has started.
@@ -274,7 +263,7 @@ DWORD WINAPI ThreadProc(LPVOID lpParameter){
274
263
  SERVICE_TABLE_ENTRY ste[] =
275
264
  {{TEXT(""),(LPSERVICE_MAIN_FUNCTION)Service_Main}, {NULL, NULL}};
276
265
 
277
- // No service to step, no service handle, no ruby exceptions, just
266
+ // No service to step, no service handle, no ruby exceptions, just
278
267
  // terminate the thread.
279
268
  if(!StartServiceCtrlDispatcher(ste))
280
269
  return 1;
@@ -291,12 +280,12 @@ static VALUE daemon_allocate(VALUE klass){
291
280
  static VALUE daemon_mainloop_protect(VALUE self)
292
281
  {
293
282
  if(rb_respond_to(self,rb_intern("service_main"))){
294
- if(Argc == 0)
283
+ if(Argc == 0)
295
284
  rb_funcall(self, rb_intern("service_main"), 0);
296
285
  else
297
286
  rb_funcall2(self, rb_intern("service_main"), Argc, Argv);
298
- }
299
-
287
+ }
288
+
300
289
  return self;
301
290
  }
302
291
 
@@ -341,115 +330,126 @@ static VALUE daemon_mainloop_ensure(VALUE self)
341
330
  */
342
331
  static VALUE daemon_mainloop(VALUE self)
343
332
  {
344
- DWORD ThreadId;
345
- HANDLE events[2];
346
- DWORD index;
347
- VALUE result, EventHookHash;
348
- int status = 0;
333
+ DWORD ThreadId;
334
+ HANDLE events[2];
335
+ DWORD index;
336
+ VALUE result, EventHookHash;
337
+ int status = 0;
338
+
339
+ dwServiceState = 0;
340
+
341
+ // Redirect STDIN, STDOUT and STDERR to the NUL device if they're still
342
+ // associated with a tty. This helps newbs avoid Errno::EBADF errors.
343
+ if(rb_funcall(rb_stdin, rb_intern("isatty"), 0) == Qtrue)
344
+ rb_funcall(rb_stdin, rb_intern("reopen"), 1, rb_str_new2("NUL"));
349
345
 
350
- dwServiceState = 0;
346
+ if(rb_funcall(rb_stdout, rb_intern("isatty"), 0) == Qtrue)
347
+ rb_funcall(rb_stdout, rb_intern("reopen"), 1, rb_str_new2("NUL"));
351
348
 
352
- // use a markable instance variable to prevent the garbage collector
349
+ if(rb_funcall(rb_stderr, rb_intern("isatty"), 0) == Qtrue)
350
+ rb_funcall(rb_stderr, rb_intern("reopen"), 1, rb_str_new2("NUL"));
351
+
352
+ // Use a markable instance variable to prevent the garbage collector
353
353
  // from freeing the hash before Ruby_Service_Ctrl exits, or just
354
354
  // at any ole time while running the service
355
355
  EventHookHash = rb_hash_new();
356
356
  rb_ivar_set(self, rb_intern("@event_hooks"), EventHookHash);
357
357
 
358
- // Event hooks
359
- if(rb_respond_to(self, rb_intern("service_stop"))){
360
- rb_hash_aset(EventHookHash, INT2NUM(SERVICE_CONTROL_STOP),
361
- rb_ary_new3(2, self, INT2NUM(rb_intern("service_stop"))));
362
- }
358
+ // Event hooks
359
+ if(rb_respond_to(self, rb_intern("service_stop"))){
360
+ rb_hash_aset(EventHookHash, INT2NUM(SERVICE_CONTROL_STOP),
361
+ rb_ary_new3(2, self, INT2NUM(rb_intern("service_stop"))));
362
+ }
363
363
 
364
- if(rb_respond_to(self, rb_intern("service_pause"))){
365
- rb_hash_aset(EventHookHash, INT2NUM(SERVICE_CONTROL_PAUSE),
366
- rb_ary_new3(2, self, INT2NUM(rb_intern("service_pause"))));
367
- }
364
+ if(rb_respond_to(self, rb_intern("service_pause"))){
365
+ rb_hash_aset(EventHookHash, INT2NUM(SERVICE_CONTROL_PAUSE),
366
+ rb_ary_new3(2, self, INT2NUM(rb_intern("service_pause"))));
367
+ }
368
368
 
369
- if(rb_respond_to(self, rb_intern("service_resume"))){
370
- rb_hash_aset(EventHookHash, INT2NUM(SERVICE_CONTROL_CONTINUE),
371
- rb_ary_new3(2, self, INT2NUM(rb_intern("service_resume"))));
372
- }
369
+ if(rb_respond_to(self, rb_intern("service_resume"))){
370
+ rb_hash_aset(EventHookHash, INT2NUM(SERVICE_CONTROL_CONTINUE),
371
+ rb_ary_new3(2, self, INT2NUM(rb_intern("service_resume"))));
372
+ }
373
373
 
374
- if(rb_respond_to(self, rb_intern("service_interrogate"))){
375
- rb_hash_aset(EventHookHash, INT2NUM(SERVICE_CONTROL_INTERROGATE),
376
- rb_ary_new3(2, self, INT2NUM(rb_intern("service_interrogate"))));
377
- }
374
+ if(rb_respond_to(self, rb_intern("service_interrogate"))){
375
+ rb_hash_aset(EventHookHash, INT2NUM(SERVICE_CONTROL_INTERROGATE),
376
+ rb_ary_new3(2, self, INT2NUM(rb_intern("service_interrogate"))));
377
+ }
378
378
 
379
- if(rb_respond_to(self, rb_intern("service_shutdown"))){
380
- rb_hash_aset(EventHookHash, INT2NUM(SERVICE_CONTROL_SHUTDOWN),
381
- rb_ary_new3(2, self, INT2NUM(rb_intern("service_shutdown"))));
382
- }
379
+ if(rb_respond_to(self, rb_intern("service_shutdown"))){
380
+ rb_hash_aset(EventHookHash, INT2NUM(SERVICE_CONTROL_SHUTDOWN),
381
+ rb_ary_new3(2, self, INT2NUM(rb_intern("service_shutdown"))));
382
+ }
383
383
 
384
384
  #ifdef SERVICE_CONTROL_PARAMCHANGE
385
- if(rb_respond_to(self, rb_intern("service_paramchange"))){
386
- rb_hash_aset(EventHookHash, INT2NUM(SERVICE_CONTROL_PARAMCHANGE),
387
- rb_ary_new3(2, self, INT2NUM(rb_intern("service_paramchange"))));
388
- }
385
+ if(rb_respond_to(self, rb_intern("service_paramchange"))){
386
+ rb_hash_aset(EventHookHash, INT2NUM(SERVICE_CONTROL_PARAMCHANGE),
387
+ rb_ary_new3(2, self, INT2NUM(rb_intern("service_paramchange"))));
388
+ }
389
389
  #endif
390
390
 
391
391
  #ifdef SERVICE_CONTROL_NETBINDADD
392
- if(rb_respond_to(self, rb_intern("service_netbindadd"))){
393
- rb_hash_aset(EventHookHash, INT2NUM(SERVICE_CONTROL_NETBINDADD),
394
- rb_ary_new3(2, self, INT2NUM(rb_intern("service_netbindadd"))));
395
- }
392
+ if(rb_respond_to(self, rb_intern("service_netbindadd"))){
393
+ rb_hash_aset(EventHookHash, INT2NUM(SERVICE_CONTROL_NETBINDADD),
394
+ rb_ary_new3(2, self, INT2NUM(rb_intern("service_netbindadd"))));
395
+ }
396
396
  #endif
397
397
 
398
398
  #ifdef SERVICE_CONTROL_NETBINDREMOVE
399
- if(rb_respond_to(self, rb_intern("service_netbindremove"))){
400
- rb_hash_aset(EventHookHash, INT2NUM(SERVICE_CONTROL_NETBINDREMOVE),
401
- rb_ary_new3(2, self, INT2NUM(rb_intern("service_netbindremove"))));
402
- }
399
+ if(rb_respond_to(self, rb_intern("service_netbindremove"))){
400
+ rb_hash_aset(EventHookHash, INT2NUM(SERVICE_CONTROL_NETBINDREMOVE),
401
+ rb_ary_new3(2, self, INT2NUM(rb_intern("service_netbindremove"))));
402
+ }
403
403
  #endif
404
404
 
405
405
  #ifdef SERVICE_CONTROL_NETBINDENABLE
406
- if(rb_respond_to(self, rb_intern("service_netbindenable"))){
407
- rb_hash_aset(EventHookHash, INT2NUM(SERVICE_CONTROL_NETBINDENABLE),
408
- rb_ary_new3(2, self, INT2NUM(rb_intern("service_netbindenable"))));
409
- }
406
+ if(rb_respond_to(self, rb_intern("service_netbindenable"))){
407
+ rb_hash_aset(EventHookHash, INT2NUM(SERVICE_CONTROL_NETBINDENABLE),
408
+ rb_ary_new3(2, self, INT2NUM(rb_intern("service_netbindenable"))));
409
+ }
410
410
  #endif
411
411
 
412
412
  #ifdef SERVICE_CONTROL_NETBINDDISABLE
413
- if(rb_respond_to(self, rb_intern("service_netbinddisable"))){
414
- rb_hash_aset(EventHookHash, INT2NUM(SERVICE_CONTROL_NETBINDDISABLE),
415
- rb_ary_new3(2, self, INT2NUM(rb_intern("service_netbinddisable"))));
416
- }
413
+ if(rb_respond_to(self, rb_intern("service_netbinddisable"))){
414
+ rb_hash_aset(EventHookHash, INT2NUM(SERVICE_CONTROL_NETBINDDISABLE),
415
+ rb_ary_new3(2, self, INT2NUM(rb_intern("service_netbinddisable"))));
416
+ }
417
417
  #endif
418
418
 
419
- // calling init here so that init failures never even tries to
420
- // start the service... of course that means that init methods
421
- // must be very quick, because the SCM will be receiving no
422
- // START_PENDING messages while init's running - I may fix this
423
- // later
424
- if(rb_respond_to(self, rb_intern("service_init")))
425
- rb_funcall(self, rb_intern("service_init"),0);
419
+ // Calling init here so that init failures never even tries to
420
+ // start the service... of course that means that init methods
421
+ // must be very quick, because the SCM will be receiving no
422
+ // START_PENDING messages while init's running - I may fix this
423
+ // later
424
+ if(rb_respond_to(self, rb_intern("service_init")))
425
+ rb_funcall(self, rb_intern("service_init"),0);
426
426
 
427
- // Create the event to signal the service to start.
428
- hStartEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
427
+ // Create the event to signal the service to start.
428
+ hStartEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
429
429
 
430
- if(hStartEvent == NULL)
431
- rb_raise(cDaemonError, ErrorDescription(GetLastError()));
430
+ if(hStartEvent == NULL)
431
+ rb_raise(cDaemonError, ErrorDescription(GetLastError()));
432
432
 
433
- // Create the event to signal the service to stop.
434
- hStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
433
+ // Create the event to signal the service to stop.
434
+ hStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
435
435
 
436
- if(hStopEvent == NULL)
437
- rb_raise(cDaemonError, ErrorDescription(GetLastError()));
436
+ if(hStopEvent == NULL)
437
+ rb_raise(cDaemonError, ErrorDescription(GetLastError()));
438
438
 
439
- // Create the event to signal the service that stop has completed
440
- hStopCompletedEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
439
+ // Create the event to signal the service that stop has completed
440
+ hStopCompletedEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
441
441
 
442
- if(hStopCompletedEvent == NULL)
443
- rb_raise(cDaemonError, ErrorDescription(GetLastError()));
442
+ if(hStopCompletedEvent == NULL)
443
+ rb_raise(cDaemonError, ErrorDescription(GetLastError()));
444
444
 
445
- // Create Thread for service main
446
- hThread = CreateThread(NULL, 0, ThreadProc, 0, 0, &ThreadId);
445
+ // Create Thread for service main
446
+ hThread = CreateThread(NULL, 0, ThreadProc, 0, 0, &ThreadId);
447
447
 
448
- if(hThread == INVALID_HANDLE_VALUE)
449
- rb_raise(cDaemonError, ErrorDescription(GetLastError()));
448
+ if(hThread == INVALID_HANDLE_VALUE)
449
+ rb_raise(cDaemonError, ErrorDescription(GetLastError()));
450
450
 
451
- events[0] = hThread;
452
- events[1] = hStartEvent;
451
+ events[0] = hThread;
452
+ events[1] = hStartEvent;
453
453
 
454
454
  // wait for Service_Main function to either start the service OR terminate
455
455
  while((index = WaitForMultipleObjects(2,events,FALSE,1000)) == WAIT_TIMEOUT)
@@ -480,10 +480,10 @@ static VALUE daemon_mainloop(VALUE self)
480
480
  /*
481
481
  * Returns the state of the service (as an constant integer) which can be any
482
482
  * of the service status constants, e.g. RUNNING, PAUSED, etc.
483
- *
483
+ *
484
484
  * This method is typically used within your service_main method to setup the
485
485
  * loop. For example:
486
- *
486
+ *
487
487
  * class MyDaemon < Daemon
488
488
  * def service_main
489
489
  * while state == RUNNING || state == PAUSED || state == IDLE
@@ -491,7 +491,7 @@ static VALUE daemon_mainloop(VALUE self)
491
491
  * end
492
492
  * end
493
493
  * end
494
- *
494
+ *
495
495
  * See the Daemon#running? method for an abstraction of the above code.
496
496
  */
497
497
  static VALUE daemon_state(VALUE self){
@@ -501,10 +501,10 @@ static VALUE daemon_state(VALUE self){
501
501
  /*
502
502
  * Returns whether or not the service is in a running state, i.e. the service
503
503
  * status is either RUNNING, PAUSED or IDLE.
504
- *
504
+ *
505
505
  * This is typically used within your service_main method to setup the main
506
506
  * loop. For example:
507
- *
507
+ *
508
508
  * class MyDaemon < Daemon
509
509
  * def service_main
510
510
  * while running?
@@ -522,11 +522,11 @@ static VALUE daemon_is_running(VALUE self){
522
522
  ){
523
523
  v_bool = Qtrue;
524
524
  }
525
-
526
- return v_bool;
525
+
526
+ return v_bool;
527
527
  }
528
528
 
529
- /*
529
+ /*
530
530
  * This is a shortcut for Daemon.new + Daemon#mainloop.
531
531
  */
532
532
  static VALUE daemon_c_mainloop(VALUE klass){
@@ -552,17 +552,17 @@ void Init_daemon()
552
552
  rb_define_method(cDaemon, "mainloop", daemon_mainloop, 0);
553
553
  rb_define_method(cDaemon, "state", daemon_state, 0);
554
554
  rb_define_method(cDaemon, "running?", daemon_is_running, 0);
555
-
555
+
556
556
  rb_define_singleton_method(cDaemon, "mainloop", daemon_c_mainloop, 0);
557
557
 
558
558
  // Intialize critical section used by green polling thread
559
559
  InitializeCriticalSection(&csControlCode);
560
560
 
561
561
  // Constants
562
-
563
- /* 0.6.1: The version of this library */
562
+
563
+ /* 0.7.0: The version of this library */
564
564
  rb_define_const(cDaemon, "VERSION", rb_str_new2(WIN32_SERVICE_VERSION));
565
-
565
+
566
566
  /* Service has received a signal to resume but is not yet running */
567
567
  rb_define_const(cDaemon, "CONTINUE_PENDING",
568
568
  INT2NUM(SERVICE_CONTINUE_PENDING));
@@ -590,7 +590,7 @@ void Init_daemon()
590
590
  /* Service is stopped. */
591
591
  rb_define_const(cDaemon, "STOPPED",
592
592
  INT2NUM(SERVICE_STOPPED));
593
-
593
+
594
594
  /* Service is in an idle state */
595
595
  rb_define_const(cDaemon, "IDLE", INT2NUM(0));
596
596
  }