Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 446 lines (396 sloc) 11.009 kb
e5c6ef7 updated for version 7.0001
vimboss authored
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. */
bd47321 Fix that uninstaller isn't found on 64-bit Windows.
Bram Moolenaar authored
49 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Vim\\Gvim", 0,
50 KEY_WOW64_64KEY | KEY_READ, &key_handle) != ERROR_SUCCESS)
e5c6ef7 updated for version 7.0001
vimboss authored
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,
bd47321 Fix that uninstaller isn't found on 64-bit Windows.
Bram Moolenaar authored
75 "Applications\\gvim.exe\\shell\\edit\\command", 0,
76 KEY_WOW64_64KEY | KEY_READ, &key_handle) != ERROR_SUCCESS)
e5c6ef7 updated for version 7.0001
vimboss authored
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;
bd47321 Fix that uninstaller isn't found on 64-bit Windows.
Bram Moolenaar authored
98 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved", 0,
99 KEY_WOW64_64KEY | KEY_ALL_ACCESS, &kh) != ERROR_SUCCESS)
e5c6ef7 updated for version 7.0001
vimboss authored
100 ++fail;
101 else
102 {
103 if (RegDeleteValue(kh, "{51EEE242-AD87-11d3-9C1E-0090278BBD99}") != ERROR_SUCCESS)
104 ++fail;
105 RegCloseKey(kh);
106 }
107 if (RegDeleteKey(HKEY_LOCAL_MACHINE, "Software\\Vim\\Gvim") != ERROR_SUCCESS)
108 ++fail;
109 if (RegDeleteKey(HKEY_LOCAL_MACHINE, "Software\\Vim") != ERROR_SUCCESS)
110 ++fail;
111
112 if (fail == 6)
113 printf("No Vim popup registry entries could be removed\n");
114 else if (fail > 0)
115 printf("Some Vim popup registry entries could not be removed\n");
116 else
117 printf("The Vim popup registry entries have been removed\n");
118 }
119
120 static void
121 remove_openwith(void)
122 {
123 int fail = 0;
124
125 if (RegDeleteKey(HKEY_CLASSES_ROOT, "Applications\\gvim.exe\\shell\\edit\\command") != ERROR_SUCCESS)
126 ++fail;
127 if (RegDeleteKey(HKEY_CLASSES_ROOT, "Applications\\gvim.exe\\shell\\edit") != ERROR_SUCCESS)
128 ++fail;
129 if (RegDeleteKey(HKEY_CLASSES_ROOT, "Applications\\gvim.exe\\shell") != ERROR_SUCCESS)
130 ++fail;
131 if (RegDeleteKey(HKEY_CLASSES_ROOT, "Applications\\gvim.exe") != ERROR_SUCCESS)
132 ++fail;
133 if (RegDeleteKey(HKEY_CLASSES_ROOT, ".htm\\OpenWithList\\gvim.exe") != ERROR_SUCCESS)
134 ++fail;
135 if (RegDeleteKey(HKEY_CLASSES_ROOT, ".vim\\OpenWithList\\gvim.exe") != ERROR_SUCCESS)
136 ++fail;
137 if (RegDeleteKey(HKEY_CLASSES_ROOT, "*\\OpenWithList\\gvim.exe") != ERROR_SUCCESS)
138 ++fail;
139
140 if (fail == 7)
141 printf("No Vim open-with registry entries could be removed\n");
142 else if (fail > 0)
143 printf("Some Vim open-with registry entries could not be removed\n");
144 else
145 printf("The Vim open-with registry entries have been removed\n");
146 }
147 #endif
148
149 /*
150 * Check if a batch file is really for the current version. Don't delete a
151 * batch file that was written for another (possibly newer) version.
152 */
153 static int
154 batfile_thisversion(char *path)
155 {
156 FILE *fd;
157 char line[BUFSIZE];
158 char *p;
159 int ver_len = strlen(VIM_VERSION_NODOT);
160 int found = FALSE;
161
162 fd = fopen(path, "r");
163 if (fd != NULL)
164 {
165 while (fgets(line, BUFSIZE, fd) != NULL)
166 {
167 for (p = line; *p != 0; ++p)
168 /* don't accept "vim60an" when looking for "vim60". */
169 if (strnicmp(p, VIM_VERSION_NODOT, ver_len) == 0
170 && !isdigit(p[ver_len])
171 && !isalpha(p[ver_len]))
172 {
173 found = TRUE;
174 break;
175 }
176 if (found)
177 break;
178 }
179 fclose(fd);
180 }
181 return found;
182 }
183
184 static int
185 remove_batfiles(int doit)
186 {
187 char *batfile_path;
188 int i;
189 int found = 0;
190
191 for (i = 1; i < TARGET_COUNT; ++i)
192 {
193 batfile_path = searchpath_save(targets[i].batname);
194 if (batfile_path != NULL && batfile_thisversion(batfile_path))
195 {
196 ++found;
197 if (doit)
198 {
199 printf("removing %s\n", batfile_path);
200 remove(batfile_path);
201 }
202 else
203 printf(" - the batch file %s\n", batfile_path);
204 free(batfile_path);
205 }
206 }
207 return found;
208 }
209
210 #ifdef WIN3264
211 static void
212 remove_if_exists(char *path, char *filename)
213 {
214 char buf[BUFSIZE];
215 FILE *fd;
216
217 sprintf(buf, "%s\\%s", path, filename);
218
219 fd = fopen(buf, "r");
220 if (fd != NULL)
221 {
222 fclose(fd);
223 printf("removing %s\n", buf);
224 remove(buf);
225 }
226 }
227
228 static void
229 remove_icons(void)
230 {
231 char path[BUFSIZE];
232 int i;
233
234 if (get_shell_folder_path(path, "desktop"))
235 for (i = 0; i < ICON_COUNT; ++i)
236 remove_if_exists(path, icon_link_names[i]);
237 }
238
239 static void
240 remove_start_menu(void)
241 {
242 char path[BUFSIZE];
243 int i;
244 struct stat st;
245
246 if (get_shell_folder_path(path, VIM_STARTMENU))
247 {
248 for (i = 1; i < TARGET_COUNT; ++i)
249 remove_if_exists(path, targets[i].lnkname);
250 remove_if_exists(path, "uninstall.lnk");
251 remove_if_exists(path, "Help.lnk");
252 /* Win95 uses .pif, WinNT uses .lnk */
253 remove_if_exists(path, "Vim tutor.pif");
254 remove_if_exists(path, "Vim tutor.lnk");
255 remove_if_exists(path, "Vim online.url");
256 if (stat(path, &st) == 0)
257 {
258 printf("removing %s\n", path);
259 rmdir(path);
260 }
261 }
262 }
263 #endif
264
265 #if 0 /* currently not used */
266 /*
267 * Return TRUE when we're on Windows 95/98/ME.
268 */
269 static int
270 win95(void)
271 {
272 static int done = FALSE;
273 static DWORD PlatformId;
274
275 if (!done)
276 {
277 OSVERSIONINFO ovi;
278
279 ovi.dwOSVersionInfoSize = sizeof(ovi);
280 GetVersionEx(&ovi);
281 PlatformId = ovi.dwPlatformId;
282 done = TRUE;
283 }
284 /* Win NT/2000/XP is VER_PLATFORM_WIN32_NT */
285 return PlatformId == VER_PLATFORM_WIN32_WINDOWS;
286 }
287 #endif
288
289 static void
290 delete_uninstall_key(void)
291 {
292 #ifdef WIN3264
293 RegDeleteKey(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Vim " VIM_VERSION_SHORT);
294 #else
295 FILE *fd;
296 char buf[BUFSIZE];
297
298 /*
299 * On DJGPP we delete registry entries by creating a .inf file and
300 * installing it.
301 */
302 fd = fopen("vim.inf", "w");
303 if (fd != NULL)
304 {
305 fprintf(fd, "[version]\n");
306 fprintf(fd, "signature=\"$CHICAGO$\"\n\n");
307 fprintf(fd, "[DefaultInstall]\n");
308 fprintf(fd, "DelReg=DeleteMe\n\n");
309 fprintf(fd, "[DeleteMe]\n");
310 fprintf(fd, "HKLM,\"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Vim " VIM_VERSION_SHORT "\"\n");
311 fclose(fd);
312
313 /* Don't know how to detect Win NT with DJGPP. Hack: Just try the Win
314 * 95/98/ME method, since the DJGPP version can't use long filenames
315 * on Win NT anyway. */
316 sprintf(buf, "rundll setupx.dll,InstallHinfSection DefaultInstall 132 %s\\vim.inf", installdir);
317 run_command(buf);
318 #if 0
319 /* Windows NT method (untested). */
320 sprintf(buf, "rundll32 syssetup,SetupInfObjectInstallAction DefaultInstall 128 %s\\vim.inf", installdir);
321 run_command(buf);
322 #endif
323
324 remove("vim.inf");
325 }
326 #endif
327 }
328
329 int
330 main(int argc, char *argv[])
331 {
332 int found = 0;
333 FILE *fd;
334 #ifdef WIN3264
335 int i;
336 struct stat st;
337 char icon[BUFSIZE];
338 char path[BUFSIZE];
339 char popup_path[BUFSIZE];
340
341 /* The nsis uninstaller calls us with a "-nsis" argument. */
342 if (argc == 2 && stricmp(argv[1], "-nsis") == 0)
343 interactive = FALSE;
344 else
345 #endif
346 interactive = TRUE;
347
348 /* Initialize this program. */
349 do_inits(argv);
350
351 printf("This program will remove the following items:\n");
352
353 #ifdef WIN3264
354 if (popup_gvim_path(popup_path))
355 {
356 printf(" - the \"Edit with Vim\" entry in the popup menu\n");
357 printf(" which uses \"%s\"\n", popup_path);
3859400 Improve the MS-Windows installer.
Bram Moolenaar authored
358 if (interactive)
359 printf("\nRemove it (y/n)? ");
360 if (!interactive || confirm())
e5c6ef7 updated for version 7.0001
vimboss authored
361 {
362 remove_popup();
363 /* Assume the "Open With" entry can be removed as well, don't
364 * bother the user with asking him again. */
365 remove_openwith();
366 }
367 }
368 else if (openwith_gvim_path(popup_path))
369 {
370 printf(" - the Vim \"Open With...\" entry in the popup menu\n");
371 printf(" which uses \"%s\"\n", popup_path);
372 printf("\nRemove it (y/n)? ");
373 if (confirm())
374 remove_openwith();
375 }
376
377 if (get_shell_folder_path(path, "desktop"))
378 {
379 printf("\n");
380 for (i = 0; i < ICON_COUNT; ++i)
381 {
382 sprintf(icon, "%s\\%s", path, icon_link_names[i]);
383 if (stat(icon, &st) == 0)
384 {
385 printf(" - the \"%s\" icon on the desktop\n", icon_names[i]);
386 ++found;
387 }
388 }
389 if (found > 0)
390 {
391 if (interactive)
392 printf("\nRemove %s (y/n)? ", found > 1 ? "them" : "it");
393 if (!interactive || confirm())
394 remove_icons();
395 }
396 }
397
398 if (get_shell_folder_path(path, VIM_STARTMENU)
399 && stat(path, &st) == 0)
400 {
401 printf("\n - the \"%s\" entry in the Start Menu\n", VIM_STARTMENU);
402 if (interactive)
403 printf("\nRemove it (y/n)? ");
404 if (!interactive || confirm())
405 remove_start_menu();
406 }
407 #endif
408
409 printf("\n");
410 found = remove_batfiles(0);
411 if (found > 0)
412 {
413 if (interactive)
414 printf("\nRemove %s (y/n)? ", found > 1 ? "them" : "it");
415 if (!interactive || confirm())
416 remove_batfiles(1);
417 }
418
419 fd = fopen("gvim.exe", "r");
420 if (fd != NULL)
421 {
422 fclose(fd);
423 printf("gvim.exe detected. Attempting to unregister gvim with OLE\n");
424 system("gvim.exe -silent -unregister");
425 }
426
427 delete_uninstall_key();
428
429 if (interactive)
430 {
431 printf("\nYou may now want to delete the Vim executables and runtime files.\n");
432 printf("(They are still where you unpacked them.)\n");
433 }
434
3859400 Improve the MS-Windows installer.
Bram Moolenaar authored
435 if (interactive)
436 {
437 rewind(stdin);
438 printf("\nPress Enter to exit...");
439 (void)getchar();
440 }
441 else
36e9390 Make the dos installer work with more compilers.
Bram Moolenaar authored
442 sleep(3);
e5c6ef7 updated for version 7.0001
vimboss authored
443
444 return 0;
445 }
Something went wrong with that request. Please try again.