1/* Add entries to the GNU Emacs Program Manager folder. 2 Copyright (C) 1995, 2001, 2002, 2003, 2004, 2005, 3 2006, 2007 Free Software Foundation, Inc. 4 5This file is part of GNU Emacs. 6 7GNU Emacs is free software; you can redistribute it and/or modify 8it under the terms of the GNU General Public License as published by 9the Free Software Foundation; either version 2, or (at your option) 10any later version. 11 12GNU Emacs is distributed in the hope that it will be useful, 13but WITHOUT ANY WARRANTY; without even the implied warranty of 14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15GNU General Public License for more details. 16 17You should have received a copy of the GNU General Public License 18along with GNU Emacs; see the file COPYING. If not, write to 19the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 20Boston, MA 02110-1301, USA. */ 21 22/**************************************************************************** 23 * 24 * Program: addpm (adds emacs to the Windows program manager) 25 * 26 * Usage: 27 * argv[1] = install path for emacs 28 * argv[2] = full path to icon for emacs (optional) 29 */ 30 31#include <windows.h> 32#include <ddeml.h> 33#include <stdlib.h> 34#include <stdio.h> 35 36HDDEDATA CALLBACK 37DdeCallback (UINT uType, UINT uFmt, HCONV hconv, 38 HSZ hsz1, HSZ hsz2, HDDEDATA hdata, 39 DWORD dwData1, DWORD dwData2) 40{ 41 return ((HDDEDATA) NULL); 42} 43 44#define DdeCommand(str) \ 45 DdeClientTransaction (str, strlen (str)+1, HConversation, (HSZ)NULL, \ 46 CF_TEXT, XTYP_EXECUTE, 30000, NULL) 47 48#define REG_ROOT "SOFTWARE\\GNU\\Emacs" 49 50static struct entry 51{ 52 char *name; 53 char *value; 54} 55env_vars[] = 56{ 57 {"emacs_dir", NULL}, 58 {"EMACSLOADPATH", "%emacs_dir%/site-lisp;%emacs_dir%/../site-lisp;%emacs_dir%/lisp;%emacs_dir%/leim"}, 59 {"SHELL", "%emacs_dir%/bin/cmdproxy.exe"}, 60 {"EMACSDATA", "%emacs_dir%/etc"}, 61 {"EMACSPATH", "%emacs_dir%/bin"}, 62 /* We no longer set INFOPATH because Info-default-directory-list 63 is then ignored. */ 64 /* {"INFOPATH", "%emacs_dir%/info"}, */ 65 {"EMACSDOC", "%emacs_dir%/etc"}, 66 {"TERM", "cmd"} 67}; 68 69BOOL 70add_registry (path) 71 char *path; 72{ 73 HKEY hrootkey = NULL; 74 int i; 75 BOOL ok = TRUE; 76 77 /* Previous versions relied on registry settings, but we do not need 78 them any more. If registry settings are installed from a previous 79 version, replace them to ensure they are the current settings. 80 Otherwise, do nothing. */ 81 82 /* Check both the current user and the local machine to see if we 83 have any resources. */ 84 85 if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, REG_ROOT, 86 REG_OPTION_NON_VOLATILE, 87 KEY_WRITE, &hrootkey) != ERROR_SUCCESS 88 && RegOpenKeyEx (HKEY_CURRENT_USER, REG_ROOT, 89 REG_OPTION_NON_VOLATILE, 90 KEY_WRITE, &hrootkey) != ERROR_SUCCESS) 91 { 92 return FALSE; 93 } 94 95 for (i = 0; i < (sizeof (env_vars) / sizeof (env_vars[0])); i++) 96 { 97 char * value = env_vars[i].value ? env_vars[i].value : path; 98 99 if (RegSetValueEx (hrootkey, env_vars[i].name, 100 0, REG_EXPAND_SZ, 101 value, lstrlen (value) + 1) != ERROR_SUCCESS) 102 ok = FALSE; 103 } 104 105 RegCloseKey (hrootkey); 106 107 return (ok); 108} 109 110int 111main (argc, argv) 112 int argc; 113 char *argv[]; 114{ 115 DWORD idDde = 0; 116 HCONV HConversation; 117 HSZ ProgMan; 118 char modname[MAX_PATH]; 119 char additem[MAX_PATH*2 + 100]; 120 char *prog_name; 121 char *emacs_path; 122 char *p; 123 int quiet = 0; 124 125 /* If no args specified, use our location to set emacs_path. */ 126#if 0 127 if (argc < 2 || argc > 3) 128 { 129 fprintf (stderr, "usage: addpm [-q] [emacs_path [icon_path]]\n"); 130 exit (1); 131 } 132#endif 133 134 if (argc > 1 135 && (argv[1][0] == '/' || argv[1][0] == '-') 136 && argv[1][1] == 'q') 137 { 138 quiet = 1; 139 --argc; 140 ++argv; 141 } 142 143 if (argc > 1) 144 emacs_path = argv[1]; 145 else 146 { 147 if (!GetModuleFileName (NULL, modname, MAX_PATH) || 148 (p = strrchr (modname, '\\')) == NULL) 149 { 150 fprintf (stderr, "fatal error"); 151 exit (1); 152 } 153 *p = 0; 154 155 /* Set emacs_path to emacs_dir if we are in "%emacs_dir%\bin". */ 156 if ((p = strrchr (modname, '\\')) && stricmp (p, "\\bin") == 0) 157 { 158 *p = 0; 159 emacs_path = modname; 160 } 161 else 162 { 163 fprintf (stderr, "usage: addpm emacs_path [icon_path]\n"); 164 exit (1); 165 } 166 167 /* Tell user what we are going to do. */ 168 if (!quiet) 169 { 170 int result; 171 172 char msg[ MAX_PATH ]; 173 sprintf (msg, "Install Emacs at %s?\n", emacs_path); 174 result = MessageBox (NULL, msg, "Install Emacs", 175 MB_OKCANCEL | MB_ICONQUESTION); 176 if (result != IDOK) 177 { 178 fprintf (stderr, "Install cancelled\n"); 179 exit (1); 180 } 181 } 182 } 183 184 add_registry (emacs_path); 185 prog_name = "runemacs.exe"; 186 187 DdeInitialize (&idDde, (PFNCALLBACK)DdeCallback, APPCMD_CLIENTONLY, 0); 188 189 ProgMan = DdeCreateStringHandle (idDde, "PROGMAN", CP_WINANSI); 190 191 HConversation = DdeConnect (idDde, ProgMan, ProgMan, NULL); 192 if (HConversation != 0) 193 { 194 DdeCommand ("[CreateGroup (\"Gnu Emacs\")]"); 195 DdeCommand ("[ReplaceItem (Emacs)]"); 196 if (argc > 2) 197 sprintf (additem, "[AddItem (\"%s\\bin\\%s\", Emacs, \"%s\")]", 198 emacs_path, prog_name, argv[2]); 199 else 200 sprintf (additem, "[AddItem (\"%s\\bin\\%s\", Emacs)]", 201 emacs_path, prog_name); 202 DdeCommand (additem); 203 204 DdeDisconnect (HConversation); 205 } 206 207 DdeFreeStringHandle (idDde, ProgMan); 208 209 DdeUninitialize (idDde); 210 211 return (0); 212} 213 214/* arch-tag: f923609d-b781-4ef4-abce-ca0da29cbbf0 215 (do not change this comment) */ 216