This seems to work, and is fully compatible with the start.exe in windows. The double-spacing in the usage message goes away if you apply my wrc patch. Not so sure if I got the internationalization right, but that can be fixed up later. Any options people miss from cygstart can also be added later; I just did the ones from windows start (plus /L to display the license, per the LGPL). Changelog: * programs/start/*: added * programs/Makefile.in: added 'start' (but don't install symlink) * winedefault.reg: .txt files handled by notepad * configure.ac: added programs/start/Makefile * tools/wineinstall: install 'start' in windows\command Copyright 2003, Dan Kegel. LGPL. -- Dan Kegel http://www.kegel.com http://counter.li.org/cgi-bin/runscript/display-person.cgi?user=78045
Index: configure.ac =================================================================== RCS file: /home/wine/wine/configure.ac,v retrieving revision 1.122 diff -u -r1.122 configure.ac --- configure.ac 15 Jan 2003 00:50:48 -0000 1.122 +++ configure.ac 18 Jan 2003 08:11:26 -0000 @@ -1519,6 +1519,7 @@ programs/regtest/Makefile programs/rpcss/Makefile programs/rundll32/Makefile +programs/start/Makefile programs/uninstaller/Makefile programs/view/Makefile programs/wcmd/Makefile Index: winedefault.reg =================================================================== RCS file: /home/wine/wine/winedefault.reg,v retrieving revision 1.61 diff -u -r1.61 winedefault.reg --- winedefault.reg 19 Dec 2002 21:16:56 -0000 1.61 +++ winedefault.reg 18 Jan 2003 08:11:26 -0000 @@ -2838,3 +2838,18 @@ "LongDistanceRule"=" 8WFG" "Name"="Uzbekistan" "SameAreaRule"="G" + +# +# Entries to get ShellExecute to map .txt files to notepad +# + +[HKEY_CLASSES_ROOT\.txt] +@="txtfile" +"Content Type"="text/plain" + +[HKEY_CLASSES_ROOT\txtfile\shell\open\command] +@="C:\\WINDOWS\\NOTEPAD.EXE %1" + +[HKEY_CLASSES_ROOT\txtfile\shell\print\command] +@="C:\\WINDOWS\\NOTEPAD.EXE /p %1" + Index: programs/Makefile.in =================================================================== RCS file: /home/wine/wine/programs/Makefile.in,v retrieving revision 1.33 diff -u -r1.33 Makefile.in --- programs/Makefile.in 4 Jan 2003 02:52:05 -0000 1.33 +++ programs/Makefile.in 18 Jan 2003 08:11:26 -0000 @@ -19,6 +19,7 @@ regtest \ rpcss \ rundll32 \ + start \ uninstaller \ view \ wcmd \ @@ -43,6 +44,7 @@ regsvr32 \ rpcss \ rundll32 \ + start \ uninstaller \ wcmd \ wineboot \ @@ -73,6 +75,7 @@ # Symlinks to apps that we want to run from inside the source tree SYMLINKS = \ + start.exe \ rpcss.exe \ wcmd.exe \ wineconsole.exe \ @@ -136,6 +139,9 @@ winhelp.exe$(DLLEXT): winhelp/winhelp.exe$(DLLEXT) $(RM) $@ && $(LN_S) winhelp/winhelp.exe$(DLLEXT) $@ + +start.exe$(DLLEXT): start/start.exe$(DLLEXT) + $(RM) $@ && $(LN_S) start/start.exe$(DLLEXT) $@ wcmd/wcmd.exe$(DLLEXT): wcmd wineconsole/wineconsole.exe$(DLLEXT): wineconsole Index: tools/wineinstall =================================================================== RCS file: /home/wine/wine/tools/wineinstall,v retrieving revision 1.50 diff -u -r1.50 wineinstall --- tools/wineinstall 5 Dec 2002 19:05:44 -0000 1.50 +++ tools/wineinstall 18 Jan 2003 08:11:26 -0000 @@ -101,6 +101,7 @@ function create_windows_directories { for tdir in "$CROOT/windows" "$CROOT/windows/system" \ + "$CROOT/windows/command" \ "$CROOT/windows/Start Menu" "$CROOT/windows/Start Menu/Programs" \ "$CROOT/Program Files" "$CROOT/Program Files/Common Files" \ "$CROOT/windows/Profiles" "$CROOT/windows/Profiles/Administrator" \ @@ -129,6 +130,7 @@ #puts windows applications replacements to windows directories, #configures them function configure_wine_applications { + link_app start "$CROOT/windows/command/start.exe" link_app notepad "$CROOT/windows/notepad.exe" link_app regedit "$CROOT/windows/regedit.exe" link_app rundll32 "$CROOT/windows/rundll32.exe" --- /dev/null 2002-08-30 16:31:37.000000000 -0700 +++ programs/start/Makefile.in 2003-01-17 23:25:49.000000000 -0800 @@ -0,0 +1,15 @@ +TOPSRCDIR = @top_srcdir@ +TOPOBJDIR = ../.. +SRCDIR = @srcdir@ +VPATH = @srcdir@ +MODULE = start.exe +APPMODE = cui +IMPORTS = shell32 user32 + +C_SRCS = start.c + +RC_SRCS = rsrc.rc + +@MAKE_PROG_RULES@ + +### Dependencies: --- /dev/null 2002-08-30 16:31:37.000000000 -0700 +++ programs/start/start.c 2003-01-18 00:04:53.000000000 -0800 @@ -0,0 +1,190 @@ +/* + * Start a program using ShellExecuteEx, optionally wait for it to finish + * Compatible with Microsoft's "c:\windows\command\start.exe" + * + * Copyright 2003 Dan Kegel + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <windows.h> +#include <winuser.h> +#include <stdio.h> +#include <stdlib.h> +#include <shlobj.h> + +#include "resources.h" + +/** + Output given message to stdout without formatting. +*/ +static void output(const char *message) +{ + DWORD count; + WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), message, strlen(message), &count, NULL); +} + +/** + Output given message, + followed by ": ", + followed by description of given GetLastError() value to stdout, + followed by a trailing newline, + then terminate. +*/ +static void fatal_error(const char *msg, DWORD error_code) +{ + LPVOID lpMsgBuf; + int status; + + output(msg); + output(": "); + status = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, error_code, 0, (LPTSTR) & lpMsgBuf, 0, NULL); + if (!status) { + output("FormatMessage failed\n"); + } else { + output(lpMsgBuf); + LocalFree((HLOCAL) lpMsgBuf); + output("\n"); + } + ExitProcess(1); +} + +/** + Output given message from string table, + followed by ": ", + followed by description of given GetLastError() value to stdout, + followed by a trailing newline, + then terminate. +*/ +static void fatal_string_error(int which, DWORD error_code) +{ + char msg[2048]; + + if (!LoadString(GetModuleHandle(NULL), which, + msg, sizeof(msg))) + fatal_error("LoadString failed", GetLastError()); + + fatal_error(msg, error_code); +} + +static void fatal_string(int which) +{ + char msg[2048]; + + if (!LoadString(GetModuleHandle(NULL), which, + msg, sizeof(msg))) + fatal_error("LoadString failed", GetLastError()); + + output(msg); + ExitProcess(1); +} + +static void usage() +{ + fatal_string(STRING_USAGE); +} + +static void license() +{ + fatal_string(STRING_LICENSE); +} + +int main(int argc, char *argv[]) +{ + char arguments[MAX_PATH]; + char *p; + SHELLEXECUTEINFO sei; + int argi; + + memset(&sei, 0, sizeof(sei)); + sei.cbSize = sizeof(sei); + sei.lpVerb = "open"; + sei.nShow = SW_SHOWNORMAL; + /* Dunno what these mean, but it looks like winMe's start uses them */ + sei.fMask = SEE_MASK_FLAG_DDEWAIT|SEE_MASK_FLAG_NO_UI; + + /* Canonical Microsoft commandline flag processing: + * flags start with /, are case insensitive, + * and may be run together in same word. + */ + for (argi=1; argi<argc; argi++) { + int ci; + + if (argv[argi][0] != '/') + break; + + /* Handle all options in this word */ + for (ci=0; argv[argi][ci]; ) { + /* Skip slash */ + ci++; + switch(argv[argi][ci]) { + case 'l': + case 'L': + license(); + break; /* notreached */ + case 'm': + case 'M': + if (argv[argi][ci+1] == 'a' || argv[argi][ci+1] == 'A') + sei.nShow = SW_SHOWMAXIMIZED; + else + sei.nShow = SW_SHOWMINIMIZED; + break; + case 'r': + case 'R': + /* sei.nShow = SW_SHOWNORMAL; */ + break; + case 'w': + case 'W': + sei.fMask |= SEE_MASK_NOCLOSEPROCESS; + break; + default: + printf("Option '%s' not recognized\n", argv[argi]+ci-1); + usage(); + } + /* Skip to next slash */ + while (argv[argi][ci] && (argv[argi][ci] != '/')) + ci++; + } + } + + if (argi == argc) + usage(); + + sei.lpFile = argv[argi++]; + + /* FIXME - prone to overflow */ + arguments[0] = 0; + for (p = arguments; argi < argc; argi++) + p += sprintf(p, " %s", argv[argi]); + + sei.lpParameters = arguments; + + if (!ShellExecuteEx(&sei)) + fatal_string_error(STRING_EXECFAIL, GetLastError()); + + if (sei.fMask & SEE_MASK_NOCLOSEPROCESS) { + DWORD exitcode; + DWORD waitcode; + waitcode = WaitForSingleObject(sei.hProcess, INFINITE); + if (waitcode) + fatal_error("WaitForSingleObject", GetLastError()); + if (!GetExitCodeProcess(sei.hProcess, &exitcode)) + fatal_error("GetExitCodeProcess", GetLastError()); + /* fixme: haven't tested whether exit code works properly */ + ExitProcess(exitcode); + } + + ExitProcess(0); +} --- /dev/null 2002-08-30 16:31:37.000000000 -0700 +++ programs/start/resources.h 2003-01-17 23:26:09.000000000 -0800 @@ -0,0 +1,3 @@ +#define STRING_USAGE 101 +#define STRING_LICENSE 102 +#define STRING_EXECFAIL 103 --- /dev/null 2002-08-30 16:31:37.000000000 -0700 +++ programs/start/En.rc 2003-01-17 23:26:09.000000000 -0800 @@ -0,0 +1,64 @@ +/* + * Start + * English Language Support + * + * Copyright 2003 Dan Kegel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(850) + +STRINGTABLE DISCARDABLE LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT +{ +STRING_USAGE, "Start a program, or open a document in the program normally used for files with that suffix. \n\ +Usage: \n\ +start [options] program_filename [...] \n\ +start [options] document_filename \n\ + \n\ +Options: \n\ +/M[inimized] Start the program minimized. \n\ +/MAX[imized] Start the program maximized. \n\ +/R[estored] Start the program normally (neither minimized nor maximized). \n\ +/W[ait] Wait for started program to finish, then exit with its exit code. \n\ +/L Show end-user license. \n\ + \n\ +start.exe version 0.2 Copyright (C) 2003, Dan Kegel \n\ +Start comes with ABSOLUTELY NO WARRANTY; for details run with /L option. \n\ +This is free software, and you are welcome to redistribute it \n\ +under certain conditions; run 'start /L' for details. \n\ +" + +STRING_LICENSE, "start.exe version 0.2 Copyright (C) 2003, Dan Kegel \n\ +This program is free software; you can redistribute it and/or \n\ +modify it under the terms of the GNU Lesser Public License \n\ +as published by the Free Software Foundation; either version 2.1 \n\ +of the License, or (at your option) any later version. \n\ + \n\ +This program is distributed in the hope that it will be useful, \n\ +but WITHOUT ANY WARRANTY; without even the implied warranty of \n\ +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the \n\ +GNU Lesser Public License for more details. \n\ + \n\ +You should have received a copy of the GNU Lesser Public License \n\ +along with this program; if not, write to the Free Software \n\ +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. \n\ + \n\ +See the COPYING.LIB file for license information. \n\ +" + +STRING_EXECFAIL "Application could not be started, or no application associated with the specified file.\nShellExecuteEx failed" +} --- /dev/null 2002-08-30 16:31:37.000000000 -0700 +++ programs/start/rsrc.rc 2003-01-17 23:26:09.000000000 -0800 @@ -0,0 +1,24 @@ +/* + * Copyright 2003 Dan Kegel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <windows.h> +#include "resources.h" + +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL + +#include "En.rc"