1+ const fs = require ( 'fs' ) ;
2+ const { spawn } = require ( 'child_process' ) ;
3+ const path = require ( 'path' ) ;
4+
5+ // 确保 __dirname 有值,如果没有则使用当前工作目录
6+ const srcDir = __dirname || "" ;
7+ // 确保目标目录有值,空字符串会导致解压到当前目录
8+ const destDir = process . env . AILY_SDK_PATH || "" ;
9+ const _7zaPath = process . env . AILY_7ZA_PATH || "" ;
10+
11+ // 使用传统的回调式 API 并用 Promise 包装
12+ function readdir ( dir ) {
13+ return new Promise ( ( resolve , reject ) => {
14+ fs . readdir ( dir , ( err , files ) => {
15+ if ( err ) reject ( err ) ;
16+ else resolve ( files ) ;
17+ } ) ;
18+ } ) ;
19+ }
20+
21+ // 自定义递归删除函数
22+ function deleteFolderRecursive ( dirPath ) {
23+ if ( fs . existsSync ( dirPath ) ) {
24+ fs . readdirSync ( dirPath ) . forEach ( file => {
25+ const curPath = path . join ( dirPath , file ) ;
26+ if ( fs . lstatSync ( curPath ) . isDirectory ( ) ) {
27+ // 递归删除子目录
28+ deleteFolderRecursive ( curPath ) ;
29+ } else {
30+ // 删除文件,忽略错误
31+ try {
32+ fs . unlinkSync ( curPath ) ;
33+ } catch ( e ) {
34+ console . warn ( `无法删除文件: ${ curPath } ` , e ) ;
35+ }
36+ }
37+ } ) ;
38+ // 删除目录本身
39+ try {
40+ fs . rmdirSync ( dirPath ) ;
41+ } catch ( e ) {
42+ console . warn ( `无法删除目录: ${ dirPath } ` , e ) ;
43+ // 如果删除失败,尝试重命名
44+ const tempPath = path . join ( path . dirname ( dirPath ) , `_temp_${ Date . now ( ) } ` ) ;
45+ fs . renameSync ( dirPath , tempPath ) ;
46+ deleteFolderRecursive ( tempPath ) ;
47+ }
48+ }
49+ }
50+
51+ // 使用 Promise 和 async/await 简化异步操作
52+ async function extractArchives ( ) {
53+ try {
54+ // 确保源目录存在
55+ if ( ! fs . existsSync ( srcDir ) ) {
56+ console . error ( `源目录不存在: ${ srcDir } ` ) ;
57+ return ;
58+ }
59+
60+ // 确保目标目录存在
61+ if ( ! destDir ) {
62+ console . error ( '未设置目标目录' ) ;
63+ return ;
64+ }
65+
66+ // 确保 7za.exe 存在
67+ if ( ! fs . existsSync ( _7zaPath ) ) {
68+ console . error ( `7za.exe 不存在: ${ _7zaPath } ` ) ;
69+ return ;
70+ }
71+
72+ if ( ! fs . existsSync ( destDir ) ) {
73+ console . log ( `目标目录不存在,创建: ${ destDir } ` ) ;
74+ fs . mkdirSync ( destDir , { recursive : true } ) ;
75+ }
76+
77+ // 读取目录并过滤出 .7z 文件
78+ const files = await readdir ( srcDir ) ;
79+ const archiveFiles = files . filter ( file => path . extname ( file ) . toLowerCase ( ) === '.7z' ) ;
80+
81+ console . log ( `找到 ${ archiveFiles . length } 个 .7z 文件` ) ;
82+
83+ // 处理每个压缩文件
84+ for ( const file of archiveFiles ) {
85+ if ( ! file ) {
86+ console . error ( '文件名为空,跳过' ) ;
87+ continue ;
88+ }
89+
90+ try {
91+ const srcPath = path . join ( srcDir , file ) ;
92+ console . log ( `准备解压: ${ srcPath } ` ) ;
93+
94+ await unpack ( srcPath , destDir ) ;
95+ console . log ( `已解压 ${ file } 到 ${ destDir } ` ) ;
96+
97+ // 重命名
98+ const newName = path . basename ( file , '.7z' ) ;
99+ const destPath = path . join ( destDir , newName ) ;
100+
101+ // 将newName中的@替换为_
102+ const newName2 = newName . replace ( '@' , '_' ) ;
103+ const newPath = path . join ( destDir , newName2 ) ;
104+
105+ // 判断是否存在目标目录,如果存在则删除
106+ if ( fs . existsSync ( newPath ) ) {
107+ try {
108+ deleteFolderRecursive ( newPath ) ;
109+ console . log ( `已删除目录: ${ newPath } ` ) ;
110+ } catch ( err ) {
111+ console . error ( `无法删除目录: ${ newPath } ` , err ) ;
112+ continue
113+ }
114+ }
115+
116+ fs . renameSync ( destPath , newPath ) ;
117+ console . log ( `已重命名 ${ destPath } 为 ${ newPath } ` ) ;
118+
119+ // Check if post-install script exists and run it
120+ const isWindows = process . platform === 'win32' ;
121+ const scriptName = isWindows ? 'post_install.bat' : 'post_install.sh' ;
122+ const scriptPath = path . join ( newPath , scriptName ) ;
123+
124+ if ( fs . existsSync ( scriptPath ) ) {
125+ console . log ( `Running post-install script: ${ scriptPath } ` ) ;
126+
127+ // Make sure the script is executable on Unix
128+ if ( ! isWindows ) {
129+ fs . chmodSync ( scriptPath , '755' ) ;
130+ }
131+
132+ // Prepare command and arguments
133+ const command = isWindows ? 'cmd' : 'sh' ;
134+ const args = isWindows ? [ '/c' , scriptPath ] : [ scriptPath ] ;
135+
136+ // Execute the script
137+ await new Promise ( ( resolve , reject ) => {
138+ const proc = spawn ( command , args , {
139+ cwd : newPath ,
140+ stdio : 'inherit' ,
141+ windowsHide : true
142+ } ) ;
143+
144+ proc . on ( 'exit' , ( code ) => {
145+ if ( code === 0 ) {
146+ console . log ( `Post-install script completed successfully.` ) ;
147+ resolve ( ) ;
148+ } else {
149+ console . error ( `Post-install script failed with code ${ code } ` ) ;
150+ reject ( new Error ( `Script exited with code ${ code } ` ) ) ;
151+ }
152+ } ) ;
153+
154+ proc . on ( 'error' , ( err ) => {
155+ console . error ( 'Failed to run post-install script:' , err ) ;
156+ reject ( err ) ;
157+ } ) ;
158+ } ) ;
159+ } else {
160+ console . log ( `No post-install script found at ${ scriptPath } ` ) ;
161+ }
162+
163+ } catch ( error ) {
164+ console . error ( `解压 ${ file } 失败:` , error ) ;
165+ }
166+ }
167+ } catch ( err ) {
168+ console . error ( '无法读取目录:' , err ) ;
169+ }
170+ }
171+
172+ // 使用 Promise 封装解压函数
173+ function unpack ( archivePath , destination ) {
174+ return new Promise ( ( resolve , reject ) => {
175+ if ( ! archivePath ) {
176+ return reject ( new Error ( '压缩文件路径不能为空' ) ) ;
177+ }
178+ if ( ! destination ) {
179+ return reject ( new Error ( '目标目录不能为空' ) ) ;
180+ }
181+
182+ const args = [ 'x' , archivePath , '-y' , '-o' + destination ] ;
183+ console . log ( `执行命令: ${ _7zaPath } ${ args . join ( ' ' ) } ` ) ;
184+
185+ const proc = spawn ( _7zaPath , args , { windowsHide : true } ) ;
186+
187+ let output = '' ;
188+
189+ proc . stdout . on ( 'data' , function ( chunk ) {
190+ output += chunk . toString ( ) ;
191+ } ) ;
192+ proc . stderr . on ( 'data' , function ( chunk ) {
193+ output += chunk . toString ( ) ;
194+ } ) ;
195+
196+ proc . on ( 'error' , function ( err ) {
197+ console . error ( '7-zip 错误:' , err ) ;
198+ reject ( err ) ;
199+ } ) ;
200+
201+ proc . on ( 'exit' , function ( code ) {
202+ if ( code === 0 ) {
203+ resolve ( ) ;
204+ } else {
205+ const error = new Error ( `7-zip 退出码 ${ code } \n${ output } ` ) ;
206+ reject ( error ) ;
207+ }
208+ } ) ;
209+ } ) ;
210+ }
211+
212+ // 执行主函数
213+ extractArchives ( ) . catch ( function ( err ) {
214+ console . error ( '执行失败:' , err ) ;
215+ } ) ;
0 commit comments