win32-service 0.8.7 → 0.8.8
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +2 -0
- data/CHANGES +21 -0
- data/MANIFEST +3 -0
- data/README +1 -7
- data/Rakefile +3 -6
- data/appveyor.yml +48 -0
- data/certs/djberg96_pub.pem +21 -0
- data/doc/daemon.txt +2 -2
- data/doc/service.txt +2 -2
- data/examples/demo_daemon.rb +1 -0
- data/examples/demo_daemon_ctl.rb +3 -2
- data/lib/win32-daemon.rb +1 -0
- data/lib/win32-service.rb +1 -0
- data/lib/win32/daemon.rb +14 -16
- data/lib/win32/service.rb +53 -43
- data/lib/win32/windows/functions.rb +4 -4
- data/lib/win32/windows/structs.rb +1 -1
- data/test/test_win32_daemon.rb +1 -1
- data/test/test_win32_service.rb +58 -27
- data/test/test_win32_service_configure.rb +17 -6
- data/test/test_win32_service_create.rb +47 -23
- data/test/test_win32_service_info.rb +24 -23
- data/win32-service.gemspec +3 -1
- metadata +54 -7
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8c9e7a6cfd6aa6f113daf315e64979fb66c9c83b
|
4
|
+
data.tar.gz: bc7920b71189a326bfd7b2b6e9affd2bd1fb1ded
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c3bca8887a30ced151972c81d62d0d724ba3954b62b7ce435b02053ce91d674602a2d274955992c6b4a28d751ce574da8f2ffb6aa5045e27b0b6d0cb345fa5fe
|
7
|
+
data.tar.gz: 8ad98044dd9fdee7917a2267715d0ecbd1b37d946525fba1a340391e877a6f340464fef6c31b4ad93f70e020e126ab5f986bc4830050d1bc66c366a2d9f59bda
|
checksums.yaml.gz.sig
ADDED
Binary file
|
data.tar.gz.sig
ADDED
data/CHANGES
CHANGED
@@ -1,3 +1,24 @@
|
|
1
|
+
== 0.8.8 - 24-Jun-2016
|
2
|
+
* Fixed the function prototypes for CreateEvent and AdjustTokenPrivileges
|
3
|
+
where I was using :bool instead of :int.
|
4
|
+
* Updated the various FFI module wrapper names so that they're more distinctly
|
5
|
+
namespaced. Avoids a clash with the win32-eventlog gem, and possibly others.
|
6
|
+
* Discovered more places where QueryServiceConfig2 could fail while attempting
|
7
|
+
to get failure actions and delayed auto start info. Instead of failing,
|
8
|
+
these now set their respective data to nil.
|
9
|
+
* A timeout value in our main observer thread was increased to potentially
|
10
|
+
improve performance. Feedback welcome.
|
11
|
+
* This gem is now signed.
|
12
|
+
* Added the win32-service.rb and win32-daemon.rb files for convenience.
|
13
|
+
* Use require_relative internally.
|
14
|
+
* Added win32-security as a development dependency. It was already being used
|
15
|
+
for tests but now it's actually part of the gemspec.
|
16
|
+
* Many tests are now skipped unless run with administrative privileges, either
|
17
|
+
because they require it, or because they otherwise take too long.
|
18
|
+
* Gem related tasks in the Rakefile now assume Rubygems 2.x.
|
19
|
+
* Added an appveyor.yml file.
|
20
|
+
* The DemoDaemon example will create C:/Tmp if it doesn't already exist.
|
21
|
+
|
1
22
|
== 0.8.7 - 14-Jul-2014
|
2
23
|
* Fixed a bug in the SERVICE_DELAYED_AUTO_START_INFO struct. It now returns 0
|
3
24
|
or 1, though it still accepts true or false as arguments. Thanks go to
|
data/MANIFEST
CHANGED
@@ -3,11 +3,14 @@
|
|
3
3
|
* README
|
4
4
|
* Rakefile
|
5
5
|
* win32-service.gemspec
|
6
|
+
* certs/djberg96_pub.pem
|
6
7
|
* doc/daemon.txt
|
7
8
|
* doc/service.txt
|
8
9
|
* examples/demo_daemon.rb
|
9
10
|
* examples/demo_daemon_ctl.rb
|
10
11
|
* examples/demo_services.rb
|
12
|
+
* lib/win32-daemon.rb
|
13
|
+
* lib/win32-service.rb
|
11
14
|
* lib/win32/service.rb
|
12
15
|
* lib/win32/daemon.rb
|
13
16
|
* test/test_win32_daemon.rb
|
data/README
CHANGED
@@ -56,17 +56,11 @@
|
|
56
56
|
Add service_session_change hook
|
57
57
|
|
58
58
|
== Copyright
|
59
|
-
(C) 2003-
|
59
|
+
(C) 2003-2016, Daniel J. Berger, All Rights Reserved
|
60
60
|
|
61
61
|
== License
|
62
62
|
Artistic 2.0
|
63
63
|
|
64
|
-
== Contributions
|
65
|
-
Although this library is free, please consider having your company
|
66
|
-
setup a gittip if used by your company professionally.
|
67
|
-
|
68
|
-
http://www.gittip.com/djberg96/
|
69
|
-
|
70
64
|
== Warranty
|
71
65
|
This package is provided "as is" and without any express or
|
72
66
|
implied warranties, including, without limitation, the implied
|
data/Rakefile
CHANGED
@@ -12,13 +12,10 @@ CLEAN.include(
|
|
12
12
|
namespace 'gem' do
|
13
13
|
desc "Create the win32-service gem"
|
14
14
|
task :create => [:clean] do
|
15
|
+
require 'rubygems/package'
|
15
16
|
spec = eval(IO.read('win32-service.gemspec'))
|
16
|
-
|
17
|
-
|
18
|
-
else
|
19
|
-
require 'rubygems/package'
|
20
|
-
Gem::Package.build(spec)
|
21
|
-
end
|
17
|
+
spec.signing_key = File.join(Dir.home, '.ssh', 'gem-private_key.pem')
|
18
|
+
Gem::Package.build(spec, true)
|
22
19
|
end
|
23
20
|
|
24
21
|
desc "Install the win32-service gem"
|
data/appveyor.yml
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
version: '{build}'
|
2
|
+
branches:
|
3
|
+
only:
|
4
|
+
- ffi
|
5
|
+
skip_tags: true
|
6
|
+
clone_depth: 10
|
7
|
+
environment:
|
8
|
+
matrix:
|
9
|
+
- ruby_version: 193
|
10
|
+
ruby_dir: 1.9.1
|
11
|
+
- ruby_version: 200
|
12
|
+
ruby_dir: 2.0.0
|
13
|
+
- ruby_version: 200-x64
|
14
|
+
ruby_dir: 2.0.0
|
15
|
+
- ruby_version: 21
|
16
|
+
ruby_dir: 2.1.0
|
17
|
+
- ruby_version: 21-x64
|
18
|
+
ruby_dir: 2.1.0
|
19
|
+
- ruby_version: 22
|
20
|
+
ruby_dir: 2.2.0
|
21
|
+
- ruby_version: 22-x64
|
22
|
+
ruby_dir: 2.2.0
|
23
|
+
install:
|
24
|
+
- ps: >-
|
25
|
+
$env:path = "C:\Ruby" + $env:ruby_version + "\bin;" + $env:path
|
26
|
+
|
27
|
+
$tpath = "C:\Ruby" + $env:ruby_version + "\lib\ruby\" + $env:ruby_dir + "\test"
|
28
|
+
|
29
|
+
if ((test-path $tpath) -eq $True){ rm -recurse -force $tpath }
|
30
|
+
|
31
|
+
gem update --system > $null
|
32
|
+
|
33
|
+
if ((gem query -i ffi) -eq $False){ gem install ffi --no-document }
|
34
|
+
|
35
|
+
if ((gem query -i win32-security) -eq $False){ gem install win32-security --no-document }
|
36
|
+
|
37
|
+
if ((gem query -i test-unit -v ">= 3.0") -eq $False){ gem install test-unit --no-document }
|
38
|
+
cache:
|
39
|
+
- C:\Ruby193\lib\ruby\gems\1.9.1
|
40
|
+
- C:\Ruby200\lib\ruby\gems\2.0.0
|
41
|
+
- C:\Ruby200-x64\lib\ruby\gems\2.0.0
|
42
|
+
- C:\Ruby21\lib\ruby\gems\2.1.0
|
43
|
+
- C:\Ruby21-x64\lib\ruby\gems\2.1.0
|
44
|
+
- C:\Ruby22\lib\ruby\gems\2.2.0
|
45
|
+
- C:\Ruby22-x64\lib\ruby\gems\2.2.0
|
46
|
+
build: off
|
47
|
+
test_script:
|
48
|
+
- cmd: rake
|
@@ -0,0 +1,21 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIIDcDCCAligAwIBAgIBATANBgkqhkiG9w0BAQUFADA/MREwDwYDVQQDDAhkamJl
|
3
|
+
cmc5NjEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPyLGQBGRYDY29t
|
4
|
+
MB4XDTE1MDkwMjIwNDkxOFoXDTE2MDkwMTIwNDkxOFowPzERMA8GA1UEAwwIZGpi
|
5
|
+
ZXJnOTYxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixkARkWA2Nv
|
6
|
+
bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMyTkvXqRp6hLs9eoJOS
|
7
|
+
Hmi8kRYbq9Vkf15/hMxJpotYMgJVHHWrmDcC5Dye2PbnXjTkKf266Zw0PtT9h+lI
|
8
|
+
S3ts9HO+vaCFSMwFFZmnWJSpQ3CNw2RcHxjWkk9yF7imEM8Kz9ojhiDXzBetdV6M
|
9
|
+
gr0lV/alUr7TNVBDngbXEfTWscyXh1qd7xZ4EcOdsDktCe5G45N/o3662tPQvJsi
|
10
|
+
FOF0CM/KuBsa/HL1/eoEmF4B3EKIRfTHrQ3hu20Kv3RJ88QM4ec2+0dd97uX693O
|
11
|
+
zv6981fyEg+aXLkxrkViM/tz2qR2ZE0jPhHTREPYeMEgptRkTmWSKAuLVWrJEfgl
|
12
|
+
DtkCAwEAAaN3MHUwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFEwe
|
13
|
+
nn6bfJADmuIDiMSOzedOrL+xMB0GA1UdEQQWMBSBEmRqYmVyZzk2QGdtYWlsLmNv
|
14
|
+
bTAdBgNVHRIEFjAUgRJkamJlcmc5NkBnbWFpbC5jb20wDQYJKoZIhvcNAQEFBQAD
|
15
|
+
ggEBAHmNOCWoDVD75zHFueY0viwGDVP1BNGFC+yXcb7u2GlK+nEMCORqzURbYPf7
|
16
|
+
tL+/hzmePIRz7i30UM//64GI1NLv9jl7nIwjhPpXpf7/lu2I9hOTsvwSumb5UiKC
|
17
|
+
/sqBxI3sfj9pr79Wpv4MuikX1XPik7Ncb7NPsJPw06Lvyc3Hkg5X2XpPtLtS+Gr2
|
18
|
+
wKJnmzb5rIPS1cmsqv0M9LPWflzfwoZ/SpnmhagP+g05p8bRNKjZSA2iImM/GyYZ
|
19
|
+
EJYzxdPOrx2n6NYR3Hk+vHP0U7UBSveI6+qx+ndQYaeyCn+GRX2PKS9h66YF/Q1V
|
20
|
+
tGSHgAmcLlkdGgan182qsE/4kKM=
|
21
|
+
-----END CERTIFICATE-----
|
data/doc/daemon.txt
CHANGED
@@ -127,7 +127,7 @@ Daemon::IDLE
|
|
127
127
|
setup your own Daemon.
|
128
128
|
|
129
129
|
= Known Bugs
|
130
|
-
None known.
|
130
|
+
None known. Please report any bugs you find on the issue tracker at
|
131
131
|
https//github.com/djberg96/win32-service
|
132
132
|
|
133
133
|
= Future Plans
|
@@ -142,7 +142,7 @@ Daemon::IDLE
|
|
142
142
|
his patch that solved service responsiveness issues.
|
143
143
|
|
144
144
|
= Copyright
|
145
|
-
(C) 2003-
|
145
|
+
(C) 2003-2016 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
|
@@ -351,7 +351,7 @@ Service::ERROR_CRITICAL
|
|
351
351
|
Add ability to create or modify service failure actions.
|
352
352
|
|
353
353
|
= Copyright
|
354
|
-
(C) 2003-
|
354
|
+
(C) 2003-2016, Daniel J. Berger, All Rights Reserved
|
355
355
|
|
356
356
|
= Warranty
|
357
357
|
This package is provided "as is" and without any express or
|
data/examples/demo_daemon.rb
CHANGED
data/examples/demo_daemon_ctl.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
# demo_daemon_ctl.rb
|
3
3
|
#
|
4
4
|
# This is a command line script for installing and/or running a small
|
5
|
-
# Ruby program as a service.
|
5
|
+
# Ruby program as a service. The service will simply write a small bit
|
6
6
|
# of text to a file every 20 seconds. It will also write some text to the
|
7
7
|
# file during the initialization (service_init) step.
|
8
8
|
#
|
@@ -10,7 +10,8 @@
|
|
10
10
|
# of the service_init hook, so don't be surprised if you see "one moment,
|
11
11
|
# start pending" about 10 times on the command line.
|
12
12
|
#
|
13
|
-
# The file in question is C:\
|
13
|
+
# The file in question is C:\Tmp\win32_daemon_test.log. Feel free to delete
|
14
|
+
# it when you're finished.
|
14
15
|
#
|
15
16
|
# To run the service, you must install it first.
|
16
17
|
#
|
data/lib/win32-daemon.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require_relative 'win32/daemon'
|
@@ -0,0 +1 @@
|
|
1
|
+
require_relative 'win32/service'
|
data/lib/win32/daemon.rb
CHANGED
@@ -1,9 +1,7 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
require 'ffi'
|
1
|
+
require_relative 'windows/helper'
|
2
|
+
require_relative 'windows/constants'
|
3
|
+
require_relative 'windows/structs'
|
4
|
+
require_relative 'windows/functions'
|
7
5
|
|
8
6
|
# The Win32 module serves as a namespace only.
|
9
7
|
module Win32
|
@@ -11,14 +9,14 @@ module Win32
|
|
11
9
|
# The Daemon class
|
12
10
|
class Daemon
|
13
11
|
include Windows::ServiceConstants
|
14
|
-
include Windows::
|
15
|
-
include Windows::
|
12
|
+
include Windows::ServiceStructs
|
13
|
+
include Windows::ServiceFunctions
|
16
14
|
|
17
|
-
extend Windows::
|
18
|
-
extend Windows::
|
15
|
+
extend Windows::ServiceStructs
|
16
|
+
extend Windows::ServiceFunctions
|
19
17
|
|
20
18
|
# The version of this library
|
21
|
-
VERSION = '0.8.
|
19
|
+
VERSION = '0.8.8'
|
22
20
|
|
23
21
|
private
|
24
22
|
|
@@ -240,21 +238,21 @@ module Win32
|
|
240
238
|
service_init() if respond_to?('service_init')
|
241
239
|
|
242
240
|
# Create the event to signal the service to start.
|
243
|
-
@@hStartEvent = CreateEvent(nil,
|
241
|
+
@@hStartEvent = CreateEvent(nil, 1, 0, nil)
|
244
242
|
|
245
243
|
if @@hStartEvent == 0
|
246
244
|
raise SystemCallError.new('CreateEvent', FFI.errno)
|
247
245
|
end
|
248
246
|
|
249
247
|
# Create the event to signal the service to stop.
|
250
|
-
@@hStopEvent = CreateEvent(nil,
|
248
|
+
@@hStopEvent = CreateEvent(nil, 1, 0, nil)
|
251
249
|
|
252
250
|
if @@hStopEvent == 0
|
253
251
|
raise SystemCallError.new('CreateEvent', FFI.errno)
|
254
252
|
end
|
255
253
|
|
256
254
|
# Create the event to signal the service that stop has completed
|
257
|
-
@@hStopCompletedEvent = CreateEvent(nil,
|
255
|
+
@@hStopCompletedEvent = CreateEvent(nil, 1, 0, nil)
|
258
256
|
|
259
257
|
if @@hStopCompletedEvent == 0
|
260
258
|
raise SystemCallError.new('CreateEvent', FFI.errno)
|
@@ -270,7 +268,7 @@ module Win32
|
|
270
268
|
events.put_pointer(0, FFI::Pointer.new(hThread))
|
271
269
|
events.put_pointer(FFI::Pointer.size, FFI::Pointer.new(@@hStartEvent))
|
272
270
|
|
273
|
-
while ((index = WaitForMultipleObjects(2, events,
|
271
|
+
while ((index = WaitForMultipleObjects(2, events, 0, 1000)) == WAIT_TIMEOUT) do
|
274
272
|
end
|
275
273
|
|
276
274
|
if index == WAIT_FAILED
|
@@ -284,7 +282,7 @@ module Win32
|
|
284
282
|
|
285
283
|
thr = Thread.new do
|
286
284
|
begin
|
287
|
-
while(WaitForSingleObject(@@hStopEvent,
|
285
|
+
while(WaitForSingleObject(@@hStopEvent, 1000) == WAIT_TIMEOUT)
|
288
286
|
# Check to see if anything interesting has been signaled
|
289
287
|
case @@waiting_control_code
|
290
288
|
when SERVICE_CONTROL_PAUSE
|
data/lib/win32/service.rb
CHANGED
@@ -10,14 +10,14 @@ module Win32
|
|
10
10
|
# creating, starting, configuring or deleting services.
|
11
11
|
class Service
|
12
12
|
include Windows::ServiceConstants
|
13
|
-
include Windows::
|
14
|
-
include Windows::
|
13
|
+
include Windows::ServiceStructs
|
14
|
+
include Windows::ServiceFunctions
|
15
15
|
|
16
|
-
extend Windows::
|
17
|
-
extend Windows::
|
16
|
+
extend Windows::ServiceStructs
|
17
|
+
extend Windows::ServiceFunctions
|
18
18
|
|
19
19
|
# The version of the win32-service library
|
20
|
-
VERSION = '0.8.
|
20
|
+
VERSION = '0.8.8'
|
21
21
|
|
22
22
|
# SCM security and access rights
|
23
23
|
|
@@ -1085,22 +1085,24 @@ module Win32
|
|
1085
1085
|
end
|
1086
1086
|
rescue
|
1087
1087
|
# While being annoying, not being able to get a description is not exceptional
|
1088
|
-
warn "WARNING: Failed to
|
1088
|
+
warn "WARNING: Failed to retrieve description for the #{service_name} service."
|
1089
1089
|
description = ''
|
1090
1090
|
end
|
1091
1091
|
|
1092
|
-
|
1093
|
-
|
1094
|
-
|
1095
|
-
|
1096
|
-
|
1097
|
-
|
1098
|
-
|
1092
|
+
begin
|
1093
|
+
delayed_start_buf = get_config2_info(handle_scs, SERVICE_CONFIG_DELAYED_AUTO_START_INFO)
|
1094
|
+
if delayed_start_buf.is_a?(FFI::MemoryPointer)
|
1095
|
+
delayed_start_info = SERVICE_DELAYED_AUTO_START_INFO.new(delayed_start_buf)
|
1096
|
+
delayed_start = delayed_start_info[:fDelayedAutostart]
|
1097
|
+
else
|
1098
|
+
delayed_start = false
|
1099
|
+
end
|
1100
|
+
rescue
|
1101
|
+
warn "WARNING: Unable to get delayed auto start information for the #{service_name} service"
|
1102
|
+
delayed_start = nil
|
1099
1103
|
end
|
1100
1104
|
else
|
1101
|
-
|
1102
|
-
msg += "service could not be found."
|
1103
|
-
warn msg
|
1105
|
+
warn "WARNING: The registry entry for the #{service_name} service could not be found"
|
1104
1106
|
|
1105
1107
|
binary_path = nil
|
1106
1108
|
load_order = nil
|
@@ -1112,41 +1114,49 @@ module Win32
|
|
1112
1114
|
description = nil
|
1113
1115
|
end
|
1114
1116
|
|
1115
|
-
|
1117
|
+
begin
|
1118
|
+
buf2 = get_config2_info(handle_scs, SERVICE_CONFIG_FAILURE_ACTIONS)
|
1116
1119
|
|
1117
|
-
|
1118
|
-
|
1120
|
+
if buf2.is_a?(FFI::MemoryPointer)
|
1121
|
+
fail_struct = SERVICE_FAILURE_ACTIONS.new(buf2)
|
1119
1122
|
|
1120
|
-
|
1121
|
-
|
1123
|
+
reset_period = fail_struct[:dwResetPeriod]
|
1124
|
+
num_actions = fail_struct[:cActions]
|
1122
1125
|
|
1123
|
-
|
1124
|
-
|
1125
|
-
|
1126
|
-
|
1127
|
-
|
1126
|
+
if fail_struct[:lpRebootMsg].null?
|
1127
|
+
reboot_msg = nil
|
1128
|
+
else
|
1129
|
+
reboot_msg = fail_struct[:lpRebootMsg].read_string
|
1130
|
+
end
|
1128
1131
|
|
1129
|
-
|
1130
|
-
|
1131
|
-
|
1132
|
-
|
1133
|
-
|
1132
|
+
if fail_struct[:lpCommand].null?
|
1133
|
+
command = nil
|
1134
|
+
else
|
1135
|
+
command = fail_struct[:lpCommand].read_string
|
1136
|
+
end
|
1134
1137
|
|
1135
|
-
|
1138
|
+
actions = nil
|
1136
1139
|
|
1137
|
-
|
1138
|
-
|
1140
|
+
if num_actions > 0
|
1141
|
+
action_ptr = fail_struct[:lpsaActions]
|
1139
1142
|
|
1140
|
-
|
1143
|
+
actions = {}
|
1141
1144
|
|
1142
|
-
|
1143
|
-
|
1144
|
-
|
1145
|
-
|
1146
|
-
|
1147
|
-
|
1145
|
+
num_actions.times{ |n|
|
1146
|
+
sc_action = SC_ACTION.new(action_ptr[n])
|
1147
|
+
delay = sc_action[:Delay]
|
1148
|
+
action_type = get_action_type(sc_action[:Type])
|
1149
|
+
actions[n+1] = {:action_type => action_type, :delay => delay}
|
1150
|
+
}
|
1151
|
+
end
|
1152
|
+
else
|
1153
|
+
reset_period = nil
|
1154
|
+
reboot_msg = nil
|
1155
|
+
command = nil
|
1156
|
+
actions = nil
|
1148
1157
|
end
|
1149
|
-
|
1158
|
+
rescue
|
1159
|
+
warn "WARNING: Unable to retrieve failure actions for the #{service_name} service"
|
1150
1160
|
reset_period = nil
|
1151
1161
|
reboot_msg = nil
|
1152
1162
|
command = nil
|
@@ -1242,7 +1252,7 @@ module Win32
|
|
1242
1252
|
# Enable shutdown privilege in access token of this process
|
1243
1253
|
bool = AdjustTokenPrivileges(
|
1244
1254
|
token_handle,
|
1245
|
-
|
1255
|
+
0,
|
1246
1256
|
tkp,
|
1247
1257
|
tkp.size,
|
1248
1258
|
nil,
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'ffi'
|
2
2
|
|
3
3
|
module Windows
|
4
|
-
module
|
4
|
+
module ServiceFunctions
|
5
5
|
extend FFI::Library
|
6
6
|
|
7
7
|
# Make FFI functions private
|
@@ -22,7 +22,7 @@ module Windows
|
|
22
22
|
ffi_lib :kernel32
|
23
23
|
|
24
24
|
attach_pfunc :CloseHandle, [:handle], :bool
|
25
|
-
attach_pfunc :CreateEvent, :CreateEventA, [:ptr, :
|
25
|
+
attach_pfunc :CreateEvent, :CreateEventA, [:ptr, :int, :int, :str], :handle
|
26
26
|
attach_pfunc :CreateThread, [:ptr, :size_t, :ptr, :ptr, :dword, :ptr], :handle, :blocking => true
|
27
27
|
attach_pfunc :EnterCriticalSection, [:ptr], :void
|
28
28
|
attach_pfunc :FormatMessage, :FormatMessageA, [:ulong, :ptr, :ulong, :ulong, :str, :ulong, :ptr], :ulong
|
@@ -31,13 +31,13 @@ module Windows
|
|
31
31
|
attach_pfunc :LeaveCriticalSection, [:ptr], :void
|
32
32
|
attach_pfunc :SetEvent, [:handle], :bool
|
33
33
|
attach_pfunc :WaitForSingleObject, [:handle, :dword], :dword, :blocking => true
|
34
|
-
attach_pfunc :WaitForMultipleObjects, [:dword, :ptr, :
|
34
|
+
attach_pfunc :WaitForMultipleObjects, [:dword, :ptr, :int, :dword], :dword
|
35
35
|
|
36
36
|
ffi_lib :advapi32
|
37
37
|
|
38
38
|
callback :handler_ex, [:ulong, :ulong, :ptr, :ptr], :void
|
39
39
|
|
40
|
-
attach_pfunc :AdjustTokenPrivileges, [:handle, :
|
40
|
+
attach_pfunc :AdjustTokenPrivileges, [:handle, :int, :ptr, :dword, :ptr, :ptr], :bool
|
41
41
|
attach_pfunc :CloseServiceHandle, [:handle], :bool
|
42
42
|
|
43
43
|
attach_pfunc :ChangeServiceConfig, :ChangeServiceConfigA,
|
data/test/test_win32_daemon.rb
CHANGED
data/test/test_win32_service.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
##########################################################################
|
2
2
|
# test_win32_service.rb
|
3
3
|
#
|
4
|
-
# Tests for the Win32::Service class.
|
4
|
+
# Tests for the Win32::Service class. Some tests are skipped unless
|
5
|
+
# run with admin privileges either because they are somewhat invasive,
|
6
|
+
# or because they take too long.
|
5
7
|
##########################################################################
|
6
8
|
require 'test-unit'
|
7
9
|
require 'win32/security'
|
@@ -20,29 +22,39 @@ class TC_Win32_Service < Test::Unit::TestCase
|
|
20
22
|
@service_name = 'stisvc'
|
21
23
|
@service_stat = nil
|
22
24
|
@services = []
|
25
|
+
@elevated = Win32::Security.elevated_security?
|
23
26
|
|
24
27
|
@singleton_methods = Win32::Service.methods.map{ |m| m.to_s }
|
25
28
|
@instance_methods = Win32::Service.instance_methods.map{ |m| m.to_s }
|
26
29
|
end
|
27
30
|
|
31
|
+
def omit_unless_elevated
|
32
|
+
omit_unless(@elevated, "Skipped unless run with admin privileges")
|
33
|
+
end
|
34
|
+
|
28
35
|
def start_service(service)
|
29
36
|
status = Win32::Service.status(@service_name).current_state
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
37
|
+
|
38
|
+
if @elevated
|
39
|
+
if status == 'paused'
|
40
|
+
Win32::Service.resume(service)
|
41
|
+
else
|
42
|
+
unless ['running', 'start pending'].include?(status)
|
43
|
+
Win32::Service.start(service)
|
44
|
+
end
|
35
45
|
end
|
46
|
+
wait_for_status('running')
|
36
47
|
end
|
37
|
-
wait_for_status('running')
|
38
48
|
end
|
39
49
|
|
40
50
|
def stop_service(service)
|
41
51
|
status = Win32::Service.status(@service_name).current_state
|
42
|
-
|
43
|
-
|
52
|
+
if @elevated
|
53
|
+
unless ['stopped', 'stop pending'].include?(status)
|
54
|
+
Win32::Service.stop(service)
|
55
|
+
end
|
56
|
+
wait_for_status('stopped')
|
44
57
|
end
|
45
|
-
wait_for_status('stopped')
|
46
58
|
end
|
47
59
|
|
48
60
|
# Helper method that waits for a status to change its state since state
|
@@ -52,14 +64,23 @@ class TC_Win32_Service < Test::Unit::TestCase
|
|
52
64
|
end
|
53
65
|
|
54
66
|
test "version number is expected value" do
|
55
|
-
assert_equal('0.8.
|
67
|
+
assert_equal('0.8.8', Win32::Service::VERSION)
|
56
68
|
end
|
57
69
|
|
58
70
|
test "services basic functionality" do
|
59
71
|
assert_respond_to(Win32::Service, :services)
|
72
|
+
end
|
73
|
+
|
74
|
+
test "services with no arguments works as expected" do
|
60
75
|
assert_nothing_raised{ Win32::Service.services }
|
61
|
-
|
62
|
-
|
76
|
+
end
|
77
|
+
|
78
|
+
test "services with explicit host works as expected" do
|
79
|
+
assert_nothing_raised{ Win32::Service.services(@@host) }
|
80
|
+
end
|
81
|
+
|
82
|
+
test "services with explicit host and group works as expected" do
|
83
|
+
assert_nothing_raised{ Win32::Service.services(@@host, 'network') }
|
63
84
|
end
|
64
85
|
|
65
86
|
test "services method returns an array without a block" do
|
@@ -87,6 +108,7 @@ class TC_Win32_Service < Test::Unit::TestCase
|
|
87
108
|
end
|
88
109
|
|
89
110
|
test "a valid hostname must be provided or an error is raised" do
|
111
|
+
omit_unless_elevated
|
90
112
|
assert_raise(SystemCallError){ Win32::Service.services('bogus') }
|
91
113
|
end
|
92
114
|
|
@@ -99,11 +121,12 @@ class TC_Win32_Service < Test::Unit::TestCase
|
|
99
121
|
end
|
100
122
|
|
101
123
|
test "delete method raises an error if a bogus service name is provided" do
|
102
|
-
|
124
|
+
omit_unless_elevated
|
103
125
|
assert_raise(SystemCallError){ Win32::Service.delete('bogus') }
|
104
126
|
end
|
105
127
|
|
106
128
|
test "delete method raises an error if a bogus host name is provided" do
|
129
|
+
omit_unless_elevated
|
107
130
|
assert_raise(SystemCallError){ Win32::Service.delete('bogus', 'bogus') }
|
108
131
|
end
|
109
132
|
|
@@ -120,7 +143,7 @@ class TC_Win32_Service < Test::Unit::TestCase
|
|
120
143
|
end
|
121
144
|
|
122
145
|
test "pause and resume work as expected" do
|
123
|
-
|
146
|
+
omit_unless_elevated
|
124
147
|
start_service(@service_name)
|
125
148
|
|
126
149
|
assert_nothing_raised{ Win32::Service.pause(@service_name) }
|
@@ -131,7 +154,7 @@ class TC_Win32_Service < Test::Unit::TestCase
|
|
131
154
|
end
|
132
155
|
|
133
156
|
test "pausing an already paused service is harmless" do
|
134
|
-
|
157
|
+
omit_unless_elevated
|
135
158
|
start_service(@service_name)
|
136
159
|
|
137
160
|
assert_nothing_raised{ Win32::Service.pause(@service_name) }
|
@@ -148,6 +171,7 @@ class TC_Win32_Service < Test::Unit::TestCase
|
|
148
171
|
end
|
149
172
|
|
150
173
|
test "pausing a service on an unrecognized host raises an error" do
|
174
|
+
omit_unless_elevated
|
151
175
|
assert_raise(SystemCallError){ Win32::Service.pause('W32Time', 'bogus') }
|
152
176
|
end
|
153
177
|
|
@@ -164,6 +188,7 @@ class TC_Win32_Service < Test::Unit::TestCase
|
|
164
188
|
end
|
165
189
|
|
166
190
|
test "resume method with an unrecognized host name raises an error" do
|
191
|
+
omit_unless_elevated
|
167
192
|
assert_raise(SystemCallError){ Win32::Service.resume('W32Time', 'bogus') }
|
168
193
|
end
|
169
194
|
|
@@ -180,7 +205,7 @@ class TC_Win32_Service < Test::Unit::TestCase
|
|
180
205
|
end
|
181
206
|
|
182
207
|
test "stop and start methods work as expected" do
|
183
|
-
|
208
|
+
omit_unless_elevated
|
184
209
|
start_service(@service_name)
|
185
210
|
|
186
211
|
assert_nothing_raised{ Win32::Service.stop(@service_name) }
|
@@ -191,7 +216,7 @@ class TC_Win32_Service < Test::Unit::TestCase
|
|
191
216
|
end
|
192
217
|
|
193
218
|
test "attempting to stop a stopped service raises an error" do
|
194
|
-
|
219
|
+
omit_unless_elevated
|
195
220
|
start_service(@service_name)
|
196
221
|
|
197
222
|
assert_nothing_raised{ Win32::Service.stop(@service_name) }
|
@@ -210,6 +235,7 @@ class TC_Win32_Service < Test::Unit::TestCase
|
|
210
235
|
end
|
211
236
|
|
212
237
|
test "stop method raises an error if the host is unrecognized" do
|
238
|
+
omit_unless_elevated
|
213
239
|
assert_raise(SystemCallError){ Win32::Service.stop('W32Time', 'bogus') }
|
214
240
|
end
|
215
241
|
|
@@ -222,7 +248,7 @@ class TC_Win32_Service < Test::Unit::TestCase
|
|
222
248
|
end
|
223
249
|
|
224
250
|
test "attempting to start a running service raises an error" do
|
225
|
-
|
251
|
+
omit_unless_elevated
|
226
252
|
start_service(@service_name)
|
227
253
|
assert_raise(SystemCallError){ Win32::Service.start(@service_name) }
|
228
254
|
end
|
@@ -232,6 +258,7 @@ class TC_Win32_Service < Test::Unit::TestCase
|
|
232
258
|
end
|
233
259
|
|
234
260
|
test "attempting to start a service on an unknown host raises an error" do
|
261
|
+
omit_unless_elevated
|
235
262
|
assert_raise(SystemCallError){ Win32::Service.start('bogus', 'bogus') }
|
236
263
|
end
|
237
264
|
|
@@ -244,6 +271,7 @@ class TC_Win32_Service < Test::Unit::TestCase
|
|
244
271
|
end
|
245
272
|
|
246
273
|
test "stop raises an error with an unrecognized host" do
|
274
|
+
omit_unless_elevated
|
247
275
|
assert_raise(SystemCallError){ Win32::Service.stop('W32Time', 'bogus') }
|
248
276
|
end
|
249
277
|
|
@@ -281,6 +309,7 @@ class TC_Win32_Service < Test::Unit::TestCase
|
|
281
309
|
end
|
282
310
|
|
283
311
|
test "get_service_name raises an error if a bogus host is provided" do
|
312
|
+
omit_unless_elevated
|
284
313
|
assert_raise(SystemCallError){ Win32::Service.get_service_name('foo', 'bogus') }
|
285
314
|
end
|
286
315
|
|
@@ -312,6 +341,7 @@ class TC_Win32_Service < Test::Unit::TestCase
|
|
312
341
|
end
|
313
342
|
|
314
343
|
test "get_display_name raises an error if a bad host name is provided" do
|
344
|
+
omit_unless_elevated
|
315
345
|
assert_raise(SystemCallError){ Win32::Service.get_display_name('W32Time', 'bogus') }
|
316
346
|
end
|
317
347
|
|
@@ -335,9 +365,8 @@ class TC_Win32_Service < Test::Unit::TestCase
|
|
335
365
|
end
|
336
366
|
|
337
367
|
test "exists method raises an error if a bogus host is passed" do
|
338
|
-
|
339
|
-
|
340
|
-
}
|
368
|
+
omit_unless_elevated
|
369
|
+
assert_raises(SystemCallError){ Win32::Service.exists?('foo', 'bogus') }
|
341
370
|
end
|
342
371
|
|
343
372
|
test "exists method only accepts up to two arguments" do
|
@@ -424,12 +453,14 @@ class TC_Win32_Service < Test::Unit::TestCase
|
|
424
453
|
@@host = nil
|
425
454
|
status = Win32::Service.status(@@service_name).current_state
|
426
455
|
|
427
|
-
if
|
428
|
-
|
429
|
-
|
456
|
+
if @elevated
|
457
|
+
if status == 'paused'
|
458
|
+
Win32::Service.resume(@@service_name)
|
459
|
+
end
|
430
460
|
|
431
|
-
|
432
|
-
|
461
|
+
unless ['running', 'start pending'].include?(status)
|
462
|
+
Win32::Service.start(@@service_name)
|
463
|
+
end
|
433
464
|
end
|
434
465
|
|
435
466
|
@@elevated = nil
|
@@ -4,6 +4,7 @@
|
|
4
4
|
# Test suite that validates the Service.configure method.
|
5
5
|
#######################################################################
|
6
6
|
require 'test-unit'
|
7
|
+
require 'win32/security'
|
7
8
|
require 'win32/service'
|
8
9
|
|
9
10
|
class TC_Win32_Service_Configure < Test::Unit::TestCase
|
@@ -11,10 +12,12 @@ class TC_Win32_Service_Configure < Test::Unit::TestCase
|
|
11
12
|
@@service = "notepad_service"
|
12
13
|
@@command = "C:\\windows\\system32\\notepad.exe"
|
13
14
|
|
14
|
-
Win32::
|
15
|
-
|
16
|
-
|
17
|
-
|
15
|
+
if Win32::Security.elevated_security?
|
16
|
+
Win32::Service.new(
|
17
|
+
:service_name => @@service,
|
18
|
+
:binary_path_name => @@command
|
19
|
+
)
|
20
|
+
end
|
18
21
|
end
|
19
22
|
|
20
23
|
def config_info
|
@@ -39,7 +42,8 @@ class TC_Win32_Service_Configure < Test::Unit::TestCase
|
|
39
42
|
end
|
40
43
|
|
41
44
|
def setup
|
42
|
-
@
|
45
|
+
@elevated = Win32::Security.elevated_security?
|
46
|
+
@info = Win32::Service.config_info(@@service) if @elevated
|
43
47
|
end
|
44
48
|
|
45
49
|
test "configure method is defined" do
|
@@ -47,24 +51,28 @@ class TC_Win32_Service_Configure < Test::Unit::TestCase
|
|
47
51
|
end
|
48
52
|
|
49
53
|
test "configuring the service type works as expected" do
|
54
|
+
omit_unless(@elevated)
|
50
55
|
assert_equal('own process', config_info.service_type)
|
51
56
|
service_configure(:service_type => Win32::Service::WIN32_SHARE_PROCESS)
|
52
57
|
assert_equal('share process', config_info.service_type)
|
53
58
|
end
|
54
59
|
|
55
60
|
test "configuring the description works as expected" do
|
61
|
+
omit_unless(@elevated)
|
56
62
|
assert_equal('', full_info.description)
|
57
63
|
service_configure(:description => 'test service')
|
58
64
|
assert_equal('test service', full_info.description)
|
59
65
|
end
|
60
66
|
|
61
67
|
test "configuring the start type works as expected" do
|
68
|
+
omit_unless(@elevated)
|
62
69
|
assert_equal('demand start', config_info.start_type)
|
63
70
|
service_configure(:start_type => Win32::Service::DISABLED)
|
64
71
|
assert_equal('disabled', config_info.start_type)
|
65
72
|
end
|
66
73
|
|
67
74
|
test "service start can be delayed" do
|
75
|
+
omit_unless(@elevated)
|
68
76
|
service_configure(:start_type => Win32::Service::AUTO_START, :delayed_start => true)
|
69
77
|
assert_equal(1, full_info.delayed_start)
|
70
78
|
end
|
@@ -89,10 +97,13 @@ class TC_Win32_Service_Configure < Test::Unit::TestCase
|
|
89
97
|
|
90
98
|
def teardown
|
91
99
|
@info = nil
|
100
|
+
@elevated = nil
|
92
101
|
end
|
93
102
|
|
94
103
|
def self.shutdown
|
95
|
-
Win32::Service.
|
104
|
+
if Win32::Service.exists?(@@service) && Win32::Security.elevated_security?
|
105
|
+
Win32::Service.delete(@@service)
|
106
|
+
end
|
96
107
|
@@service = nil
|
97
108
|
@@command = nil
|
98
109
|
end
|
@@ -5,6 +5,7 @@
|
|
5
5
|
# a dummy (notepad) service. It won't actually run of course.
|
6
6
|
########################################################################
|
7
7
|
require 'test-unit'
|
8
|
+
require 'win32/security'
|
8
9
|
require 'win32/service'
|
9
10
|
|
10
11
|
class TC_Win32_Service_Create < Test::Unit::TestCase
|
@@ -13,28 +14,34 @@ class TC_Win32_Service_Create < Test::Unit::TestCase
|
|
13
14
|
@@service2 = "notepad_service2"
|
14
15
|
@@command = "C:\\windows\\system32\\notepad.exe"
|
15
16
|
|
16
|
-
Win32::
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
17
|
+
if Win32::Security.elevated_security?
|
18
|
+
Win32::Service.new(
|
19
|
+
:service_name => @@service1,
|
20
|
+
:binary_path_name => @@command
|
21
|
+
)
|
22
|
+
|
23
|
+
Win32::Service.new(
|
24
|
+
:service_name => @@service2,
|
25
|
+
:display_name => 'Notepad Test',
|
26
|
+
:desired_access => Win32::Service::ALL_ACCESS,
|
27
|
+
:service_type => Win32::Service::WIN32_OWN_PROCESS,
|
28
|
+
:start_type => Win32::Service::DISABLED,
|
29
|
+
:error_control => Win32::Service::ERROR_IGNORE,
|
30
|
+
:binary_path_name => @@command,
|
31
|
+
:load_order_group => 'Network',
|
32
|
+
:dependencies => 'W32Time',
|
33
|
+
:description => 'Test service. Please delete me'
|
34
|
+
)
|
35
|
+
end
|
33
36
|
end
|
34
37
|
|
35
38
|
def setup
|
36
|
-
@
|
37
|
-
|
39
|
+
@elevated = Win32::Security.elevated_security?
|
40
|
+
|
41
|
+
if @elevated
|
42
|
+
@info1 = Win32::Service.config_info(@@service1)
|
43
|
+
@info2 = Win32::Service.config_info(@@service2)
|
44
|
+
end
|
38
45
|
end
|
39
46
|
|
40
47
|
test "constructor basic functionality" do
|
@@ -48,48 +55,59 @@ class TC_Win32_Service_Create < Test::Unit::TestCase
|
|
48
55
|
end
|
49
56
|
|
50
57
|
test "ensure services were created in startup method" do
|
58
|
+
omit_unless(@elevated)
|
51
59
|
notify "If this test fails then remaining results are meaningless."
|
52
60
|
assert_true(Win32::Service.exists?(@@service1))
|
53
61
|
assert_true(Win32::Service.exists?(@@service2))
|
54
62
|
end
|
55
63
|
|
56
64
|
test "expected service type configuration information" do
|
65
|
+
omit_unless(@elevated)
|
57
66
|
assert_equal('own process', @info1.service_type)
|
58
67
|
end
|
59
68
|
|
60
69
|
test "expected start type configuration information" do
|
70
|
+
omit_unless(@elevated)
|
61
71
|
assert_equal('demand start', @info1.start_type)
|
62
72
|
end
|
63
73
|
|
64
74
|
test "expected error control configuration information" do
|
75
|
+
omit_unless(@elevated)
|
65
76
|
assert_equal('normal', @info1.error_control)
|
66
77
|
end
|
67
78
|
|
68
79
|
test "expected binary path name configuration information" do
|
80
|
+
omit_unless(@elevated)
|
69
81
|
assert_equal(@@command, @info1.binary_path_name)
|
70
82
|
end
|
71
83
|
|
72
84
|
test "expected load order group configuration information" do
|
85
|
+
omit_unless(@elevated)
|
73
86
|
assert_equal('', @info1.load_order_group)
|
74
87
|
end
|
75
88
|
|
76
89
|
test "expected tag id configuration information" do
|
90
|
+
omit_unless(@elevated)
|
77
91
|
assert_equal(0, @info1.tag_id)
|
78
92
|
end
|
79
93
|
|
80
94
|
test "expected dependency configuration information" do
|
95
|
+
omit_unless(@elevated)
|
81
96
|
assert_equal([], @info1.dependencies)
|
82
97
|
end
|
83
98
|
|
84
99
|
test "expected service start time configuration information" do
|
100
|
+
omit_unless(@elevated)
|
85
101
|
assert_equal('LocalSystem', @info1.service_start_name)
|
86
102
|
end
|
87
103
|
|
88
104
|
test "expected display name configuration information" do
|
105
|
+
omit_unless(@elevated)
|
89
106
|
assert_equal('notepad_service1', @info1.display_name)
|
90
107
|
end
|
91
108
|
|
92
109
|
test "configuration information options are set properly for service 2" do
|
110
|
+
omit_unless(@elevated)
|
93
111
|
assert_equal('own process', @info2.service_type)
|
94
112
|
assert_equal('disabled', @info2.start_type)
|
95
113
|
assert_equal('ignore', @info2.error_control)
|
@@ -114,13 +132,19 @@ class TC_Win32_Service_Create < Test::Unit::TestCase
|
|
114
132
|
end
|
115
133
|
|
116
134
|
def teardown
|
117
|
-
@
|
118
|
-
|
135
|
+
if @elevated
|
136
|
+
@info1 = nil
|
137
|
+
@info2 = nil
|
138
|
+
end
|
139
|
+
|
140
|
+
@elevated = nil
|
119
141
|
end
|
120
142
|
|
121
143
|
def self.shutdown
|
122
|
-
|
123
|
-
|
144
|
+
if Win32::Security.elevated_security?
|
145
|
+
Win32::Service.delete(@@service1) if Win32::Service.exists?(@@service1)
|
146
|
+
Win32::Service.delete(@@service2) if Win32::Service.exists?(@@service2)
|
147
|
+
end
|
124
148
|
|
125
149
|
@@service1 = nil
|
126
150
|
@@service2 = nil
|
@@ -71,106 +71,107 @@ class TC_Win32_ServiceInfo_Struct < Test::Unit::TestCase
|
|
71
71
|
]
|
72
72
|
end
|
73
73
|
|
74
|
-
|
74
|
+
test "service_name basic functionality" do
|
75
75
|
assert_respond_to(@service_info, :service_name)
|
76
76
|
assert_kind_of(String, @service_info.service_name)
|
77
77
|
end
|
78
78
|
|
79
|
-
|
79
|
+
test "display_name basic functionality" do
|
80
80
|
assert_respond_to(@service_info, :display_name)
|
81
81
|
assert_kind_of(String, @service_info.display_name)
|
82
82
|
end
|
83
83
|
|
84
|
-
|
84
|
+
test "service_type basic functionality" do
|
85
85
|
assert_respond_to(@service_info, :service_type)
|
86
86
|
assert(@types.include?(@service_info.service_type))
|
87
87
|
end
|
88
88
|
|
89
|
-
|
89
|
+
test "current_state basic functionality" do
|
90
90
|
assert_respond_to(@service_info, :current_state)
|
91
91
|
assert(@states.include?(@service_info.current_state))
|
92
92
|
end
|
93
93
|
|
94
|
-
|
94
|
+
test "controls_accepted basic functionality" do
|
95
95
|
assert_respond_to(@service_info, :controls_accepted)
|
96
96
|
assert_kind_of(Array, @service_info.controls_accepted)
|
97
|
+
end
|
98
|
+
|
99
|
+
test "controls_accepted returns expected values" do
|
97
100
|
assert_false(@service_info.controls_accepted.empty?)
|
98
|
-
@service_info.controls_accepted.each{ |
|
99
|
-
assert_true(@controls.include?(control))
|
100
|
-
}
|
101
|
+
@service_info.controls_accepted.each{ |c| assert_true(@controls.include?(c)) }
|
101
102
|
end
|
102
103
|
|
103
|
-
|
104
|
+
test "win32_exit_code basic functionality" do
|
104
105
|
assert_respond_to(@service_info, :win32_exit_code)
|
105
106
|
assert_kind_of(Fixnum, @service_info.win32_exit_code)
|
106
107
|
end
|
107
108
|
|
108
|
-
|
109
|
+
test "service_specific_exit_code basic functionality" do
|
109
110
|
assert_respond_to(@service_info, :service_specific_exit_code)
|
110
111
|
assert_kind_of(Fixnum, @service_info.service_specific_exit_code)
|
111
112
|
end
|
112
113
|
|
113
|
-
|
114
|
+
test "check_point basic functionality" do
|
114
115
|
assert_respond_to(@service_info, :check_point)
|
115
116
|
assert_kind_of(Fixnum, @service_info.check_point)
|
116
117
|
end
|
117
118
|
|
118
|
-
|
119
|
+
test "wait_hint basic functionality" do
|
119
120
|
assert_respond_to(@service_info, :wait_hint)
|
120
121
|
assert_kind_of(Fixnum, @service_info.wait_hint)
|
121
122
|
end
|
122
123
|
|
123
|
-
|
124
|
+
test "binary_path_name basic functionality" do
|
124
125
|
assert_respond_to(@service_info, :binary_path_name)
|
125
126
|
assert_kind_of(String, @service_info.binary_path_name)
|
126
127
|
end
|
127
128
|
|
128
|
-
|
129
|
+
test "start_type basic functionality" do
|
129
130
|
assert_respond_to(@service_info, :start_type)
|
130
131
|
assert(@start_types.include?(@service_info.start_type))
|
131
132
|
end
|
132
133
|
|
133
|
-
|
134
|
+
test "error_control basic functionality" do
|
134
135
|
assert_respond_to(@service_info, :error_control)
|
135
136
|
assert(@error_controls.include?(@service_info.error_control))
|
136
137
|
end
|
137
138
|
|
138
|
-
|
139
|
+
test "load_order_group basic functionality" do
|
139
140
|
assert_respond_to(@service_info, :load_order_group)
|
140
141
|
assert_kind_of(String, @service_info.load_order_group)
|
141
142
|
end
|
142
143
|
|
143
|
-
|
144
|
+
test "tag_id basic functionality" do
|
144
145
|
assert_respond_to(@service_info, :tag_id)
|
145
146
|
assert_kind_of(Fixnum, @service_info.tag_id)
|
146
147
|
end
|
147
148
|
|
148
|
-
|
149
|
+
test "start_name basic functionality" do
|
149
150
|
assert_respond_to(@service_info, :start_name)
|
150
151
|
assert_kind_of(String, @service_info.start_name)
|
151
152
|
end
|
152
153
|
|
153
|
-
|
154
|
+
test "dependencies basic functionality" do
|
154
155
|
assert_respond_to(@service_info, :dependencies)
|
155
156
|
assert_kind_of(Array, @service_info.dependencies)
|
156
157
|
end
|
157
158
|
|
158
|
-
|
159
|
+
test "description basic functionality" do
|
159
160
|
assert_respond_to(@service_info, :description)
|
160
161
|
assert_kind_of(String, @service_info.description)
|
161
162
|
end
|
162
163
|
|
163
|
-
|
164
|
+
test "interactive basic functionality" do
|
164
165
|
assert_respond_to(@service_info, :interactive)
|
165
166
|
assert_boolean(@service_info.interactive)
|
166
167
|
end
|
167
168
|
|
168
|
-
|
169
|
+
test "service_flags basic functionality" do
|
169
170
|
assert_respond_to(@service_info, :service_flags)
|
170
171
|
assert([0,1].include?(@service_info.service_flags))
|
171
172
|
end
|
172
173
|
|
173
|
-
|
174
|
+
test "delayed_start basic functionality" do
|
174
175
|
assert_respond_to(@service_info, :delayed_start)
|
175
176
|
assert([0,1].include?(@service_info.delayed_start))
|
176
177
|
end
|
data/win32-service.gemspec
CHANGED
@@ -2,13 +2,14 @@ require 'rubygems'
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |spec|
|
4
4
|
spec.name = 'win32-service'
|
5
|
-
spec.version = '0.8.
|
5
|
+
spec.version = '0.8.8'
|
6
6
|
spec.authors = ['Daniel J. Berger', 'Park Heesob']
|
7
7
|
spec.license = 'Artistic 2.0'
|
8
8
|
spec.email = 'djberg96@gmail.com'
|
9
9
|
spec.homepage = 'http://github.com/djberg96/win32-service'
|
10
10
|
spec.summary = 'An interface for MS Windows services'
|
11
11
|
spec.test_files = Dir['test/test*.rb']
|
12
|
+
spec.cert_chain = Dir['certs/*']
|
12
13
|
|
13
14
|
spec.files = Dir['**/*'].reject{ |f| f.include?('git') }
|
14
15
|
|
@@ -23,6 +24,7 @@ Gem::Specification.new do |spec|
|
|
23
24
|
spec.add_dependency('ffi')
|
24
25
|
spec.add_development_dependency('test-unit')
|
25
26
|
spec.add_development_dependency('rake')
|
27
|
+
spec.add_development_dependency('win32-security')
|
26
28
|
|
27
29
|
spec.description = <<-EOF
|
28
30
|
The win32-service library provides a Ruby interface to services on
|
metadata
CHANGED
@@ -1,15 +1,37 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: win32-service
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel J. Berger
|
8
8
|
- Park Heesob
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
|
-
cert_chain:
|
12
|
-
|
11
|
+
cert_chain:
|
12
|
+
- |
|
13
|
+
-----BEGIN CERTIFICATE-----
|
14
|
+
MIIDcDCCAligAwIBAgIBATANBgkqhkiG9w0BAQUFADA/MREwDwYDVQQDDAhkamJl
|
15
|
+
cmc5NjEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPyLGQBGRYDY29t
|
16
|
+
MB4XDTE1MDkwMjIwNDkxOFoXDTE2MDkwMTIwNDkxOFowPzERMA8GA1UEAwwIZGpi
|
17
|
+
ZXJnOTYxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixkARkWA2Nv
|
18
|
+
bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMyTkvXqRp6hLs9eoJOS
|
19
|
+
Hmi8kRYbq9Vkf15/hMxJpotYMgJVHHWrmDcC5Dye2PbnXjTkKf266Zw0PtT9h+lI
|
20
|
+
S3ts9HO+vaCFSMwFFZmnWJSpQ3CNw2RcHxjWkk9yF7imEM8Kz9ojhiDXzBetdV6M
|
21
|
+
gr0lV/alUr7TNVBDngbXEfTWscyXh1qd7xZ4EcOdsDktCe5G45N/o3662tPQvJsi
|
22
|
+
FOF0CM/KuBsa/HL1/eoEmF4B3EKIRfTHrQ3hu20Kv3RJ88QM4ec2+0dd97uX693O
|
23
|
+
zv6981fyEg+aXLkxrkViM/tz2qR2ZE0jPhHTREPYeMEgptRkTmWSKAuLVWrJEfgl
|
24
|
+
DtkCAwEAAaN3MHUwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFEwe
|
25
|
+
nn6bfJADmuIDiMSOzedOrL+xMB0GA1UdEQQWMBSBEmRqYmVyZzk2QGdtYWlsLmNv
|
26
|
+
bTAdBgNVHRIEFjAUgRJkamJlcmc5NkBnbWFpbC5jb20wDQYJKoZIhvcNAQEFBQAD
|
27
|
+
ggEBAHmNOCWoDVD75zHFueY0viwGDVP1BNGFC+yXcb7u2GlK+nEMCORqzURbYPf7
|
28
|
+
tL+/hzmePIRz7i30UM//64GI1NLv9jl7nIwjhPpXpf7/lu2I9hOTsvwSumb5UiKC
|
29
|
+
/sqBxI3sfj9pr79Wpv4MuikX1XPik7Ncb7NPsJPw06Lvyc3Hkg5X2XpPtLtS+Gr2
|
30
|
+
wKJnmzb5rIPS1cmsqv0M9LPWflzfwoZ/SpnmhagP+g05p8bRNKjZSA2iImM/GyYZ
|
31
|
+
EJYzxdPOrx2n6NYR3Hk+vHP0U7UBSveI6+qx+ndQYaeyCn+GRX2PKS9h66YF/Q1V
|
32
|
+
tGSHgAmcLlkdGgan182qsE/4kKM=
|
33
|
+
-----END CERTIFICATE-----
|
34
|
+
date: 2016-06-25 00:00:00.000000000 Z
|
13
35
|
dependencies:
|
14
36
|
- !ruby/object:Gem::Dependency
|
15
37
|
name: ffi
|
@@ -53,6 +75,20 @@ dependencies:
|
|
53
75
|
- - ">="
|
54
76
|
- !ruby/object:Gem::Version
|
55
77
|
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: win32-security
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
type: :development
|
86
|
+
prerelease: false
|
87
|
+
version_requirements: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
56
92
|
description: |2
|
57
93
|
The win32-service library provides a Ruby interface to services on
|
58
94
|
MS Windows. You can create new services, or control, configure and
|
@@ -70,21 +106,32 @@ extra_rdoc_files:
|
|
70
106
|
- doc/service.txt
|
71
107
|
- doc/daemon.txt
|
72
108
|
files:
|
109
|
+
- appveyor.yml
|
110
|
+
- certs
|
111
|
+
- certs/djberg96_pub.pem
|
73
112
|
- CHANGES
|
74
|
-
-
|
75
|
-
- README
|
76
|
-
- Rakefile
|
113
|
+
- doc
|
77
114
|
- doc/daemon.txt
|
78
115
|
- doc/service.txt
|
116
|
+
- examples
|
79
117
|
- examples/demo_daemon.rb
|
80
118
|
- examples/demo_daemon_ctl.rb
|
81
119
|
- examples/demo_services.rb
|
120
|
+
- lib
|
121
|
+
- lib/win32
|
82
122
|
- lib/win32/daemon.rb
|
83
123
|
- lib/win32/service.rb
|
124
|
+
- lib/win32/windows
|
84
125
|
- lib/win32/windows/constants.rb
|
85
126
|
- lib/win32/windows/functions.rb
|
86
127
|
- lib/win32/windows/helper.rb
|
87
128
|
- lib/win32/windows/structs.rb
|
129
|
+
- lib/win32-daemon.rb
|
130
|
+
- lib/win32-service.rb
|
131
|
+
- MANIFEST
|
132
|
+
- Rakefile
|
133
|
+
- README
|
134
|
+
- test
|
88
135
|
- test/test_win32_daemon.rb
|
89
136
|
- test/test_win32_service.rb
|
90
137
|
- test/test_win32_service_configure.rb
|
@@ -112,7 +159,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
112
159
|
version: '0'
|
113
160
|
requirements: []
|
114
161
|
rubyforge_project:
|
115
|
-
rubygems_version: 2.4
|
162
|
+
rubygems_version: 2.6.4
|
116
163
|
signing_key:
|
117
164
|
specification_version: 4
|
118
165
|
summary: An interface for MS Windows services
|
metadata.gz.sig
ADDED
Binary file
|