Open with emacs.exe

In Windows Vista and later, it's not possible to associate file types with programs that are not located in certain standard program folders, such as the Program Files folder. If it is desired to associate file types with GNU Emacs, it is possible to do a workaround on this problem. One can instead make a program that works as a middle hand, which with the file types are associated instead. The program, once started, opens Emacs, passing it the same arguments (except the first one which is the search path to the program) as it got itself. The program should be located in one of the standard program folders (for example Program Files), and to make it able to find Emacs, it is necessary that the address of the bin folder in the Emacs directory is added to the system path.

Example files
Here is an example of such a program. The code is written in C.

main.c:
 * 1) include 
 * 2) include 


 * 1) define WAIT_FOR_PROCESS  0 /* If the program should wait for runemacs to finish or not */

ptr = malloc(sizeof(*ptr)*number);                     \ if (!ptr) {                                            \ MessageBoxA(0, "Not enough memory\n"               \                        "Trying to allocate memory for\n"       \                        #number " number of elements to\n"      \                        #ptr, "open_with_emacs",                \                        MB_ICONERROR);                          \ exit(1);                                           \ }                                                      \    }
 * 1) define MALLOC_NUM(ptr, number) {                              \

int main(int argc, char **argv) { const char* app = "runemacs"; const unsigned int app_name_length = strlen(app); char *curr_cl, *new_cl; /* Current and new command line */ /* For creating the process */ STARTUPINFO         si = {sizeof(si)}; PROCESS_INFORMATION pi;

/* Find arguments */ curr_cl = GetCommandLine; if (argc >= 1) { if     (*curr_cl == '"' ) curr_cl += strlen(argv[0]) + 2;        else if (*curr_cl != '\0') curr_cl += strlen(argv[0]);    }    /* Create new command line */    MALLOC_NUM(new_cl, app_name_length + strlen(curr_cl) + 1);    strcpy(new_cl, app);    strcpy(new_cl + app_name_length, curr_cl);    /* Run command line */    if (CreateProcessA(0, /* lpApplicationName, optional */                       new_cl, /* lpCommandLine, The command line to be executed */                       0, /* lpProcessAttributes */                       0, /* lpThreadAttributes */                       0, /* bInheritHandles */                       0, /* dwCreationFlags */                       0, /* lpEnvironment */                       0, /* lpCurrentDirectory */                       &si, /* lpStartupInfo */                       &pi  /* lpProcessInformation, receiving process id information */                       )) {       /* optionally wait for process to finish */ WaitForSingleObject(pi.hProcess, INFINITE); /* Closing handles is completely safe */ CloseHandle(pi.hProcess); CloseHandle(pi.hThread); }   else {       /* Display error code */ const char *message_base = "Couldn't create the process runemacs\n\nError code: "; const unsigned int message_base_length = strlen(message_base); const int max_code_lentgh = 10; char code[max_code_lentgh + 1]; /* Required number of chars to hold "4294967295", max of DWORD */ char message[message_base_length + max_code_lentgh + 1]; DWORD error_code = GetLastError; DWORD temp_error_code = error_code; int i;       for (i = 0; temp_error_code; i++) {           temp_error_code /= 10; }       i += !i; code[i] = '\0'; for (i; i--) {           temp_error_code = error_code/10; code[i-1] = '0' + error_code - temp_error_code*10; error_code = temp_error_code; }       strcpy(message, message_base); strcpy(message + message_base_length, code); MessageBoxA(0, message, "open_with_emacs", MB_ICONERROR); }
 * 1) if WAIT_FOR_PROCESS
 * 1) endif

free(new_cl); return 0; }

By using this Makefile, no console window will show, making the program invisible to the user. Requires compilation with MinGW and MSYS.

Makefile: CC=gcc CCFLAGS=-std=c99 CCFLAGS+=-Wall -Wextra -pedantic -g CCFLAGS+=-lmingw32 CCFLAGS+=-Wl,--subsystem,windows #Can sometimes be replaced with -mwindows FILES=main.x SRC=$(FILES:.x=.c) OBJ=$(FILES:.x=.o) OUT=open_with_emacs.exe

all: $(OUT) rm $(OBJ) #Remove .o files

$(OBJ) : $(CC) $(SRC) $(CCFLAGS) -c #Create .o files

$(OUT) : $(OBJ) $(CC) $(OBJ) $(CCFLAGS) -o $@ #Link .o files

Since the compilation is invoked by the make command, the files main.c and Makefile have to be located in the same folder.