Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
AD-Control-Golang
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
陶腾飞
AD-Control-Golang
Commits
b764cc38
Commit
b764cc38
authored
Jul 06, 2022
by
陶腾飞
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
2022/06/29 v2.5.8
parent
3d237ca9
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
240 additions
and
51 deletions
+240
-51
README.MD
+1
-0
adct/adct.go
+0
-1
public/cmdbjson.go
+2
-0
public/dept.go
+5
-2
public/env.go
+17
-10
public/log.go
+1
-1
public/msg_deal.go
+37
-25
public/msg_init.go
+8
-0
public/network.go
+52
-0
public/user.go
+1
-0
public/win.go
+36
-0
registry/registry.go
+7
-0
users/menu.go
+73
-12
No files found.
README.MD
View file @
b764cc38
...
...
@@ -104,6 +104,7 @@
-
2022/04/29 v2.5.5 ci工具 自我升级
-
2022/05/26 v2.5.6 更新主要计算机功能bug修复
-
2022/06/14 v2.5.7 更新日志输出、删除情报一二三部
-
2022/06/29 v2.5.8 增加抖音组,解决walk的反射问题,优化软件安装的下载速度
## 四、其他说明
...
...
adct/adct.go
View file @
b764cc38
...
...
@@ -104,7 +104,6 @@ func flag_report(s string) {
cir
.
Mac
=
pub
.
GetMacaddressFromIP
(
cir
.
Ip
)
cir
.
Start_time
=
pub
.
GetNowTimeString
()
cir
.
PC_update_time
=
pub
.
GetNowTimeString
()
cir
.
PC_update_time
=
pub
.
GetNowTimeString
()
cir
.
Position
=
pub
.
GetCMDBPosition
(
hostnameSplit
[
0
],
hostnameSplit
[
1
])
d
,
err
=
json
.
Marshal
(
cir
)
if
err
!=
nil
{
...
...
public/cmdbjson.go
View file @
b764cc38
...
...
@@ -206,6 +206,8 @@ func (cir *CIRecordStartup) GetDept() (string, error) {
result
=
Dept_zw_qbmb_jd_string
+
Dept_zw_qbbm_unit
case
"HW"
:
result
=
Dept_zw_qbmb_hw_string
+
Dept_zw_qbbm_unit
case
"DY"
:
result
=
Dept_zw_qbmb_dy_string
+
Dept_zw_qbbm_unit
case
"BGYJ"
:
result
=
Dept_zw_qbmb_bgyj_string
+
Dept_zw_qbbm_unit
default
:
...
...
public/dept.go
View file @
b764cc38
...
...
@@ -9,7 +9,7 @@ const Region_zz = "郑州"
const
Dept_zw_unit
=
"部"
const
Dept_zw_qbbm_unit
=
"组"
const
Dept_zw_chanpin
=
"产品"
const
Dept_zw_chan
g
pin
=
"产品"
const
Dept_zw_renshi
=
"人事"
const
Dept_zw_peixun
=
"培训"
const
Dept_zw_chaiwu
=
"财务"
...
...
@@ -27,10 +27,11 @@ const Dept_zw_qbmb_txwj_string = "腾讯危机"
const
Dept_zw_qbmb_js_string
=
"技术"
const
Dept_zw_qbmb_jd_string
=
"京东"
const
Dept_zw_qbmb_hw_string
=
"华为"
const
Dept_zw_qbmb_dy_string
=
"抖音"
const
Dept_zw_qbmb_bgyj_string
=
"报告研究中心"
var
Dept_zw_region_array
=
[]
string
{
Region_nb
,
Region_zz
}
var
Dept_zw_noqbmm_array
=
[]
string
{
Dept_zw_chanpin
,
Dept_zw_renshi
,
Dept_zw_peixun
,
Dept_zw_chaiwu
,
Dept_zw_jishu
}
var
Dept_zw_noqbmm_array
=
[]
string
{
Dept_zw_chan
g
pin
,
Dept_zw_renshi
,
Dept_zw_peixun
,
Dept_zw_chaiwu
,
Dept_zw_jishu
}
func
GetPostationFromHostname
(
hostname
string
)
(
string
,
error
)
{
switch
hostname
{
...
...
@@ -68,6 +69,8 @@ func GetPostationFromHostname(hostname string) (string, error) {
return
Cmdb_Position_7
,
nil
case
HOST_Dept_JD
:
return
Cmdb_Position_7
,
nil
case
HOST_Dept_DY
:
return
Cmdb_Position_7
,
nil
default
:
return
""
,
fmt
.
Errorf
(
"%s is error format"
,
hostname
)
}
...
...
public/env.go
View file @
b764cc38
...
...
@@ -8,24 +8,27 @@ var OS_Type = getOSType()
var
Active
bool
=
true
const
SymbolHostname
=
"-"
const
SymbolSplit
=
","
// AD-Control //
const
Version
string
=
"2.5.7"
const
Host_adserver
string
=
"ADSERVER"
const
Host_adserver_lan
string
=
"192.168.0.20"
const
Host_adserver_wan
string
=
"115.231.214.234"
const
Host_adserver
string
=
"ADSERVER"
const
Host_thserver
string
=
"THSERVER"
const
Host_zzserver
string
=
"ZZSERVER"
const
DaemonListen
string
=
":16823"
const
DaemonLogListen
string
=
":16824"
var
ADServerDaemon
string
=
Host_adserver
+
DaemonListen
var
ADServerLogDaemon
string
=
Host_adserver
+
DaemonLogListen
var
THServerDaemon
string
=
Host_thserver
+
DaemonListen
var
THServerLogDaemon
string
=
Host_thserver
+
DaemonLogListen
var
ZZServerDaemon
string
=
Host_zzserver
+
DaemonListen
var
ZZServerLogDaemon
string
=
Host_zzserver
+
DaemonLogListen
const
ADServerDaemon
string
=
Host_adserver
+
DaemonListen
const
ADServerLogDaemon
string
=
Host_adserver
+
DaemonLogListen
const
THServerDaemon
string
=
Host_thserver
+
DaemonListen
const
THServerLogDaemon
string
=
Host_thserver
+
DaemonLogListen
const
ZZServerDaemon
string
=
Host_zzserver
+
DaemonListen
const
ZZServerLogDaemon
string
=
Host_zzserver
+
DaemonLogListen
var
Host_server_download
=
Host_adserver_lan
+
DaemonListen
// users //
...
...
@@ -52,11 +55,10 @@ const SMB_ADSoftPlus string = SMB_ADSoft + `plus\`
// Local Folder //
var
Dir_userprofile
string
=
GetEnv
(
"USERPROFILE"
)
var
Dir_tmp
string
=
GetEnv
(
"tmp"
)
const
Dir_
ADsoftware_local
string
=
`H:\software\softlike\`
const
Dir_
ADControl_local
string
=
`H:\software\application\`
const
Dir_
softlike
string
=
`H:\software\softlike\`
const
Dir_
application
string
=
`H:\software\application\`
// application //
const
App_MultiSplit
string
=
SMB_ADSoftOthTool
+
"win_MultiSplit.exe"
...
...
@@ -79,6 +81,10 @@ const Cmd_c string = "cmd /c "
const
Cmd_k
string
=
"cmd /k "
const
Cmd_K_Start
string
=
"cmd /k start "
//
const
Msg_file
=
"file"
const
Msg_softlike
=
"softlike"
// wxwork key //
var
WxworkBotLink
string
...
...
@@ -95,6 +101,7 @@ const WxWorkInteraction_Dimission = "停用个人账号"
// log level //
var
Loglevel
string
=
INFO
var
MS
MsgSwitch
const
INFO
string
=
"info"
const
WARN
string
=
"warn"
...
...
public/log.go
View file @
b764cc38
...
...
@@ -62,7 +62,7 @@ func logDeal(level string, l *logs) {
return
}
}
func
LOG
(
level
string
,
msgtype
string
,
args
...
any
)
{
func
LOG
(
level
string
,
msgtype
string
,
args
...
interface
{}
)
{
if
(
Loglevel
!=
DEBUG
)
&&
(
level
==
DEBUG
)
{
return
}
...
...
public/msg_deal.go
View file @
b764cc38
...
...
@@ -31,17 +31,23 @@ func DealMsg(url []string, query string, unmsg []byte) ([]byte, error) {
var
ret
[]
byte
switch
msgtype
{
case
"file"
:
case
Msg_file
:
var
err
error
file
:=
url
[
2
]
ret
,
err
=
ioutil
.
ReadFile
(
Dir_
ADControl_local
+
file
)
ret
,
err
=
ioutil
.
ReadFile
(
Dir_
application
+
file
)
if
err
!=
nil
{
LOG
(
ERROR
,
NULL
,
err
)
return
nil
,
err
}
case
Msg_softlike
:
var
err
error
file
:=
url
[
2
]
ret
,
err
=
ioutil
.
ReadFile
(
Dir_softlike
+
file
)
if
err
!=
nil
{
LOG
(
ERROR
,
NULL
,
err
)
return
nil
,
err
}
// 报告 消息
case
Msg_Report
:
var
msg
MJreport
...
...
@@ -83,11 +89,8 @@ func DealMsg(url []string, query string, unmsg []byte) ([]byte, error) {
//
// 关于 report 报告 的 消息处理
func
(
rep
*
MJreport
)
MsgDeal
()
interface
{}
{
// 创建菜单调用工具:https://open.work.weixin.qq.com/wwopen/devtool/interface?doc_id=10786
// 创建菜单官方说明:https://work.weixin.qq.com/api/doc/90000/90135/90231
switch
rep
.
Instruction
{
case
Msg_Report_WillTurnOffPC
:
...
...
@@ -102,7 +105,7 @@ func (rep *MJreport) MsgDeal() interface{} {
if
err
!=
nil
{
LOG
(
ERROR
,
rep
.
Instruction
,
err
)
}
else
{
LOG
(
INFO
,
rep
.
Instruction
,
rep
.
Computername
)
LOG
(
INFO
,
rep
.
Instruction
,
rep
.
Computername
+
" 关机"
)
}
}
// 客户端
...
...
@@ -123,7 +126,7 @@ func (rep *MJreport) MsgDeal() interface{} {
break
}
}
LOG
(
INFO
,
rep
.
Instruction
,
rep
.
Computername
)
LOG
(
INFO
,
rep
.
Instruction
,
rep
.
Computername
+
" 开机"
)
// 客户端
case
Msg_status_deal
:
return
nil
...
...
@@ -179,8 +182,8 @@ func (rep *MJreport) MsgDeal() interface{} {
case
Msg_status_commit
:
LOG
(
INFO
,
rep
.
Instruction
,
rep
.
DataStr
)
SendWxworkTextToHR
(
rep
.
DataStr
)
//
SendWxworkTextToAdmins(rep.DataStr)
//
SendWxworkTextToHR(rep.DataStr)
SendWxworkTextToAdmins
(
rep
.
DataStr
)
case
Msg_status_deal
:
msg
:=
strings
.
Split
(
rep
.
DataStr
,
"
\n
"
)
...
...
@@ -240,8 +243,8 @@ func (rep *MJreport) MsgDeal() interface{} {
}
// 如果创建完成
rep
.
SendWXwork
(
name
+
"创建完成"
)
LOG
(
ERROR
,
rep
.
Instruction
,
name
+
"创建完成"
)
SendWxworkTextToAUser
(
rep
.
User
name
,
name
+
"创建完成"
)
LOG
(
INFO
,
rep
.
Instruction
,
name
+
"创建完成"
)
SendWxworkTextToAUser
(
name
,
name
+
"创建完成"
)
}
case
Msg_Report_Dimission
:
...
...
@@ -270,6 +273,18 @@ func (rep *MJreport) MsgDeal() interface{} {
"首次登录后需要重置密码,密码规则大小写+数字+至少8位,不包含用户名
\n
"
+
"个人账号支持通过“知微运维平台”远程唤醒主机!"
)
}
case
Msg_Report_GetSoftlike
:
switch
rep
.
Status
{
case
Msg_status_commit
:
f
,
err
:=
GetFolderInFileName
(
`H:\software\softlike\`
)
if
err
!=
nil
{
LOG
(
ERROR
,
rep
.
Instruction
,
err
)
}
rep
.
DataStr
=
strings
.
Join
(
f
,
SymbolSplit
)
LOG
(
INFO
,
rep
.
Instruction
,
fmt
.
Sprintf
(
"%s 获取 应用软件"
,
rep
.
Computername
))
case
Msg_status_deal
:
MS
.
S
=
rep
.
DataStr
}
default
:
LOG
(
ERROR
,
"Default Report Json"
,
rep
.
Instruction
)
...
...
@@ -288,7 +303,6 @@ func (rep *MJreport) MsgDeal() interface{} {
}
// 关于 exec 执行 的 消息处理
func
(
exec
*
MJexec
)
MsgDeal
()
interface
{}
{
// 状态变更
...
...
@@ -322,16 +336,15 @@ func (exec *MJexec) MsgDeal() interface{} {
exec
.
Status
=
Msg_Exec_State_Over
case
Msg_Exec_InstallSoftware
:
// 对于 msi 格式,从\\adserver目录使用msiexec安装
// 共享则需要everyone的读取权限
if
strings
.
HasSuffix
(
exec
.
Command
,
".msi"
)
{
full_cmd
:=
"msiexec /i "
+
SMB_ADSoftlike
+
`\`
+
exec
.
Command
+
" /qb"
PsExec_sdi
(
exec
.
Computername
,
full_cmd
,
exec
.
SessionID
)
// 对于 exe 格式,从 ADMIN$ 复制到C:\windows,再执行
}
else
{
PsExec_sfdic
(
exec
.
Computername
,
Dir_ADsoftware_local
+
exec
.
Command
,
exec
.
SessionID
)
LOG
(
INFO
,
exec
.
Instruction
,
exec
.
Command
)
// 对于 msi 格式,使用msiexec进行安装
if
strings
.
HasSuffix
(
exec
.
Command
,
".msi"
)
{
exec
.
Command
=
"msiexec /i "
+
exec
.
Command
+
" /qb"
}
PsExec_sdi
(
exec
.
Computername
,
exec
.
Command
,
exec
.
SessionID
)
exec
.
Status
=
Msg_Exec_State_Over
case
Msg_Exec_OpenAdminEXE
:
...
...
@@ -367,7 +380,6 @@ func (exec *MJexec) MsgDeal() interface{} {
}
// 关于 wake 唤醒 的 消息处理
func
(
wake
*
MJwake
)
MsgDeal
()
interface
{}
{
switch
wake
.
Instruction
{
case
Msg_Wake_Status_Req
:
...
...
@@ -466,9 +478,9 @@ func (ci *MJCmdbInfo) MsgDeal() interface{} {
}
// 关于 wxwork 企业微信 的 消息处理
func
(
wxwork
*
MJwxwork
)
MsgDealSend
()
{
// 创建菜单调用工具:https://open.work.weixin.qq.com/wwopen/devtool/interface?doc_id=10786
// 创建菜单官方说明:https://work.weixin.qq.com/api/doc/90000/90135/90231
switch
wxwork
.
Instruction
{
// 电源管理 芝麻开机
...
...
public/msg_init.go
View file @
b764cc38
...
...
@@ -34,6 +34,7 @@ const Msg_Report_WillTurnOffPC string = "WillTurnOffPC"
const
Msg_Report_UpdatePrimaryHost
string
=
"UpdatePrimaryHost"
const
Msg_Report_SignUPUser
string
=
"SignUPUser"
const
Msg_Report_Dimission
string
=
"Dimission"
const
Msg_Report_GetSoftlike
string
=
"GetSoftlike"
// msg exec type ////////////////////////////////////////////////////////////////
...
...
@@ -76,6 +77,13 @@ const (
Msg_Reg_Read
)
type
MsgSwitch
struct
{
S
string
B
bool
SS
[]
string
I
int
}
//
//
// group Json ////
...
...
public/network.go
0 → 100644
View file @
b764cc38
package
public
import
(
"fmt"
"net"
"time"
)
func
Telnet
(
ip
,
port
string
)
bool
{
// 3 秒超时
conn
,
err
:=
net
.
DialTimeout
(
"tcp"
,
ip
+
port
,
3
*
time
.
Second
)
if
err
!=
nil
{
return
false
// todo log handler
}
else
{
if
conn
!=
nil
{
_
=
conn
.
Close
()
return
true
}
else
{
return
false
}
}
}
var
initServer
=
false
func
DownloadFile
(
url
,
saveFile
string
)
error
{
if
!
initServer
{
if
Telnet
(
Host_adserver_wan
,
DaemonListen
[
1
:
])
{
Host_server_download
=
Host_adserver_wan
+
DaemonListen
}
else
{
Host_server_download
=
Host_adserver_lan
+
DaemonListen
}
initServer
=
true
}
fullurl
:=
fmt
.
Sprintf
(
"http://%s/%s"
,
Host_server_download
,
url
)
LOG
(
INFO
,
"Download"
,
fullurl
)
// 采用外部工具进行下载的原因时,文件会写入变量中
// 对于大文件将加载超过文件本身大小的4倍内存
// 这地方暂未优化
switch
OS_Type
{
case
OS_Type_Windows
:
cmd
:=
fmt
.
Sprintf
(
`Invoke-WebRequest -uri "%s" -OutFile "%s"`
,
fullurl
,
saveFile
)
if
err
:=
PSCommandWait
(
cmd
);
err
!=
nil
{
return
err
}
}
return
nil
}
public/user.go
View file @
b764cc38
...
...
@@ -22,6 +22,7 @@ const HOST_Dept_TXHD string = "TXHD"
const
HOST_Dept_BGYJ
string
=
"BGYJ"
const
HOST_Dept_HW
string
=
"HW"
const
HOST_Dept_JD
string
=
"JD"
const
HOST_Dept_DY
string
=
"DY"
// os
const
(
...
...
public/win.go
View file @
b764cc38
...
...
@@ -177,6 +177,29 @@ func PSCommandOutput(cmd string) (string, error) {
}
return
strings
.
TrimSpace
(
string
(
out
)),
nil
}
func
PSCommandWait
(
cmd
string
)
error
{
if
cmd
==
""
{
return
Error_Lost_Parameter
}
cmd
=
"powershell -command "
+
cmd
app
,
appargs
,
err
:=
execcmd_base
(
cmd
)
if
err
!=
nil
{
return
err
}
r
:=
exec
.
Command
(
app
,
appargs
...
)
if
err
:=
r
.
Start
();
err
!=
nil
{
return
err
}
if
err
:=
r
.
Wait
();
err
!=
nil
{
return
err
}
return
err
// out := ToChineseChar(r)
// if err != nil {
// return "", err
// }
// return strings.TrimSpace(string(out)), nil
}
func
PSCommandOutputNoSplit
(
cmd
string
)
(
string
,
error
)
{
cmd
=
"powershell -command "
+
cmd
app
,
appargs
,
err
:=
execcmd_base
(
cmd
)
...
...
@@ -364,6 +387,19 @@ func GetNewFolder(rdir, extdir string) string {
return
firstName
}
// 获取指定文件夹中的文件名
func
GetFolderInFileName
(
dir
string
)
([]
string
,
error
)
{
f
,
err
:=
ioutil
.
ReadDir
(
dir
)
if
err
!=
nil
{
return
nil
,
err
}
r
:=
make
([]
string
,
len
(
f
))
for
i
,
j
:=
range
f
{
r
[
i
]
=
j
.
Name
()
}
return
r
,
nil
}
// 获取硬件信息
func
GetHardwareCPUForPS
()
(
string
,
string
,
string
,
string
)
{
var
c
,
j
int
...
...
registry/registry.go
View file @
b764cc38
...
...
@@ -26,6 +26,13 @@ func Write_DC(key, value string) {
func
Query_DC
(
key
string
)
string
{
return
Query_key_one
(
HKLM
,
REG_ADCONTROL
,
key
)
}
func
Query_DC_panic
(
key
string
)
string
{
ret
:=
Query_key_one
(
HKLM
,
REG_ADCONTROL
,
key
)
if
ret
==
""
{
panic
(
errors
.
New
(
key
+
" not found reg query result"
))
}
return
ret
}
// reg func for AD
...
...
users/menu.go
View file @
b764cc38
...
...
@@ -3,6 +3,7 @@ package main
import
(
"encoding/json"
"fmt"
"log"
"strings"
pub
"git.zhiweidata.top/taotengfei/AD-Control-Golang/public"
...
...
@@ -395,23 +396,83 @@ func tWindowsBlock() {
// 工具集合 软件安装
func
tSoftwareInstall
()
{
softpath
:=
`Z:\softlike\`
if
pub
.
NotExist
(
softpath
)
{
pub
.
Execcmd_wait
(
"gpupdate /force /target:user"
)
mw
:=
&
siMainWindow
{
siM
:
siSetModel
()}
if
_
,
err
:=
(
MainWindow
{
AssignTo
:
&
mw
.
MainWindow
,
Title
:
"软件安装"
,
MinSize
:
Size
{
Width
:
250
,
Height
:
500
},
Size
:
Size
{
Width
:
250
,
Height
:
500
},
Layout
:
VBox
{
MarginsZero
:
true
},
// 请勿删除
Children
:
[]
Widget
{
ListBox
{
AssignTo
:
&
mw
.
siLB
,
Model
:
mw
.
siM
,
OnItemActivated
:
mw
.
siInstall
,
},
PushButton
{
Text
:
"安装"
,
OnClicked
:
mw
.
siInstall
,
},
},
}
.
Run
());
err
!=
nil
{
log
.
Fatal
(
err
)
}
softname
:=
chooseFile
(
"请选择安装包"
,
softpath
)
if
softname
==
""
{
pub
.
LOG
(
INFO
,
"USERS_TOOLS"
,
"执行 工具集合-软件安装"
)
}
type
siMainWindow
struct
{
*
walk
.
MainWindow
siM
*
siModel
siLB
*
walk
.
ListBox
}
type
EnvItem
struct
{
name
string
}
type
siModel
struct
{
walk
.
ListModelBase
items
[]
EnvItem
}
// 请勿删除
func
(
m
*
siModel
)
ItemCount
()
int
{
return
len
(
m
.
items
)
}
// 请勿删除
func
(
m
*
siModel
)
Value
(
index
int
)
interface
{}
{
return
m
.
items
[
index
]
.
name
}
func
(
mw
*
siMainWindow
)
siInstall
()
{
app
:=
(
&
mw
.
siM
.
items
[
mw
.
siLB
.
CurrentIndex
()])
.
name
go
Msg
(
"下载文件中,请等待,请勿重复点击"
)
pub
.
LOG
(
INFO
,
"SoftwareInstall"
,
"下载"
+
app
)
url
:=
fmt
.
Sprintf
(
"%s/%s"
,
pub
.
Msg_softlike
,
app
)
fullapp
:=
fmt
.
Sprintf
(
`%s\%s`
,
pub
.
Dir_tmp
,
app
)
err
:=
pub
.
DownloadFile
(
url
,
fullapp
)
if
err
!=
nil
{
go
Msg
(
"下载文件失败"
)
pub
.
LOG
(
ERROR
,
"SoftwareInstall"
,
"下载文件失败"
+
err
.
Error
())
return
}
if
strings
.
HasPrefix
(
softname
,
softpath
)
{
softname
=
strings
.
TrimPrefix
(
softname
,
softpath
)
go
Msg
(
"正在复制安装包,请稍等!"
)
pub
.
SendServerExec
(
pub
.
GJexecInstallSoftware
(
softname
,
User_sessionID
))
}
else
{
go
Msg
(
"安装失败:不是指定的文件路径!"
)
pub
.
LOG
(
INFO
,
"SoftwareInstall"
,
app
+
" 下载完成"
)
pub
.
SendADMsg
(
pub
.
Msg_Exec
,
pub
.
GJexecInstallSoftware
(
fullapp
,
User_sessionID
))
}
func
siSetModel
()
*
siModel
{
pub
.
SendADMsg
(
pub
.
Msg_Report
,
pub
.
GJreportString
(
pub
.
Msg_Report_GetSoftlike
,
""
))
m
:=
&
siModel
{
items
:
make
([]
EnvItem
,
strings
.
Count
(
pub
.
MS
.
S
,
pub
.
SymbolSplit
)
+
1
)}
for
i
,
j
:=
range
strings
.
Split
(
pub
.
MS
.
S
,
pub
.
SymbolSplit
)
{
m
.
items
[
i
]
=
EnvItem
{
j
}
}
pub
.
LOG
(
INFO
,
"USERS_TOOLS"
,
"执行 工具集合-软件安装"
)
return
m
}
// 文件共享 会议室大屏主机
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment