vmopt 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|