change-image-suffix 2.1.13 → 2.1.15
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.
- package/CHANGELOG.md +19 -0
- package/dist/index.js +25 -26
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
### [2.1.15](https://github.com/GuoSirius/change-image-suffix/compare/v2.1.14...v2.1.15) (2026-05-25)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* use AllFilesystemObjects to support mixed file+directory selection ([5a67d8f](https://github.com/GuoSirius/change-image-suffix/commit/5a67d8f3a436f24b1b9cff2c173d5aeea661f907))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Documentation
|
|
14
|
+
|
|
15
|
+
* update CLAUDE.md for AllFilesystemObjects architecture ([5957326](https://github.com/GuoSirius/change-image-suffix/commit/59573263dfb01c9d27239d06878068d63de96229))
|
|
16
|
+
|
|
17
|
+
### [2.1.14](https://github.com/GuoSirius/change-image-suffix/compare/v2.1.13...v2.1.14) (2026-05-25)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Bug Fixes
|
|
21
|
+
|
|
22
|
+
* add quotes around %V/%1 in context menu, make resolveSplitPath return string[] ([28ccc83](https://github.com/GuoSirius/change-image-suffix/commit/28ccc83d39f4441eac31a8985509ac49a8ab7019))
|
|
23
|
+
|
|
5
24
|
### [2.1.13](https://github.com/GuoSirius/change-image-suffix/compare/v2.1.12...v2.1.13) (2026-05-25)
|
|
6
25
|
|
|
7
26
|
|
package/dist/index.js
CHANGED
|
@@ -68,10 +68,10 @@ function installContextMenu() {
|
|
|
68
68
|
{ verb: 'tiff', label: '📋 TIFF' },
|
|
69
69
|
];
|
|
70
70
|
// ── 使用 ExtendedSubCommandsKey,直接调用 node.exe(无 bat 中转)──
|
|
71
|
+
// AllFilesystemObjects 覆盖文件和目录,支持混合多选
|
|
71
72
|
const menuBases = [
|
|
72
|
-
{ base: 'HKCU\\Software\\Classes\\Directory\\Background\\shell\\cis', subMenu: 'Directory\\ContextMenus\\cis', arg: '-p %V' },
|
|
73
|
-
{ base: 'HKCU\\Software\\Classes\\
|
|
74
|
-
{ base: 'HKCU\\Software\\Classes\\*\\shell\\cis', subMenu: 'Directory\\ContextMenus\\cis_file', arg: '-f %1' },
|
|
73
|
+
{ base: 'HKCU\\Software\\Classes\\Directory\\Background\\shell\\cis', subMenu: 'Directory\\ContextMenus\\cis', arg: '-p "%V"' },
|
|
74
|
+
{ base: 'HKCU\\Software\\Classes\\AllFilesystemObjects\\shell\\cis', subMenu: 'Directory\\ContextMenus\\cis_afo', arg: '%*', multiSelect: true },
|
|
75
75
|
];
|
|
76
76
|
// 1. 注册格式子菜单
|
|
77
77
|
const REG_ROOT = 'HKCU\\Software\\Classes\\';
|
|
@@ -89,6 +89,9 @@ function installContextMenu() {
|
|
|
89
89
|
execSync(`reg add "${menu.base}" /ve /d "🖼 转换图片 (cis)" /f`, { stdio: 'ignore' });
|
|
90
90
|
execSync(`reg add "${menu.base}" /v Icon /d "${iconPath}" /f`, { stdio: 'ignore' });
|
|
91
91
|
execSync(`reg add "${menu.base}" /v ExtendedSubCommandsKey /d "${menu.subMenu}" /f`, { stdio: 'ignore' });
|
|
92
|
+
if (menu.multiSelect) {
|
|
93
|
+
execSync(`reg add "${menu.base}" /v MultiSelectModel /d Player /f`, { stdio: 'ignore' });
|
|
94
|
+
}
|
|
92
95
|
}
|
|
93
96
|
// 写入版本标记,用于检测 npm update 后自动刷新菜单
|
|
94
97
|
const versionFile = path.join(appDataDir, 'version.json');
|
|
@@ -103,11 +106,12 @@ function installContextMenu() {
|
|
|
103
106
|
}
|
|
104
107
|
function uninstallContextMenu() {
|
|
105
108
|
requireWindows();
|
|
106
|
-
//
|
|
109
|
+
// 删除主菜单项(含旧版残留)
|
|
107
110
|
const mainKeys = [
|
|
108
111
|
'HKCU\\Software\\Classes\\Directory\\Background\\shell\\cis',
|
|
109
|
-
'HKCU\\Software\\Classes\\
|
|
110
|
-
'HKCU\\Software\\Classes
|
|
112
|
+
'HKCU\\Software\\Classes\\AllFilesystemObjects\\shell\\cis',
|
|
113
|
+
'HKCU\\Software\\Classes\\Directory\\shell\\cis', // 旧版残留
|
|
114
|
+
'HKCU\\Software\\Classes\\*\\shell\\cis', // 旧版残留
|
|
111
115
|
];
|
|
112
116
|
for (const key of mainKeys) {
|
|
113
117
|
try {
|
|
@@ -115,11 +119,12 @@ function uninstallContextMenu() {
|
|
|
115
119
|
}
|
|
116
120
|
catch { /* ignore */ }
|
|
117
121
|
}
|
|
118
|
-
//
|
|
122
|
+
// 删除公共子菜单
|
|
119
123
|
const subMenuRoots = [
|
|
120
124
|
'HKCU\\Software\\Classes\\Directory\\ContextMenus\\cis',
|
|
121
|
-
'HKCU\\Software\\Classes\\Directory\\ContextMenus\\cis_dir',
|
|
122
|
-
'HKCU\\Software\\Classes\\Directory\\ContextMenus\\cis_file',
|
|
125
|
+
'HKCU\\Software\\Classes\\Directory\\ContextMenus\\cis_dir', // 旧版残留
|
|
126
|
+
'HKCU\\Software\\Classes\\Directory\\ContextMenus\\cis_file', // 旧版残留
|
|
127
|
+
'HKCU\\Software\\Classes\\Directory\\ContextMenus\\cis_afo',
|
|
123
128
|
];
|
|
124
129
|
for (const root of subMenuRoots) {
|
|
125
130
|
try {
|
|
@@ -127,13 +132,13 @@ function uninstallContextMenu() {
|
|
|
127
132
|
}
|
|
128
133
|
catch { /* ignore */ }
|
|
129
134
|
}
|
|
130
|
-
//
|
|
135
|
+
// 删除遗留文件(旧版 bat 脚本、图标、版本标记)
|
|
131
136
|
const appDataDir = path.join(os.homedir(), 'AppData', 'Roaming', 'change-image-suffix');
|
|
132
137
|
const batPath = path.join(appDataDir, 'cis_file.bat');
|
|
133
138
|
try {
|
|
134
139
|
fs.unlinkSync(batPath);
|
|
135
140
|
}
|
|
136
|
-
catch { /* ignore */ }
|
|
141
|
+
catch { /* ignore */ } // 旧版残留清理
|
|
137
142
|
const iconPath = path.join(appDataDir, 'icon.ico');
|
|
138
143
|
try {
|
|
139
144
|
fs.unlinkSync(iconPath);
|
|
@@ -183,19 +188,13 @@ function autoUpdateContextMenu() {
|
|
|
183
188
|
// 此函数尝试将拆散的片段拼接回完整路径。
|
|
184
189
|
function resolveSplitPath(parts) {
|
|
185
190
|
if (parts.length === 1)
|
|
186
|
-
return path.resolve(parts[0]);
|
|
187
|
-
//
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
joined += ' ' + parts[j];
|
|
194
|
-
if (fs.existsSync(joined))
|
|
195
|
-
return path.resolve(joined);
|
|
196
|
-
}
|
|
197
|
-
// 都不存在,返回全拼接结果(后续流程会报 "不存在")
|
|
198
|
-
return path.resolve(joined);
|
|
191
|
+
return [path.resolve(parts[0])];
|
|
192
|
+
// 尝试将拆散的片段用空格拼接回完整路径(右键菜单可能将含空格的路径拆成多段)
|
|
193
|
+
const fullJoin = parts.join(' ');
|
|
194
|
+
if (fs.existsSync(fullJoin))
|
|
195
|
+
return [path.resolve(fullJoin)];
|
|
196
|
+
// 无法拼接为单个存在的路径 → 各段视为独立路径(用户主动传了多个路径)
|
|
197
|
+
return parts.map(p => path.resolve(p));
|
|
199
198
|
}
|
|
200
199
|
function parseArgs() {
|
|
201
200
|
const args = process.argv.slice(2);
|
|
@@ -278,7 +277,7 @@ function parseArgs() {
|
|
|
278
277
|
dirsFromFlag.push(path.resolve('.'));
|
|
279
278
|
}
|
|
280
279
|
else {
|
|
281
|
-
dirsFromFlag.push(resolveSplitPath(parts));
|
|
280
|
+
dirsFromFlag.push(...resolveSplitPath(parts));
|
|
282
281
|
}
|
|
283
282
|
i++;
|
|
284
283
|
continue;
|
|
@@ -294,7 +293,7 @@ function parseArgs() {
|
|
|
294
293
|
console.error('❌ -f/--file 需要指定至少一个文件路径');
|
|
295
294
|
process.exit(1);
|
|
296
295
|
}
|
|
297
|
-
filesFromFlag.push(resolveSplitPath(parts));
|
|
296
|
+
filesFromFlag.push(...resolveSplitPath(parts));
|
|
298
297
|
i++;
|
|
299
298
|
continue;
|
|
300
299
|
}
|