Mercurial > vim
annotate src/uninstal.c @ 2254:4620acaf4814 vim73
One more fix for conceal patch.
author | Bram Moolenaar <bram@vim.org> |
---|---|
date | Sun, 06 Jun 2010 17:41:24 +0200 |
parents | 120502692d82 |
children | 573da4dac306 |
rev | line source |
---|---|
7 | 1 /* vi:set ts=8 sts=4 sw=4: |
2 * | |
3 * VIM - Vi IMproved by Bram Moolenaar | |
4 * | |
5 * Do ":help uganda" in Vim to read copying and usage conditions. | |
6 * Do ":help credits" in Vim to see a list of people who contributed. | |
7 * See README.txt for an overview of the Vim source code. | |
8 */ | |
9 | |
10 /* | |
11 * uninstal.c: Minimalistic uninstall program for Vim on MS-Windows | |
12 * Removes: | |
13 * - the "Edit with Vim" popup menu entry | |
14 * - the Vim "Open With..." popup menu entry | |
15 * - any Vim Batch files in the path | |
16 * - icons for Vim on the Desktop | |
17 * - the Vim entry in the Start Menu | |
18 */ | |
19 | |
20 /* Include common code for dosinst.c and uninstal.c. */ | |
21 #include "dosinst.h" | |
22 | |
23 /* | |
24 * Return TRUE if the user types a 'y' or 'Y', FALSE otherwise. | |
25 */ | |
26 static int | |
27 confirm(void) | |
28 { | |
29 char answer[10]; | |
30 | |
31 fflush(stdout); | |
32 return (scanf(" %c", answer) == 1 && toupper(answer[0]) == 'Y'); | |
33 } | |
34 | |
35 #ifdef WIN3264 | |
36 /* | |
37 * Check if the popup menu entry exists and what gvim it refers to. | |
38 * Returns non-zero when it's found. | |
39 */ | |
40 static int | |
41 popup_gvim_path(char *buf) | |
42 { | |
43 HKEY key_handle; | |
44 DWORD value_type; | |
45 DWORD bufsize = BUFSIZE; | |
46 int r; | |
47 | |
48 /* Open the key where the path to gvim.exe is stored. */ | |
49 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Vim\\Gvim", 0, KEY_READ, | |
50 &key_handle) != ERROR_SUCCESS) | |
51 return 0; | |
52 | |
53 /* get the DisplayName out of it to show the user */ | |
54 r = RegQueryValueEx(key_handle, "path", 0, | |
55 &value_type, (LPBYTE)buf, &bufsize); | |
56 RegCloseKey(key_handle); | |
57 | |
58 return (r == ERROR_SUCCESS); | |
59 } | |
60 | |
61 /* | |
62 * Check if the "Open With..." menu entry exists and what gvim it refers to. | |
63 * Returns non-zero when it's found. | |
64 */ | |
65 static int | |
66 openwith_gvim_path(char *buf) | |
67 { | |
68 HKEY key_handle; | |
69 DWORD value_type; | |
70 DWORD bufsize = BUFSIZE; | |
71 int r; | |
72 | |
73 /* Open the key where the path to gvim.exe is stored. */ | |
74 if (RegOpenKeyEx(HKEY_CLASSES_ROOT, | |
75 "Applications\\gvim.exe\\shell\\edit\\command", 0, KEY_READ, | |
76 &key_handle) != ERROR_SUCCESS) | |
77 return 0; | |
78 | |
79 /* get the DisplayName out of it to show the user */ | |
80 r = RegQueryValueEx(key_handle, "", 0, &value_type, (LPBYTE)buf, &bufsize); | |
81 RegCloseKey(key_handle); | |
82 | |
83 return (r == ERROR_SUCCESS); | |
84 } | |
85 | |
86 static void | |
87 remove_popup(void) | |
88 { | |
89 int fail = 0; | |
90 HKEY kh; | |
91 | |
92 if (RegDeleteKey(HKEY_CLASSES_ROOT, "CLSID\\{51EEE242-AD87-11d3-9C1E-0090278BBD99}\\InProcServer32") != ERROR_SUCCESS) | |
93 ++fail; | |
94 if (RegDeleteKey(HKEY_CLASSES_ROOT, "CLSID\\{51EEE242-AD87-11d3-9C1E-0090278BBD99}") != ERROR_SUCCESS) | |
95 ++fail; | |
96 if (RegDeleteKey(HKEY_CLASSES_ROOT, "*\\shellex\\ContextMenuHandlers\\gvim") != ERROR_SUCCESS) | |
97 ++fail; | |
98 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved", 0, KEY_ALL_ACCESS, &kh) != ERROR_SUCCESS) | |
99 ++fail; | |
100 else | |
101 { | |
102 if (RegDeleteValue(kh, "{51EEE242-AD87-11d3-9C1E-0090278BBD99}") != ERROR_SUCCESS) | |
103 ++fail; | |
104 RegCloseKey(kh); | |
105 } | |
106 if (RegDeleteKey(HKEY_LOCAL_MACHINE, "Software\\Vim\\Gvim") != ERROR_SUCCESS) | |
107 ++fail; | |
108 if (RegDeleteKey(HKEY_LOCAL_MACHINE, "Software\\Vim") != ERROR_SUCCESS) | |
109 ++fail; | |
110 | |
111 if (fail == 6) | |
112 printf("No Vim popup registry entries could be removed\n"); | |
113 else if (fail > 0) | |
114 printf("Some Vim popup registry entries could not be removed\n"); | |
115 else | |
116 printf("The Vim popup registry entries have been removed\n"); | |
117 } | |
118 | |
119 static void | |
120 remove_openwith(void) | |
121 { | |
122 int fail = 0; | |
123 | |
124 if (RegDeleteKey(HKEY_CLASSES_ROOT, "Applications\\gvim.exe\\shell\\edit\\command") != ERROR_SUCCESS) | |
125 ++fail; | |
126 if (RegDeleteKey(HKEY_CLASSES_ROOT, "Applications\\gvim.exe\\shell\\edit") != ERROR_SUCCESS) | |
127 ++fail; | |
128 if (RegDeleteKey(HKEY_CLASSES_ROOT, "Applications\\gvim.exe\\shell") != ERROR_SUCCESS) | |
129 ++fail; | |
130 if (RegDeleteKey(HKEY_CLASSES_ROOT, "Applications\\gvim.exe") != ERROR_SUCCESS) | |
131 ++fail; | |
132 if (RegDeleteKey(HKEY_CLASSES_ROOT, ".htm\\OpenWithList\\gvim.exe") != ERROR_SUCCESS) | |
133 ++fail; | |
134 if (RegDeleteKey(HKEY_CLASSES_ROOT, ".vim\\OpenWithList\\gvim.exe") != ERROR_SUCCESS) | |
135 ++fail; | |
136 if (RegDeleteKey(HKEY_CLASSES_ROOT, "*\\OpenWithList\\gvim.exe") != ERROR_SUCCESS) | |
137 ++fail; | |
138 | |
139 if (fail == 7) | |
140 printf("No Vim open-with registry entries could be removed\n"); | |
141 else if (fail > 0) | |
142 printf("Some Vim open-with registry entries could not be removed\n"); | |
143 else | |
144 printf("The Vim open-with registry entries have been removed\n"); | |
145 } | |
146 #endif | |
147 | |
148 /* | |
149 * Check if a batch file is really for the current version. Don't delete a | |
150 * batch file that was written for another (possibly newer) version. | |
151 */ | |
152 static int | |
153 batfile_thisversion(char *path) | |
154 { | |
155 FILE *fd; | |
156 char line[BUFSIZE]; | |
157 char *p; | |
158 int ver_len = strlen(VIM_VERSION_NODOT); | |
159 int found = FALSE; | |
160 | |
161 fd = fopen(path, "r"); | |
162 if (fd != NULL) | |
163 { | |
164 while (fgets(line, BUFSIZE, fd) != NULL) | |
165 { | |
166 for (p = line; *p != 0; ++p) | |
167 /* don't accept "vim60an" when looking for "vim60". */ | |
168 if (strnicmp(p, VIM_VERSION_NODOT, ver_len) == 0 | |
169 && !isdigit(p[ver_len]) | |
170 && !isalpha(p[ver_len])) | |
171 { | |
172 found = TRUE; | |
173 break; | |
174 } | |
175 if (found) | |
176 break; | |
177 } | |
178 fclose(fd); | |
179 } | |
180 return found; | |
181 } | |
182 | |
183 static int | |
184 remove_batfiles(int doit) | |
185 { | |
186 char *batfile_path; | |
187 int i; | |
188 int found = 0; | |
189 | |
190 for (i = 1; i < TARGET_COUNT; ++i) | |
191 { | |
192 batfile_path = searchpath_save(targets[i].batname); | |
193 if (batfile_path != NULL && batfile_thisversion(batfile_path)) | |
194 { | |
195 ++found; | |
196 if (doit) | |
197 { | |
198 printf("removing %s\n", batfile_path); | |
199 remove(batfile_path); | |
200 } | |
201 else | |
202 printf(" - the batch file %s\n", batfile_path); | |
203 free(batfile_path); | |
204 } | |
205 } | |
206 return found; | |
207 } | |
208 | |
209 #ifdef WIN3264 | |
210 static void | |
211 remove_if_exists(char *path, char *filename) | |
212 { | |
213 char buf[BUFSIZE]; | |
214 FILE *fd; | |
215 | |
216 sprintf(buf, "%s\\%s", path, filename); | |
217 | |
218 fd = fopen(buf, "r"); | |
219 if (fd != NULL) | |
220 { | |
221 fclose(fd); | |
222 printf("removing %s\n", buf); | |
223 remove(buf); | |
224 } | |
225 } | |
226 | |
227 static void | |
228 remove_icons(void) | |
229 { | |
230 char path[BUFSIZE]; | |
231 int i; | |
232 | |
233 if (get_shell_folder_path(path, "desktop")) | |
234 for (i = 0; i < ICON_COUNT; ++i) | |
235 remove_if_exists(path, icon_link_names[i]); | |
236 } | |
237 | |
238 static void | |
239 remove_start_menu(void) | |
240 { | |
241 char path[BUFSIZE]; | |
242 int i; | |
243 struct stat st; | |
244 | |
245 if (get_shell_folder_path(path, VIM_STARTMENU)) | |
246 { | |
247 for (i = 1; i < TARGET_COUNT; ++i) | |
248 remove_if_exists(path, targets[i].lnkname); | |
249 remove_if_exists(path, "uninstall.lnk"); | |
250 remove_if_exists(path, "Help.lnk"); | |
251 /* Win95 uses .pif, WinNT uses .lnk */ | |
252 remove_if_exists(path, "Vim tutor.pif"); | |
253 remove_if_exists(path, "Vim tutor.lnk"); | |
254 remove_if_exists(path, "Vim online.url"); | |
255 if (stat(path, &st) == 0) | |
256 { | |
257 printf("removing %s\n", path); | |
258 rmdir(path); | |
259 } | |
260 } | |
261 } | |
262 #endif | |
263 | |
264 #if 0 /* currently not used */ | |
265 /* | |
266 * Return TRUE when we're on Windows 95/98/ME. | |
267 */ | |
268 static int | |
269 win95(void) | |
270 { | |
271 static int done = FALSE; | |
272 static DWORD PlatformId; | |
273 | |
274 if (!done) | |
275 { | |
276 OSVERSIONINFO ovi; | |
277 | |
278 ovi.dwOSVersionInfoSize = sizeof(ovi); | |
279 GetVersionEx(&ovi); | |
280 PlatformId = ovi.dwPlatformId; | |
281 done = TRUE; | |
282 } | |
283 /* Win NT/2000/XP is VER_PLATFORM_WIN32_NT */ | |
284 return PlatformId == VER_PLATFORM_WIN32_WINDOWS; | |
285 } | |
286 #endif | |
287 | |
288 static void | |
289 delete_uninstall_key(void) | |
290 { | |
291 #ifdef WIN3264 | |
292 RegDeleteKey(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Vim " VIM_VERSION_SHORT); | |
293 #else | |
294 FILE *fd; | |
295 char buf[BUFSIZE]; | |
296 | |
297 /* | |
298 * On DJGPP we delete registry entries by creating a .inf file and | |
299 * installing it. | |
300 */ | |
301 fd = fopen("vim.inf", "w"); | |
302 if (fd != NULL) | |
303 { | |
304 fprintf(fd, "[version]\n"); | |
305 fprintf(fd, "signature=\"$CHICAGO$\"\n\n"); | |
306 fprintf(fd, "[DefaultInstall]\n"); | |
307 fprintf(fd, "DelReg=DeleteMe\n\n"); | |
308 fprintf(fd, "[DeleteMe]\n"); | |
309 fprintf(fd, "HKLM,\"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Vim " VIM_VERSION_SHORT "\"\n"); | |
310 fclose(fd); | |
311 | |
312 /* Don't know how to detect Win NT with DJGPP. Hack: Just try the Win | |
313 * 95/98/ME method, since the DJGPP version can't use long filenames | |
314 * on Win NT anyway. */ | |
315 sprintf(buf, "rundll setupx.dll,InstallHinfSection DefaultInstall 132 %s\\vim.inf", installdir); | |
316 run_command(buf); | |
317 #if 0 | |
318 /* Windows NT method (untested). */ | |
319 sprintf(buf, "rundll32 syssetup,SetupInfObjectInstallAction DefaultInstall 128 %s\\vim.inf", installdir); | |
320 run_command(buf); | |
321 #endif | |
322 | |
323 remove("vim.inf"); | |
324 } | |
325 #endif | |
326 } | |
327 | |
328 int | |
329 main(int argc, char *argv[]) | |
330 { | |
331 int found = 0; | |
332 FILE *fd; | |
333 #ifdef WIN3264 | |
334 int i; | |
335 struct stat st; | |
336 char icon[BUFSIZE]; | |
337 char path[BUFSIZE]; | |
338 char popup_path[BUFSIZE]; | |
339 | |
340 /* The nsis uninstaller calls us with a "-nsis" argument. */ | |
341 if (argc == 2 && stricmp(argv[1], "-nsis") == 0) | |
342 interactive = FALSE; | |
343 else | |
344 #endif | |
345 interactive = TRUE; | |
346 | |
347 /* Initialize this program. */ | |
348 do_inits(argv); | |
349 | |
350 printf("This program will remove the following items:\n"); | |
351 | |
352 #ifdef WIN3264 | |
353 if (popup_gvim_path(popup_path)) | |
354 { | |
355 printf(" - the \"Edit with Vim\" entry in the popup menu\n"); | |
356 printf(" which uses \"%s\"\n", popup_path); | |
2217
120502692d82
Improve the MS-Windows installer.
Bram Moolenaar <bram@vim.org>
parents:
7
diff
changeset
|
357 if (interactive) |
120502692d82
Improve the MS-Windows installer.
Bram Moolenaar <bram@vim.org>
parents:
7
diff
changeset
|
358 printf("\nRemove it (y/n)? "); |
120502692d82
Improve the MS-Windows installer.
Bram Moolenaar <bram@vim.org>
parents:
7
diff
changeset
|
359 if (!interactive || confirm()) |
7 | 360 { |
361 remove_popup(); | |
362 /* Assume the "Open With" entry can be removed as well, don't | |
363 * bother the user with asking him again. */ | |
364 remove_openwith(); | |
365 } | |
366 } | |
367 else if (openwith_gvim_path(popup_path)) | |
368 { | |
369 printf(" - the Vim \"Open With...\" entry in the popup menu\n"); | |
370 printf(" which uses \"%s\"\n", popup_path); | |
371 printf("\nRemove it (y/n)? "); | |
372 if (confirm()) | |
373 remove_openwith(); | |
374 } | |
375 | |
376 if (get_shell_folder_path(path, "desktop")) | |
377 { | |
378 printf("\n"); | |
379 for (i = 0; i < ICON_COUNT; ++i) | |
380 { | |
381 sprintf(icon, "%s\\%s", path, icon_link_names[i]); | |
382 if (stat(icon, &st) == 0) | |
383 { | |
384 printf(" - the \"%s\" icon on the desktop\n", icon_names[i]); | |
385 ++found; | |
386 } | |
387 } | |
388 if (found > 0) | |
389 { | |
390 if (interactive) | |
391 printf("\nRemove %s (y/n)? ", found > 1 ? "them" : "it"); | |
392 if (!interactive || confirm()) | |
393 remove_icons(); | |
394 } | |
395 } | |
396 | |
397 if (get_shell_folder_path(path, VIM_STARTMENU) | |
398 && stat(path, &st) == 0) | |
399 { | |
400 printf("\n - the \"%s\" entry in the Start Menu\n", VIM_STARTMENU); | |
401 if (interactive) | |
402 printf("\nRemove it (y/n)? "); | |
403 if (!interactive || confirm()) | |
404 remove_start_menu(); | |
405 } | |
406 #endif | |
407 | |
408 printf("\n"); | |
409 found = remove_batfiles(0); | |
410 if (found > 0) | |
411 { | |
412 if (interactive) | |
413 printf("\nRemove %s (y/n)? ", found > 1 ? "them" : "it"); | |
414 if (!interactive || confirm()) | |
415 remove_batfiles(1); | |
416 } | |
417 | |
418 fd = fopen("gvim.exe", "r"); | |
419 if (fd != NULL) | |
420 { | |
421 fclose(fd); | |
422 printf("gvim.exe detected. Attempting to unregister gvim with OLE\n"); | |
423 system("gvim.exe -silent -unregister"); | |
424 } | |
425 | |
426 delete_uninstall_key(); | |
427 | |
428 if (interactive) | |
429 { | |
430 printf("\nYou may now want to delete the Vim executables and runtime files.\n"); | |
431 printf("(They are still where you unpacked them.)\n"); | |
432 } | |
433 | |
2217
120502692d82
Improve the MS-Windows installer.
Bram Moolenaar <bram@vim.org>
parents:
7
diff
changeset
|
434 if (interactive) |
120502692d82
Improve the MS-Windows installer.
Bram Moolenaar <bram@vim.org>
parents:
7
diff
changeset
|
435 { |
120502692d82
Improve the MS-Windows installer.
Bram Moolenaar <bram@vim.org>
parents:
7
diff
changeset
|
436 rewind(stdin); |
120502692d82
Improve the MS-Windows installer.
Bram Moolenaar <bram@vim.org>
parents:
7
diff
changeset
|
437 printf("\nPress Enter to exit..."); |
120502692d82
Improve the MS-Windows installer.
Bram Moolenaar <bram@vim.org>
parents:
7
diff
changeset
|
438 (void)getchar(); |
120502692d82
Improve the MS-Windows installer.
Bram Moolenaar <bram@vim.org>
parents:
7
diff
changeset
|
439 } |
120502692d82
Improve the MS-Windows installer.
Bram Moolenaar <bram@vim.org>
parents:
7
diff
changeset
|
440 else |
120502692d82
Improve the MS-Windows installer.
Bram Moolenaar <bram@vim.org>
parents:
7
diff
changeset
|
441 Sleep(3000); |
7 | 442 |
443 return 0; | |
444 } |