vmopt 0.0.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/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/bin/devcon +0 -0
- data/bin/vmdrive +97 -0
- data/bin/vmdvd +193 -0
- data/bin/vmnetwork +172 -0
- data/bin/vmnotepad +144 -0
- data/bin/vmopt +22 -0
- data/bin/vmpower +73 -0
- data/bin/vmserial +92 -0
- data/bin/vmsysres +58 -0
- data/lib/vmopt.rb +14 -0
- data/lib/vmopt/disk_operation.rb +188 -0
- data/lib/vmopt/dvd_operation.rb +120 -0
- data/lib/vmopt/ext/string_ext.rb +104 -0
- data/lib/vmopt/network.rb +128 -0
- data/lib/vmopt/notepad.rb +145 -0
- data/lib/vmopt/power_operation.rb +57 -0
- data/lib/vmopt/serialport_operation.rb +62 -0
- data/lib/vmopt/system_resource.rb +44 -0
- data/lib/vmopt/utils/ip.rb +287 -0
- data/lib/vmopt/utils/registry.rb +13 -0
- data/lib/vmopt/utils/wmi.rb +19 -0
- data/lib/vmopt/version.rb +3 -0
- data/lib/vmopt/windows/win_net.rb +295 -0
- data/lib/vmopt/windows/win_winutils.rb +200 -0
- data/vmopt.gemspec +37 -0
- metadata +170 -0
@@ -0,0 +1,19 @@
|
|
1
|
+
#encoding: utf-8
|
2
|
+
#功能:wmi模块,用于查询本地设备信息
|
3
|
+
module WMI
|
4
|
+
class << self
|
5
|
+
def connect(uri = wmi_resource_uri)
|
6
|
+
require 'win32ole'
|
7
|
+
WIN32OLE.codepage = WIN32OLE::CP_UTF8
|
8
|
+
WIN32OLE.connect(uri)
|
9
|
+
end
|
10
|
+
|
11
|
+
def wmi_resource_uri( host = '.' )
|
12
|
+
"winmgmts:{impersonationLevel=impersonate}!//#{host}/root/cimv2"
|
13
|
+
end
|
14
|
+
|
15
|
+
def execquery(query)
|
16
|
+
connect().execquery(query)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,295 @@
|
|
1
|
+
#encoding: utf-8
|
2
|
+
#功能:提供查询网卡详细信息的接口
|
3
|
+
#
|
4
|
+
$LOAD_PATH.unshift(File.join(__FILE__, '../..', '..'))
|
5
|
+
require "vmopt/utils/ip"
|
6
|
+
require "vmopt/utils/registry"
|
7
|
+
require "vmopt/utils/wmi"
|
8
|
+
|
9
|
+
module WinNetError
|
10
|
+
class NoInterfaceError < RuntimeError; end #没有给网络借口
|
11
|
+
class CMDexecFailedError < RuntimeError; end #命令执行出错
|
12
|
+
class NotFindFileError < RuntimeError; end #查不到对应文件
|
13
|
+
class NoSavePathError < RuntimeError;end #没有路径可保存
|
14
|
+
class InvalidParamError < RuntimeError;end #参数错误
|
15
|
+
end
|
16
|
+
|
17
|
+
class WinNet
|
18
|
+
# The WMI query used to return ip information
|
19
|
+
#
|
20
|
+
# @return [String]
|
21
|
+
#
|
22
|
+
# @api private
|
23
|
+
#WMI_IP_INFO_QUERY = 'SELECT Description, ServiceName, IPAddress, IPConnectionMetric, InterfaceIndex, Index, IPSubnet, MACAddress, MTU, SettingID FROM Win32_NetworkAdapterConfiguration WHERE IPConnectionMetric IS NOT NULL AND IPEnabled = TRUE'
|
24
|
+
WMI_IP_INFO_QUERY = 'SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPConnectionMetric IS NOT NULL AND IPEnabled = TRUE'
|
25
|
+
|
26
|
+
|
27
|
+
# Mapping fact names to WMI properties of the Win32_NetworkAdapterConfiguration
|
28
|
+
#
|
29
|
+
# @api private
|
30
|
+
WINDOWS_LABEL_WMI_MAP = {
|
31
|
+
:ipaddress => 'IPAddress',
|
32
|
+
:ipaddress6 => 'IPAddress',
|
33
|
+
:macaddress => 'MACAddress',
|
34
|
+
:netmask => 'IPSubnet'
|
35
|
+
}
|
36
|
+
|
37
|
+
#net connect status map
|
38
|
+
WINDOWS_CON_STATUS_MAP = {
|
39
|
+
0 => "Disconnected",
|
40
|
+
1 => "Connecting",
|
41
|
+
2 => "Connected",
|
42
|
+
3 => "Disconnecting",
|
43
|
+
4 => "Hardware not present",
|
44
|
+
5 => "Hardware disabled",
|
45
|
+
6 => "Hardware malfunction",
|
46
|
+
7 => "Media disconnected",
|
47
|
+
8 => "Authenticating",
|
48
|
+
9 => "Authentication succeeded",
|
49
|
+
10 => "Authentication failed",
|
50
|
+
11 => "Invalid address",
|
51
|
+
12 => "Credentials required"
|
52
|
+
}
|
53
|
+
|
54
|
+
def self.to_s
|
55
|
+
'windows'
|
56
|
+
end
|
57
|
+
|
58
|
+
# Windows doesn't display netmask in hex.
|
59
|
+
#
|
60
|
+
# @return [Boolean] false by default
|
61
|
+
#
|
62
|
+
# @api private
|
63
|
+
def self.convert_netmask_from_hex?
|
64
|
+
false
|
65
|
+
end
|
66
|
+
|
67
|
+
# Retrieves a list of unique interfaces names.
|
68
|
+
#
|
69
|
+
# @return [Array<String>]
|
70
|
+
#
|
71
|
+
# @api private
|
72
|
+
def self.interfaces
|
73
|
+
interface_names = []
|
74
|
+
|
75
|
+
WMI.execquery("SELECT * FROM Win32_NetworkAdapter").each do |nic|
|
76
|
+
interface_names << nic.NetConnectionId unless nic.NetConnectionId.nil? or nic.NetConnectionId.empty?
|
77
|
+
end
|
78
|
+
|
79
|
+
interface_names.uniq
|
80
|
+
end
|
81
|
+
|
82
|
+
# Retrieves netadapter
|
83
|
+
#
|
84
|
+
# @return [Array<win32ole>]
|
85
|
+
#
|
86
|
+
# @api private
|
87
|
+
def self.network_adapter
|
88
|
+
nics = []
|
89
|
+
WMI.execquery("SELECT * FROM Win32_NetworkAdapter WHERE NetConnectionID IS NOT NULL" ).each do |nic|
|
90
|
+
nics << nic
|
91
|
+
end
|
92
|
+
nics
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.netconnstatus
|
97
|
+
stat={}
|
98
|
+
network_adapter.each do |interface|
|
99
|
+
stat[interface.netConnectionId] = WINDOWS_CON_STATUS_MAP[interface.netConnectionStatus]
|
100
|
+
end
|
101
|
+
stat
|
102
|
+
end
|
103
|
+
|
104
|
+
# Get the value of an interface and label. For example, you may want to find
|
105
|
+
# the MTU for eth0.
|
106
|
+
#
|
107
|
+
# @param [String] interface the name of the interface returned by the {#interfaces} method.
|
108
|
+
# @param [String] label the type of value to return, e.g. ipaddress
|
109
|
+
# @return [String] the value, or nil if not defined
|
110
|
+
#
|
111
|
+
# @api private
|
112
|
+
def self.value_for_interface_and_label(interface, label)
|
113
|
+
wmi_value = WINDOWS_LABEL_WMI_MAP[label.downcase.to_sym]
|
114
|
+
label_value = nil
|
115
|
+
WMI.execquery("SELECT Index FROM Win32_NetworkAdapter WHERE NetConnectionID = '#{interface}'").each do |nic|
|
116
|
+
WMI.execquery("SELECT #{wmi_value} FROM Win32_NetworkAdapterConfiguration WHERE Index = #{nic.Index}").each do |nic_config|
|
117
|
+
case label.downcase.to_sym
|
118
|
+
when :ipaddress
|
119
|
+
nic_config.IPAddress.any? do |addr|
|
120
|
+
label_value = addr if valid_ipv4_address?(addr)
|
121
|
+
label_value
|
122
|
+
end
|
123
|
+
when :ipaddress6
|
124
|
+
nic_config.IPAddress.any? do |addr|
|
125
|
+
label_value = addr if IP::Windows.valid_ipv6_address?(addr)
|
126
|
+
label_value
|
127
|
+
end
|
128
|
+
when :netmask
|
129
|
+
nic_config.IPSubnet.any? do |addr|
|
130
|
+
label_value = addr if IP::Windows.valid_ipv4_address?(addr)
|
131
|
+
label_value
|
132
|
+
end
|
133
|
+
when :macaddress
|
134
|
+
label_value = nic_config.MACAddress
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
label_value
|
140
|
+
end
|
141
|
+
|
142
|
+
# Returns an array of partial Win32_NetworkAdapterConfiguration objects.
|
143
|
+
#
|
144
|
+
# @return [Array<WIN32OLE>] objects
|
145
|
+
#
|
146
|
+
# @api private
|
147
|
+
def self.network_adapter_configurations
|
148
|
+
nics = []
|
149
|
+
# WIN32OLE doesn't implement Enumerable
|
150
|
+
WMI.execquery(WMI_IP_INFO_QUERY).each do |nic|
|
151
|
+
nics << nic
|
152
|
+
end
|
153
|
+
nics
|
154
|
+
end
|
155
|
+
|
156
|
+
# Gets a list of active IPv4 network adapter configurations sorted by the
|
157
|
+
# lowest IP connection metric. If two configurations have the same metric,
|
158
|
+
# then the IPv4 specific binding order as specified in the registry will
|
159
|
+
# be used.
|
160
|
+
#
|
161
|
+
# @return [Array<WIN32OLE>]
|
162
|
+
#
|
163
|
+
# @api private
|
164
|
+
def self.get_preferred_ipv4_adapters
|
165
|
+
get_preferred_network_adapters(Bindings4.new)
|
166
|
+
end
|
167
|
+
|
168
|
+
# Gets a list of active IPv6 network adapter configurations sorted by the
|
169
|
+
# lowest IP connection metric. If two configurations have the same metric,
|
170
|
+
# then the IPv6 specific binding order as specified in the registry will
|
171
|
+
# be used.
|
172
|
+
#
|
173
|
+
# @return [Array<WIN32OLE>]
|
174
|
+
#
|
175
|
+
# @api private
|
176
|
+
def self.get_preferred_ipv6_adapters
|
177
|
+
get_preferred_network_adapters(Bindings6.new)
|
178
|
+
end
|
179
|
+
|
180
|
+
# Gets a list of active network adapter configurations sorted by the lowest
|
181
|
+
# IP connection metric. If two configurations have the same metric, then
|
182
|
+
# the adapter binding order as specified in the registry will be used.
|
183
|
+
# Note the order may different for IPv4 vs IPv6 addresses.
|
184
|
+
#
|
185
|
+
# @see http://support.microsoft.com/kb/894564
|
186
|
+
# @return [Array<WIN32OLE>]
|
187
|
+
#
|
188
|
+
# @api private
|
189
|
+
def self.get_preferred_network_adapters(bindings)
|
190
|
+
network_adapter_configurations.select do |nic|
|
191
|
+
bindings.bindings.include?(nic.SettingID)
|
192
|
+
end.sort do |nic_left,nic_right|
|
193
|
+
cmp = nic_left.IPConnectionMetric <=> nic_right.IPConnectionMetric
|
194
|
+
if cmp == 0
|
195
|
+
bindings.bindings[nic_left.SettingID] <=> bindings.bindings[nic_right.SettingID]
|
196
|
+
else
|
197
|
+
cmp
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
class Bindings4
|
203
|
+
def initialize
|
204
|
+
@key = 'SYSTEM\CurrentControlSet\Services\Tcpip\Linkage'
|
205
|
+
end
|
206
|
+
|
207
|
+
def bindings
|
208
|
+
require 'vmopt/utils/registry'
|
209
|
+
bindings = {}
|
210
|
+
|
211
|
+
Registry.hklm_read(@key, 'Bind').each_with_index do |entry, index|
|
212
|
+
match_data = entry.match(/\\Device\\(\{.*\})/)
|
213
|
+
unless match_data.nil?
|
214
|
+
bindings[match_data[1]] = index
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
bindings
|
219
|
+
rescue
|
220
|
+
{}
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
class Bindings6 < Bindings4
|
225
|
+
def initialize
|
226
|
+
@key = 'SYSTEM\CurrentControlSet\Services\Tcpip6\Linkage'
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
# Determines if the value passed in is a valid ipv4 address.
|
231
|
+
#
|
232
|
+
# @param [String] ip_address the IPv4 address to validate
|
233
|
+
# @return [Boolean]
|
234
|
+
#
|
235
|
+
# @api private
|
236
|
+
def self.valid_ipv4_address?(ip_address)
|
237
|
+
String(ip_address).scan(/(?:[0-9]{1,3}\.){3}[0-9]{1,3}/).each do |match|
|
238
|
+
# excluding 169.254.x.x in Windows - this is the DHCP APIPA
|
239
|
+
# meaning that if the node cannot get an ip address from the dhcp server,
|
240
|
+
# it auto-assigns a private ip address
|
241
|
+
unless match == "127.0.0.1" or match =~ /^169.254.*/
|
242
|
+
return !!match
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
false
|
247
|
+
end
|
248
|
+
|
249
|
+
# Determines if the value passed in is a valid ipv6 address.
|
250
|
+
#
|
251
|
+
# @param [String] ip_address the IPv6 address to validate
|
252
|
+
# @return [Boolean]
|
253
|
+
#
|
254
|
+
# @api private
|
255
|
+
def self.valid_ipv6_address?(ip_address)
|
256
|
+
String(ip_address).scan(/(?>[0-9,a-f,A-F]*\:{1,2})+[0-9,a-f,A-F]{0,4}/).each do |match|
|
257
|
+
unless match =~ /fe80.*/ or match == "::1"
|
258
|
+
return !!match
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
false
|
263
|
+
end
|
264
|
+
|
265
|
+
end
|
266
|
+
|
267
|
+
|
268
|
+
if __FILE__ == $0
|
269
|
+
|
270
|
+
#查询网络接口名称
|
271
|
+
WinNet.interfaces.each{|i| puts i}
|
272
|
+
|
273
|
+
#查询网络接口mac地址
|
274
|
+
WinNet.interfaces.each do |inf|
|
275
|
+
puts WinNet.value_for_interface_and_label(inf, :macaddress)
|
276
|
+
end
|
277
|
+
|
278
|
+
#查询网络接口的属性,分别是描述,服务名,设置id
|
279
|
+
WinNet.network_adapter_configurations.each{|interface| puts interface.description}
|
280
|
+
WinNet.network_adapter_configurations.each{|interface| puts interface.serviceName}
|
281
|
+
WinNet.network_adapter_configurations.each{|interface| puts interface.settingID}
|
282
|
+
|
283
|
+
#查询网卡的连接状态
|
284
|
+
WinNet.interfaces.each do|i|
|
285
|
+
puts "#{i}: "+WinNet.netconnstatus[i]
|
286
|
+
end
|
287
|
+
|
288
|
+
#打印设备的PNPDeviceID,可用来提交给devcon.exe工具
|
289
|
+
WinNet.network_adapter.each{|interface| puts "#{interface.NetConnectionId} : " + "#{interface.pNPDeviceID}"}
|
290
|
+
|
291
|
+
end
|
292
|
+
|
293
|
+
|
294
|
+
|
295
|
+
|
@@ -0,0 +1,200 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#功能:提供windows窗口的基本操作
|
3
|
+
|
4
|
+
=begin rdoc
|
5
|
+
类名: 通用操作类
|
6
|
+
描述: 封装系统操作调用相关的内容
|
7
|
+
=end
|
8
|
+
require "win32ole"
|
9
|
+
WIN32OLE.codepage = WIN32OLE::CP_UTF8
|
10
|
+
require "Win32API"
|
11
|
+
require "rautomation"
|
12
|
+
require "vmopt/ext/string_ext"
|
13
|
+
|
14
|
+
module WinUtils
|
15
|
+
|
16
|
+
class KillProcessFailError < RuntimeError; end #杀死进程失败的错误
|
17
|
+
class EmptyFileFailError < RuntimeError; end #清除目录错误
|
18
|
+
class NotFindZipError < RuntimeError; end #查不到对应的ZIP文件
|
19
|
+
class NotFindFileError < RuntimeError; end #查不到对应文件
|
20
|
+
class NotSuitableStringError < RuntimeError; end #未按要求的的字符串
|
21
|
+
class NotFindWindowError < RuntimeError; end #查找不到窗口
|
22
|
+
class ActivateFailError < RuntimeError; end #激活窗口失败
|
23
|
+
class WaitConnectTimeoutError < RuntimeError; end #TCP连接失败异常
|
24
|
+
class NoSavePathError < RuntimeError;end #没有路径可保存
|
25
|
+
|
26
|
+
=begin rdoc
|
27
|
+
参数:无
|
28
|
+
作用:检测到除了为简体中文时为中文系统,其余都判断为英文系统.
|
29
|
+
返回值:返回国家域名缩写的小写形式
|
30
|
+
=end
|
31
|
+
def self.os_type
|
32
|
+
WIN32OLE.connect('winmgmts:\\\.').ExecQuery("select * from Win32_OperatingSystem").each do |m|
|
33
|
+
return "cn" if m.OSLanguage == 4 || m.OSLanguage == 2052
|
34
|
+
end
|
35
|
+
"en"
|
36
|
+
end
|
37
|
+
|
38
|
+
=begin rdoc
|
39
|
+
参数:titlename:查找的标题名称,activate_flag = false
|
40
|
+
作用:查找是否有给定标题名称的惟一对象,activate_flag表示是否能够激活窗口。
|
41
|
+
返回值:找到惟一对象则返回true;找不到或找到为非惟一的则返回false
|
42
|
+
=end
|
43
|
+
def self.find_single_active_window?(titlename,activate_flag = false)
|
44
|
+
find_res=0
|
45
|
+
all_rautowindow = RAutomation::Window.windows
|
46
|
+
all_rautowindow.each do |win|
|
47
|
+
find_res+=1 if (win.exists? && win.title !=nil && (win.title.include?(titlename) rescue false))
|
48
|
+
end
|
49
|
+
return false if find_res.to_s != "1" #找到了有多个标题框的内容,直接返回fasle
|
50
|
+
rautowindow = RAutomation::Window.new(:title=>titlename,:adapter=>"Autoit")
|
51
|
+
if activate_flag
|
52
|
+
return false unless rautowindow.exists? #不存在为假;
|
53
|
+
rautowindow.WinActivate(rautowindow.title) unless rautowindow.WinActive(rautowindow.title)
|
54
|
+
return true if res_status.to_s == "15"
|
55
|
+
return false
|
56
|
+
else
|
57
|
+
rautowindow.exists?
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
=begin rdoc
|
62
|
+
参数:要搜索的标题名称和激活窗口标志,激活窗口标志默认为true
|
63
|
+
作用:查找是否有查找到给定的标题名称的对话框,如果有则返回RAutomation对
|
64
|
+
象,否则返回nil
|
65
|
+
返回值:成功找到返回RAutomation的Windows对象
|
66
|
+
=end
|
67
|
+
def self.find_window(titlename,flag = true)
|
68
|
+
retrytime=0
|
69
|
+
begin
|
70
|
+
rautowindow = RAutomation::Window.new(:title=>titlename,:adapter=>"Autoit")
|
71
|
+
retrytime+=1
|
72
|
+
sleep 1
|
73
|
+
end while !rautowindow.exists? and retrytime <= 10
|
74
|
+
raise ::WinUtils::NotFindWindowError,"Not found the windows like #{titlename}." if !rautowindow.exists?
|
75
|
+
if flag
|
76
|
+
res = rautowindow.WinActivate(rautowindow.title) unless rautowindow.WinActive(rautowindow.title)
|
77
|
+
raise ::WinUtils::ActivateFailError,"Cant't Activate the Window #{rautowindow.title}" if res.to_s == "0"
|
78
|
+
end
|
79
|
+
rautowindow
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
|
84
|
+
=begin rdoc
|
85
|
+
参数:根据窗口的text来定位title
|
86
|
+
作用:查找是否有查找到给定的窗口的text的对话框,如果有则返回RAutomation对
|
87
|
+
象,否则的返回false
|
88
|
+
返回值:成功找到返回RAutomation的Windows对象
|
89
|
+
=end
|
90
|
+
def self.find_window_by_text(textname)
|
91
|
+
rautowindows = RAutomation::Window.windows
|
92
|
+
rautowindows.map do |win|
|
93
|
+
return win if win.text.include?(textname)
|
94
|
+
end
|
95
|
+
nil
|
96
|
+
end
|
97
|
+
|
98
|
+
=begin rdoc
|
99
|
+
参数:process_name:进程名;reserve_process_path:期望路径
|
100
|
+
作用:杀掉给定名称的进程,reserve_process_path有值则保留这个环境下的进程
|
101
|
+
返回值:若异常则抛出异常,否则返回真
|
102
|
+
=end
|
103
|
+
def self.kill_process(process_name,reserve_process_path=nil)
|
104
|
+
raise ArgumentError,"the argument can't be nil." if process_name.nil?
|
105
|
+
begin
|
106
|
+
gbk_reserve_process_path = reserve_process_path.to_gbk unless reserve_process_path.nil?
|
107
|
+
WIN32OLE.connect('winmgmts:\\\.').ExecQuery("SELECT * FROM Win32_Process").each do |item|
|
108
|
+
if item.Caption == process_name.to_gbk
|
109
|
+
if gbk_reserve_process_path == nil
|
110
|
+
item.Terminate
|
111
|
+
next
|
112
|
+
end
|
113
|
+
next if item.ExecutablePath != nil && item.ExecutablePath.gsub("\\","/").downcase == gbk_reserve_process_path.gsub("\\","/").downcase
|
114
|
+
item.Terminate
|
115
|
+
end
|
116
|
+
end
|
117
|
+
return true
|
118
|
+
rescue =>err
|
119
|
+
raise ::WinUtils::KillProcessFailError,"Kill process: #{process_name.to_utf8} failed!err_msg:#{err}"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
=begin rdoc
|
124
|
+
参数:process_name:进程名
|
125
|
+
作用:查找给定名称的进程,
|
126
|
+
返回值:查看是否有找到给定文件名的进程,若有则返回真,若无则返回假
|
127
|
+
=end
|
128
|
+
def self.find_process?(process_name)
|
129
|
+
raise ArgumentError,"the argument can't be nil." if process_name.nil?
|
130
|
+
gbk_process_name = process_name.to_gbk
|
131
|
+
WIN32OLE.connect('winmgmts:\\\.').ExecQuery("SELECT * FROM Win32_Process").each do |item|
|
132
|
+
return true if item.Caption.downcase == gbk_process_name.downcase
|
133
|
+
end
|
134
|
+
false
|
135
|
+
end
|
136
|
+
|
137
|
+
=begin rdoc
|
138
|
+
参数:准备被清空的目录dir或文件
|
139
|
+
作用:清空目录下的所有文件;但保留dir目录,若dir为文件就会删除
|
140
|
+
返回值:若异常则抛出异常,否则返回真
|
141
|
+
=end
|
142
|
+
def self.empty_dir(dir)
|
143
|
+
raise ArgumentError,"the argument can't be nil." if dir.nil?
|
144
|
+
begin
|
145
|
+
gbk_dest_dir = dir.to_gbk
|
146
|
+
Find.find(gbk_dest_dir) do |file|
|
147
|
+
next if ! File.exist?(file)
|
148
|
+
#next if File.directory?(file) && (file.downcase == gbk_dest_dir.downcase)
|
149
|
+
if File.directory?(file)
|
150
|
+
FileWinUtils.rm_rf(file)
|
151
|
+
else
|
152
|
+
File.delete(file)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
return true
|
156
|
+
rescue =>err
|
157
|
+
raise ::WinUtils::EmptyFileFailError,"empty_dir #{dir.to_utf8} failed!err_msg:#{err}."
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
=begin rdoc
|
162
|
+
参数:给定的目录,需要查找的文件名
|
163
|
+
作用:在给定的目录中查找给定的文件,若查找到时返回这个文件的目路径,否则返回空
|
164
|
+
返回值:返回文件所在路径或为空
|
165
|
+
=end
|
166
|
+
def self.get_filepath(dest_dir,filename)
|
167
|
+
raise ArgumentError,"the argument can't be nil." if dest_dir.nil? || filename.nil?
|
168
|
+
gbk_dest_dir = dest_dir.to_gbk
|
169
|
+
gbk_filename = filename.to_gbk
|
170
|
+
Find.find(gbk_dest_dir) do |filepath|
|
171
|
+
filepath_arr = filepath.split("/")
|
172
|
+
return (Pathname.new(File.expand_path(filepath)).realpath).to_s.gsub("/","\\\\") if (filepath_arr[-1].downcase == gbk_filename.downcase && !File.directory?(filepath) )
|
173
|
+
end
|
174
|
+
raise ::WinUtils::NotFindFileError,"Not find named :#{filename.to_utf8} file in the dir:#{dest_dir.to_utf8}."
|
175
|
+
end
|
176
|
+
=begin rdoc
|
177
|
+
参数:两个字符串str1,str2
|
178
|
+
作用:去除str1中头部有str2的部分,需要完整匹配
|
179
|
+
返回值:被去除后的字符串
|
180
|
+
=end
|
181
|
+
def self.remove_head_str(str1,str2)
|
182
|
+
str1_size = str1.size
|
183
|
+
str2_size = str2.size
|
184
|
+
raise ::WinUtils::NotSuitableStringError,"the length of str1 need > str2's size." if str1_size<str2_size
|
185
|
+
return "" if str1 == str2
|
186
|
+
i = 1
|
187
|
+
str2_arr_size = str2.split("\n").size
|
188
|
+
result_str=""
|
189
|
+
str1.each_line do |line|
|
190
|
+
if i<=str2_arr_size
|
191
|
+
raise ::WinUtils::NotSuitableStringError,"The relation of str1:#{str1.dump} and str2:#{str2.dump} is not suitable." unless str2.include?(line)
|
192
|
+
i = i+1
|
193
|
+
next
|
194
|
+
end
|
195
|
+
result_str<<line
|
196
|
+
end
|
197
|
+
result_str.strip
|
198
|
+
end
|
199
|
+
|
200
|
+
end #end of WinUtils.
|