19

I am trying to set up the emacs server daemon and use emacsclient on MS Windows so that files can be opened quickly without the delay and overhead associated with starting additional instances of emacs for each file opened. I am following the specific instructions provided in emacswiki for MS Windows which involves:

  1. Running emacs as a daemon, runemacs.exe --daemon
  2. Followed by invoking emacsclientw.exe with the appropriate options.

Starting the daemon succeeds (I see emacs.exe in the process list), but invoking emacsclient produces errors. The wiki says to create a shortcut to emacsclientw.exe and change the target to

X:\path\to\emacs\bin\emacsclientw.exe -na "X:\path\to\emacs\bin\emacsclientw.exe" -c -n

Is this correct? It looks like the client is invoked twice. Using the target as shown does not run the program and produces the error "file name or argument required". Using only the first part of the target shown above

X:\path\to\emacs\bin\emacsclientw.exe -na

produces a generic error. Using only the second part

X:\path\to\emacs\bin\emacsclientw.exe -c -n

produces the error "No socket or alternate editor." (The official emacsclient options are described here.)

Any suggestions? Emacs runs fine in standard mode, that is, not in daemon mode. Version 25.1. I would prefer to run the daemon rather than starting the server in my initialization file.

Snelephant
  • 814
  • 1
  • 7
  • 17

7 Answers7

12

I am not so sure about the advice in the emacswiki page. What you want to do is to the following:

  • Launch an emacs client connected to the running emacs server.
  • If the emacs server is not running, start it, and then connect the emacs client.
  • Don't wait for the client to finish (if you're starting from a command line).

The command I use is

C:\emacs\bin\emacsclientw.exe -n -c -a ""

The -n means don't wait for the client to finish when you're launching from command line. The -a allows you to specify an alternative editor if the emacs server isn't running, but if you give it an empty string, it will try to start the emacs server and connect to it. Finally, if you're putting this in a windows shortcut, you want to also add a -c which will open a new frame (see emacsclient options).

Here's my shortcut, it works for me (on windows 7, emacs 25.3). I don't know why the emacswiki page put another invocation of emacsclientw as the alternative editor that makes no sense.

I should add that when I try to omit the -c option when running as a shortcut, it gives an error.

emacsclientw shortcut

Angelo
  • 271
  • 2
  • 9
  • 2
    Configuring the emacsclientw.exe shortcut in the way shown produces: `Error: Cannot connect even after starting the Emacs daemon` Confirmed this shortcut does launch the daemon process, but files still open in their own emacs instance. Tested with and without administrator priveleges. Emacs 25.1, Windows 7. – Snelephant Feb 04 '18 at 01:14
  • 1
    @Snelephant, hmm, I don't know what could be wrong. I even downgraded to emacs 25.1 and my shortcut still worked. How are you opening files through a context menu or with the command in the shortcut followed by the filename? – Angelo Feb 04 '18 at 14:07
  • The error occurs both when I click the shortcut to emacsclientw.exe itself with no file specified and when I click a shortcut to a text file with the emacsclientw.exe and file name specified in the Target field. Actually, I am not clear on the intended method for opening files into the client on Windows? I would like to just click the file in Windows Explorer. Clicking a file in OSX seems to open the file in an existing instance, but clicking a file in Windows creates a separate instance. Note I have configured Windows to open text files using the runemacs.exe provided with emacs. – Snelephant Feb 05 '18 at 02:39
  • If you have configured Windows to open text files with runemacs.exe, then they will open in separate Emacs processes. You'd want to change that association to use emacsclientw instead. – glucas Jun 01 '18 at 05:03
  • 1
    @glucas Changed text file associations to the shortcut to emacsclientw.exe as Angelo described. Clicking a text file produces the same `Error: Cannot connect even after starting the Emacs daemon`. – Snelephant Jun 13 '18 at 17:56
3

For Emacs 26.3 and Windows 10 works:

Daemon: C:\YOUR_EMACS\emacs-26.3\bin\emacs.exe "--daemon"

Client: e.g: C:\YOUR_EMACS\emacs-26.3\bin\emacsclientw.exe "temp.org"

When you add Emacs executable into PATH, you can easily open emacsclientw.exe from anywhere. Also you can add daemon in startup folder: C:\Windows\System32\cmd.exe /c start /high emacs.exe "--daemon"

Stefan
  • 26,154
  • 3
  • 46
  • 84
Michal
  • 31
  • 1
  • 1
    Thank you so much this worked great for me when nothing else seemed like it was. I will also say I had to create a shortcut for the client to actually launch it. For some reason `emacsclientw.exe "temp.org"` wasn't working from the cmd line with my emacs config. That said with _no_ config it did work to launch from the cmd line like that. :/ – nmu Aug 13 '20 at 13:00
2

The command I use is:

emacsclientw.exe --create-frame --no-wait --alternate-editor runemacs.exe --server-file %APPDATA%\.emacs.d\server\server

(If the Emacs bin folder is not on your PATH, use the full paths for emacsclientw.exe and runemacs.exe.)

or with the short option names and the empty string trick,

emacsclientw.exe -c -n -a "" -f %APPDATA%\.emacs.d\server\server

Note that the empty string trick for -a will start the daemon if it isn't running, but this isn't supposed work until Emacs 26 (I'm still on 25). Before 26 you have to specify the alternative editor explicitly. I used runemacs.exe, but my Emacs is configured to start the server and leave it running.

Because Windows lacks the local Unix domain sockets emacsclient normally would have used to connect to the server, it has to fall back to using a network TCP socket. For obvious security reasons, you don't want just anyone on your network to access your whole file system via the Emacs server. Thus, emacsclient must know the right (ephemeral) port and security token written in the server file before the server will allow it to connect.

If the server is already running, then you shouldn't need the -a (but it doesn't hurt). You could set the ALTERNATE_EDITOR environment variable instead of using -a.

If you set the EMACS_SERVER_FILE environment variable, then you don't need to specify it again with -f.

gilch
  • 121
  • 3
2

I encountered the connection problem too. And I try to fix it by the steps below.

  1. Checks if the environment variable EMACS_SERVER_FILE exists.

    • A. If the variable exists, go to step 2
    • B. If not, go to step 5
  2. Checks if the EMACS_SERVER_FILE pointed file exists. It is normally %USERPROFILE%\.emacs.d\server\server.

    • A. If it exists, remove it and go to step 3
    • B. If not, go to step 5
  3. Closes all Emacs processes and run emacs --daemon in the cmd or PowerShell. Checks if EMACS_SERVER_FILE file generates.

    • A. If the file generates, go to step 4
    • B. If not, go to step 5
  4. Uses this command emacsclientw -c -n -a= to connect the server and cross your fingers.

    • A. If it can connect to the server, congratulations to you.
    • B. If not, go to step 5.
  5. Uses a file search tool to monitor all server files on your machine. I'm using Everything to monitor files with this filter regex:^server$ ext:. Keep the search results on top. Then close all Emacs processes and rerun emacs --daemon.

    • A. If the search results doesn't change, go to step 6
    • B. If the results changes, find out changed one and set its path as EMACS_SERVER_FILE, redo step 4 to see if the problem solves
  6. Uses emacs --daemon --debug-init to enable Emacs Lisp debugger for init file. See the printed logs and figure out which one causes the server down.

This picture is the search results on my machine: the search results on my machine

In my machine, the reason causes the connection problem is the EMACS_SERVER_FILE pointed file does not the actual used file.

Hopefully, my course of debugging can help you fix it.

Pagliacii
  • 21
  • 2
  • It took me a while to find that darn `server` file too! In the end, on Emacs 27 and Windows 7, I found it in `C:\path\to\emacs\.emacs.d\.local\etc\server\server`. After I set `EMACS_SERVER_FILE` to this (AND restarted my machine), everything worked okay. – Steve Eynon Jun 11 '21 at 08:49
1

Create a client shortcut on the Desktop

Emacs ships with several executables for Windows. The emacsclientw.exe binary is used to connect to a running Emacs server (i.e. daemon).

  1. Create a shortcut to the client executable.

Right click on the desktop and select "Shortcut".

create shortcut

  1. Define the client shortcut.

Set Target: as C:\path\to\emacsclientw.exe -n -c --a "".

make the target C:\path\to\emacsclientw.exe -n -c --a ""

This creates a new frame (-c) without waiting for the server to respond (-n). It has an EDITOR fallback (-a) that is blank which means Emacs will try to start Emacs in daemon mode on failure before trying to connect again.

Use the "Start in" field to define where the default-directory should be. Note, this may be somewhere different from where your init.el lives. The "Start in" field defines what directory shows up when you go to find a file (M-x find-file).

I also like to define a shortcut key in order to open new client frames.

Windows startup script for starting the server

  1. Goto the startup folder.

This can be done with shell:startup in File Explorer:

goto shell:startup

  1. Create a new text file.

Right click in the folder and select "New > Text Document".

create text file

  1. Change the text file to a batch file.

Right click or press F2 to rename the file as a .bat (e.g. StartEmacsServer.bat).

make it a .bat batch file

  1. Define the script.

Put the following code into the batch file.

rem Sets HOME for current shell
set HOME=%APPDATA%

rem Clean previous server file info first
del /q ""%HOME%\\.emacs.d\\server\\*""

rem Start the Emacs daemon/server with HOME as the default directory
C:\path\to\bin\runemacs.exe --daemon

rem Open a client frame
start "" "C:\Users\%USERNAME%\Desktop\emacsclientw.exe - Shortcut.lnk"

REM (for "remark") is a comment describing the next command.

First, we define an environment variable HOME. The GNU/Linux equivalent to "HOME" is something like "My Documents" or "AppData\Roaming". Since HOME doesn't exist on Windows systems and Emacs kind of expects it (or is more friendly when it's defined), we call set to define it in whatever shell instance runs the batch file. The variable %APPDATA% expands to something like "C:\Users<username>\AppData\Roaming". This is typically where the .emacs.d directory lives (or at least where I keep mine).

Next, we clear out any old data from previous runs. Emacs stores server/daemon data in the .emacs.d directory. The del command removes any copies that may exist.

Another executable shipped with Emacs is runemacs.exe. This runs a standalone Emacs instance. Here Emacs is started as a server (--daemon). Since HOME was just defined, the Emacs daemon will read the init.el from that location.

Finally, we call the client shortcut that we previously created.

All together, when Windows starts up, the Emacs server will spin up automatically and, once up, a new frame will appear (eventually. Windows is slow).

Server startup shortcut

  1. Create a shortcut to the server startup script.

I like to create a shortcut to the server startup script. This is useful when I want to have a clean server instance. I kill the server with something like my-suicide, then can click the shortcut to get the server going.

(defun my-suicide ()
  "Kill all Emacs processes."
  (interactive)
  (let ((cmd "taskkill /f /fi \"IMAGENAME eq emacs.exe\" /fi \"MEMUSAGE gt 15000\""))
    (shell-command cmd)))

create a shortcut to the server shortcut

Lorem Ipsum
  • 4,327
  • 2
  • 14
  • 35
0

Two steps are necessary:

1. Emacs.vbs

Create Emacs.vbs, content:

Set objShell = WScript.CreateObject("WScript.Shell")
objShell.Run "cmd /c emacs --daemon", 0, True 

Open autostart folder (Win + R, type shell:startup RET) and put Emacs.vbs into it.

2. Emacsclientw.bat

Create Emacsclientw.bat, content:

@echo off
start /b emacsclientw.exe -c -a ""
exit

Safe somewhere, create link, move link to desktop.

After next reboot plus a few seconds, doubleclick on link, here you are.

Works on Win 8.1.

I found the code of Emacs.vbs somewhere, but lost the link.

Keks Dose
  • 508
  • 4
  • 19
0

I have go through the same trouble when setting up Emacs server-mode on Windows. Here's some tips:

  1. Check if you can start server-mode in normal instance

    You can start a non-server mode Emacs instance, then use M-x server-mode to check if you could start a server daemon.

    If success, use M-x server-force-delete to remove that daemon. A message will prompt in mini-buffer where your server file path was. You can re-read it in Message buffer by C-x b *Messages*.

    If failed, Emacs should prompt you the path to server file is not secure, because the directory is not owned by your account. In this case, find the path from Message buffer, then use file property to change owner of that folder and try to start server-mode again.

    Default folder holding server file is:

    %AppData%\.emacs.d\server

    Use explorer to locate the folder, right click -> property -> security tab -> advance... -> change ownership (in front of the tabs). In popup windows, click advance then search for existing account on your computer, and select your normal user account.

  2. Start server-mode with a batch file

    Create a start.bat file, put the following command in that file:

    start runemacs --daemon

    This assumes runemacs is on your PATH environment variable. You can check it by directly launch runemacs from Windows Run [Win+r]. If failed, search PATH in windows search, then add the path to runemacs into user's PATH variable.

  3. Add a service to launch that batch file

    Start a command / PowerShell in Administrator's privilege:

    sc create "Emacs Server" binPath= "path/to/start.bat" type= share start= delayed-auto

    This will create an auto start service for current user, which start a Emacs's server after user login.

  4. Setup other user variable

    Now try emacsclient -c to see if you can connect to your server. If failed and prompt you to set EMACS_SERVER_FILE variable, create a new user variable:

    variable name: EMACS_SERVER_FILE value: path/to/server_file

    If you forgot your server file path, use M-x server-force-kill to check the Message buffer.