diff --git a/configure b/configure index 956b09d2ed0..0f0d865aa17 100755 --- a/configure +++ b/configure @@ -6371,7 +6371,6 @@ dlls/shfolder/Makefile dlls/shlwapi/Makefile dlls/tapi32/Makefile dlls/ttydrv/Makefile -dlls/ttydrv/Makefile dlls/urlmon/Makefile dlls/user/Makefile dlls/version/Makefile @@ -6409,8 +6408,8 @@ include/Makefile library/Makefile libtest/Makefile loader/Makefile -loader/ne/Makefile loader/dos/Makefile +loader/ne/Makefile memory/Makefile misc/Makefile miscemu/Makefile @@ -6418,15 +6417,16 @@ msdos/Makefile objects/Makefile ole/Makefile programs/Makefile +programs/avitools/Makefile programs/clock/Makefile programs/cmdlgtst/Makefile programs/control/Makefile -programs/avitools/Makefile -programs/osversioncheck/Makefile programs/notepad/Makefile +programs/osversioncheck/Makefile programs/progman/Makefile -programs/regtest/Makefile programs/regapi/Makefile +programs/regtest/Makefile +programs/uninstaller/Makefile programs/view/Makefile programs/wcmd/Makefile programs/winemine/Makefile @@ -6439,8 +6439,8 @@ server/Makefile tools/Makefile tools/cvdump/Makefile tools/winebuild/Makefile -tools/wrc/Makefile tools/wmc/Makefile +tools/wrc/Makefile tsx11/Makefile unicode/Makefile win32/Makefile @@ -6607,7 +6607,6 @@ dlls/shfolder/Makefile dlls/shlwapi/Makefile dlls/tapi32/Makefile dlls/ttydrv/Makefile -dlls/ttydrv/Makefile dlls/urlmon/Makefile dlls/user/Makefile dlls/version/Makefile @@ -6645,8 +6644,8 @@ include/Makefile library/Makefile libtest/Makefile loader/Makefile -loader/ne/Makefile loader/dos/Makefile +loader/ne/Makefile memory/Makefile misc/Makefile miscemu/Makefile @@ -6654,15 +6653,16 @@ msdos/Makefile objects/Makefile ole/Makefile programs/Makefile +programs/avitools/Makefile programs/clock/Makefile programs/cmdlgtst/Makefile programs/control/Makefile -programs/avitools/Makefile -programs/osversioncheck/Makefile programs/notepad/Makefile +programs/osversioncheck/Makefile programs/progman/Makefile -programs/regtest/Makefile programs/regapi/Makefile +programs/regtest/Makefile +programs/uninstaller/Makefile programs/view/Makefile programs/wcmd/Makefile programs/winemine/Makefile @@ -6675,8 +6675,8 @@ server/Makefile tools/Makefile tools/cvdump/Makefile tools/winebuild/Makefile -tools/wrc/Makefile tools/wmc/Makefile +tools/wrc/Makefile tsx11/Makefile unicode/Makefile win32/Makefile diff --git a/configure.in b/configure.in index 360f95755de..d3ae566d126 100644 --- a/configure.in +++ b/configure.in @@ -259,7 +259,7 @@ then if test "$wine_cv_opengl_version_OK" = "yes" -a \( "$wine_cv_opengl_version_threadsafe" = "no" -o $OPENGL = "yes" \) then - dnl Check for the presense of the library + dnl Check for the presence of the library AC_CHECK_LIB(GL,glXCreateContext, X_PRE_LIBS="$X_PRE_LIBS -lGL" MESA_SRCS='$(MESA_SRCS)' @@ -1040,7 +1040,6 @@ dlls/shfolder/Makefile dlls/shlwapi/Makefile dlls/tapi32/Makefile dlls/ttydrv/Makefile -dlls/ttydrv/Makefile dlls/urlmon/Makefile dlls/user/Makefile dlls/version/Makefile @@ -1078,8 +1077,8 @@ include/Makefile library/Makefile libtest/Makefile loader/Makefile -loader/ne/Makefile loader/dos/Makefile +loader/ne/Makefile memory/Makefile misc/Makefile miscemu/Makefile @@ -1087,15 +1086,16 @@ msdos/Makefile objects/Makefile ole/Makefile programs/Makefile +programs/avitools/Makefile programs/clock/Makefile programs/cmdlgtst/Makefile programs/control/Makefile -programs/avitools/Makefile -programs/osversioncheck/Makefile programs/notepad/Makefile +programs/osversioncheck/Makefile programs/progman/Makefile -programs/regtest/Makefile programs/regapi/Makefile +programs/regtest/Makefile +programs/uninstaller/Makefile programs/view/Makefile programs/wcmd/Makefile programs/winemine/Makefile @@ -1108,8 +1108,8 @@ server/Makefile tools/Makefile tools/cvdump/Makefile tools/winebuild/Makefile -tools/wrc/Makefile tools/wmc/Makefile +tools/wrc/Makefile tsx11/Makefile unicode/Makefile win32/Makefile diff --git a/include/regstr.h b/include/regstr.h new file mode 100644 index 00000000000..21f263b6a98 --- /dev/null +++ b/include/regstr.h @@ -0,0 +1,22 @@ +/* + * Win32 registry string defines (see also winnt.h) + */ +#ifndef _INC_REGSTR +#define _INC_REGSTR + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +#define REGSTR_PATH_UNINSTALL TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall") + +/* DisplayName <= 32 chars in Windows (otherwise not displayed for uninstall) */ +#define REGSTR_VAL_UNINSTALLER_DISPLAYNAME TEXT("DisplayName") +/* UninstallString <= 63 chars in Windows (otherwise problems) */ +#define REGSTR_VAL_UNINSTALLER_COMMANDLINE TEXT("UninstallString") + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* _INC_REGSTR_H */ diff --git a/programs/Makefile.in b/programs/Makefile.in index 8b96580cf1b..d50d97494d7 100644 --- a/programs/Makefile.in +++ b/programs/Makefile.in @@ -14,6 +14,7 @@ SUBDIRS = \ progman \ regapi \ regtest \ + uninstaller \ view \ wcmd \ winemine \ diff --git a/programs/uninstaller/.cvsignore b/programs/uninstaller/.cvsignore new file mode 100644 index 00000000000..664cfff4531 --- /dev/null +++ b/programs/uninstaller/.cvsignore @@ -0,0 +1,4 @@ +Makefile +rsrc.s +uninstaller +uninstaller.spec.c diff --git a/programs/uninstaller/Makefile.in b/programs/uninstaller/Makefile.in new file mode 100644 index 00000000000..e284f8fb4b9 --- /dev/null +++ b/programs/uninstaller/Makefile.in @@ -0,0 +1,32 @@ +DEFS = -DWINELIB -DSTRICT +TOPSRCDIR = @top_srcdir@ +TOPOBJDIR = ../.. +SRCDIR = @srcdir@ +VPATH = @srcdir@ +MODULE = none +PROGRAMS = uninstaller +WRCEXTRA = -s -p uninstaller + +LICENSELANG = En + +C_SRCS = \ + main.c + +SPEC_SRCS = uninstaller.spec + +RC_SRCS = rsrc.rc + +all: check_wrc $(PROGRAMS) + +@MAKE_RULES@ + +uninstaller: $(OBJS) + $(CC) -o uninstaller $(OBJS) $(DLL_LINK) $(LIBS) + +install:: + $(INSTALL_PROGRAM) uninstaller $(bindir)/uninstaller + +uninstall:: + $(RM) $(bindir)/uninstaller + +### Dependencies: diff --git a/programs/uninstaller/README b/programs/uninstaller/README new file mode 100644 index 00000000000..0e110bfd62e --- /dev/null +++ b/programs/uninstaller/README @@ -0,0 +1,21 @@ +Uninstaller README + +Uninstaller, copyright 2000, Andreas Mohr +Uninstaller is to be distributed under the Wine License +See the Wine License for further information. + +This is an uninstaller for all setup programs that put an uninstall entry +into the registry, such as e.g. InstallShield or the WISE installer. +Its files have been shamelessly ripped from WineMine partially :) + +TODO: + - implement sorting of the uninstall entries + - let the uninstall happen in a separate thread in order to be able to + uninstall several programs concurrently + +KNOWN BUGS: + - minimizing/maximizing is broken (just as with WineMine) + - the icon is, ermm, wrong ;-)) + +UNKNOWN BUGS: + ??? diff --git a/programs/uninstaller/main.c b/programs/uninstaller/main.c new file mode 100644 index 00000000000..a7d7911d339 --- /dev/null +++ b/programs/uninstaller/main.c @@ -0,0 +1,335 @@ +/* + * Q&D Uninstaller (main.c) + * + * Copyright 2000 Andreas Mohr + * To be distributed under the Wine License + */ + + +#include +#include +#include +#include +#include +#include "main.h" +#include "regstr.h" + +/* Work around a Wine bug which defines handles as UINT rather than LPVOID */ +#ifdef WINE_STRICT +#define NULL_HANDLE NULL +#else +#define NULL_HANDLE 0 +#endif + +#ifdef DUMB_DEBUG +#include +#define DEBUG(x) fprintf(stderr,x) +#else +#define DEBUG(x) +#endif + +/* use multi-select listbox */ +#undef USE_MULTIPLESEL + +/* Delete uninstall registry key after execution. + * This is probably a bad idea, because it's the + * uninstall program that is supposed to do that. + */ +#undef DEL_REG_KEY + +char appname[18]; + +static char about_string[] = + "Windows program uninstaller (C) 2000 by Andreas Mohr "; +static char program_description[] = + "Welcome to the Wine uninstaller !\n\nThe purpose of this program is to let you get rid of all those fantastic programs that somehow manage to always take way too much space on your HDD :-)"; + +typedef struct { + char *key; + char *descr; + char *command; +#ifdef USE_MULTIPLESEL + int active; +#endif +} uninst_entry; + +uninst_entry *entries = NULL; + +int numentries = 0; + +int cursel = -1; + +struct { + DWORD style; + LPCSTR text; + HWND hwnd; +} button[] = +{ + { BS_PUSHBUTTON, "Add/Remove", 0 }, + { BS_PUSHBUTTON, "About", 0 }, + { BS_PUSHBUTTON, "Exit", 0 } +}; + +#define NUM (sizeof button/sizeof button[0]) + +int WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR cmdline, int cmdshow ) +{ + MSG msg; + WNDCLASS wc; + HWND hWnd; + + LoadString( hInst, IDS_APPNAME, appname, sizeof(appname)); + + wc.style = 0; + wc.lpfnWndProc = MainProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInst; + wc.hIcon = LoadIcon( hInst, appname ); + wc.hCursor = LoadCursor( NULL_HANDLE, IDI_APPLICATION ); + wc.hbrBackground = (HBRUSH) GetStockObject( LTGRAY_BRUSH ); + wc.lpszMenuName = NULL; + wc.lpszClassName = appname; + + if (!RegisterClass(&wc)) exit(1); + hWnd = CreateWindow( appname, appname, + WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + NULL_HANDLE, NULL_HANDLE, hInst, NULL ); + + if (!hWnd) exit(1); + + ShowWindow( hWnd, cmdshow ); + UpdateWindow( hWnd ); + + while( GetMessage(&msg, NULL_HANDLE, 0, 0) ) { + TranslateMessage( &msg ); + DispatchMessage( &msg ); + } + return msg.wParam; +} + +int GetUninstallStrings() +{ + HKEY hkeyUninst, hkeyApp; + int i; + DWORD sizeOfSubKeyName=255, displen, uninstlen; + char subKeyName[256]; + char key_app[1024]; + char *p; + + + if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGSTR_PATH_UNINSTALL, + 0, KEY_READ, &hkeyUninst) != ERROR_SUCCESS ) + { + MessageBox(0, "Uninstall registry key not available (yet), nothing to do !", appname, MB_OK); + return 0; + } + + strcpy(key_app, REGSTR_PATH_UNINSTALL); + strcat(key_app, "\\"); + p = key_app+strlen(REGSTR_PATH_UNINSTALL)+1; + for ( i=0; + RegEnumKeyExA( hkeyUninst, i, subKeyName, &sizeOfSubKeyName, + NULL, NULL, NULL, NULL ) != ERROR_NO_MORE_ITEMS; + ++i, sizeOfSubKeyName=255 ) + { + strcpy(p, subKeyName); + RegOpenKeyEx(HKEY_LOCAL_MACHINE, key_app, 0, KEY_READ, &hkeyApp); + + if ( (RegQueryValueEx(hkeyApp, REGSTR_VAL_UNINSTALLER_DISPLAYNAME, + 0, 0, NULL, &displen) == ERROR_SUCCESS) + && (RegQueryValueEx(hkeyApp, REGSTR_VAL_UNINSTALLER_COMMANDLINE, + 0, 0, NULL, &uninstlen) == ERROR_SUCCESS) ) + { + numentries++; + entries = HeapReAlloc(GetProcessHeap(), 0, entries, numentries*sizeof(uninst_entry)); + entries[numentries-1].key = + HeapAlloc(GetProcessHeap(), 0, strlen(subKeyName)+1); + strcpy(entries[numentries-1].key, subKeyName); + entries[numentries-1].descr = + HeapAlloc(GetProcessHeap(), 0, displen); + RegQueryValueEx(hkeyApp, REGSTR_VAL_UNINSTALLER_DISPLAYNAME, 0, 0, + entries[numentries-1].descr, &displen); + entries[numentries-1].command = + HeapAlloc(GetProcessHeap(), 0, uninstlen); +#ifdef USE_MULTIPLESEL + entries[numentries-1].active = 0; +#endif + RegQueryValueEx(hkeyApp, REGSTR_VAL_UNINSTALLER_COMMANDLINE, 0, 0, + entries[numentries-1].command, &uninstlen); + } + RegCloseKey(hkeyApp); + } + RegCloseKey(hkeyUninst); + return 1; +} + +void UninstallProgram(HWND hWnd) +{ + int i; + char errormsg[1024]; + BOOL res; + STARTUPINFO si; + PROCESS_INFORMATION info; + DWORD exit_code; +#ifdef DEL_REG_KEY + HKEY hkey; +#endif + +#ifdef USE_MULTIPLESEL + for (i=0; i < numentries; i++) + { + if (!(entries[i].active)) /* don't uninstall this one */ + continue; +#else + if (cursel == -1) + return; + i = cursel; +#endif + memset(&si, 0, sizeof(STARTUPINFO)); + si.cb = sizeof(STARTUPINFO); + si.wShowWindow = SW_NORMAL; + res = CreateProcess(NULL, entries[i].command, NULL, NULL, FALSE, 0, NULL, NULL, &si, &info); + if (res == TRUE) + { /* wait for the process to exit */ + WaitForSingleObject(info.hProcess, INFINITE); + res = GetExitCodeProcess(info.hProcess, &exit_code); + fprintf(stderr, "%d: %08lx\n", res, exit_code); +#ifdef DEL_REG_KEY + /* delete the program's uninstall entry */ + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGSTR_PATH_UNINSTALL, + 0, KEY_READ, &hkey) == ERROR_SUCCESS) + { + RegDeleteKey(hkey, entries[i].key); + RegCloseKey(hkey); + } +#endif + + /* update listbox */ + numentries = 0; + GetUninstallStrings(); + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + } + else + { + sprintf(errormsg, "Execution of uninstall command '%s' failed, perhaps due to missing executable.", entries[i].command); + MessageBox(0, errormsg, appname, MB_OK); + } +#ifdef USE_MULTIPLESEL + } +#endif +} + +LRESULT WINAPI MainProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + HDC hdc; + PAINTSTRUCT ps; + TEXTMETRIC tm; + int cxChar, cyChar, i, y, bx, by, maxx, maxy, wx, wy; + static HWND hwndList = 0; + DWORD style; + RECT rect; + + switch( msg ) { + case WM_CREATE: + { + if (!(GetUninstallStrings())) + { + PostQuitMessage(0); + return 0; + } + hdc = GetDC(hWnd); + GetTextMetrics(hdc, &tm); + cxChar = tm.tmAveCharWidth; + cyChar = tm.tmHeight + tm.tmExternalLeading; + ReleaseDC(hWnd, hdc); + /* FIXME: implement sorting and use LBS_SORT here ! */ + style = (WS_CHILD|WS_VISIBLE|LBS_STANDARD) & ~LBS_SORT; +#ifdef USE_MULTIPLESEL + style |= LBS_MULTIPLESEL; +#endif + bx = maxx = cxChar * 5; + by = maxy = cyChar * 3; + hwndList = CreateWindow("listbox", NULL, + style, + maxx, maxy, + cxChar * 50 + GetSystemMetrics(SM_CXVSCROLL), cyChar * 20, + hWnd, (HMENU) 1, + (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE), NULL); + + GetWindowRect(hwndList, &rect); + y = by; + maxx += (rect.right - rect.left)*1.1; + maxy += (rect.bottom - rect.top)*1.1; + wx = 20*cxChar; + wy = 7*cyChar/4; + for (i=0; i < NUM; i++) + { + button[i].hwnd = CreateWindow("button", button[i].text, + WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, + maxx, y, + wx, wy, + hWnd, (HMENU)i, + ((LPCREATESTRUCT)lParam)->hInstance, NULL); + if (!button[i].hwnd) + PostQuitMessage(0); + y += 2*cyChar; + } + CreateWindow("static", program_description, + WS_CHILD|WS_VISIBLE|SS_LEFT, + bx, maxy, + cxChar * 50, wy, + hWnd, (HMENU)1, + ((LPCREATESTRUCT)lParam)->hInstance, NULL); + maxx += wx + cxChar * 5; /* button + right border */ + maxy += cyChar * 5 + cyChar * 3; /* static text + bottom border */ + SetWindowPos( hWnd, 0, + 0, 0, maxx, maxy, + SWP_NOMOVE); + return 0; + } + + case WM_PAINT: + { + SendMessage(hwndList, LB_RESETCONTENT, 0, 0); + for (i=0; i < numentries; i++) + SendMessage(hwndList, LB_ADDSTRING, 0, (LPARAM)entries[i].descr); + hdc = BeginPaint( hWnd, &ps ); + EndPaint( hWnd, &ps ); + return 0; + } + + case WM_DESTROY: + PostQuitMessage( 0 ); + return 0; + + case WM_COMMAND: + if ((HWND)lParam == hwndList) + { + if (HIWORD(wParam) == LBN_SELCHANGE) + { + int sel = SendMessage(hwndList, LB_GETCURSEL, 0, 0); + +#ifdef USE_MULTIPLESEL + entries[sel].active ^= 1; /* toggle */ +#else + cursel = sel; +#endif + } + } + else + if ((HWND)lParam == button[0].hwnd) /* Uninstall button */ + UninstallProgram(hWnd); + else + if ((HWND)lParam == button[1].hwnd) /* About button */ + MessageBox(0, about_string, "About", MB_OK); + else + if ((HWND)lParam == button[2].hwnd) /* Exit button */ + PostQuitMessage(0); + return 0; + } + + return( DefWindowProc( hWnd, msg, wParam, lParam )); +} diff --git a/programs/uninstaller/main.h b/programs/uninstaller/main.h new file mode 100644 index 00000000000..6b1471131f5 --- /dev/null +++ b/programs/uninstaller/main.h @@ -0,0 +1,5 @@ +#include + +#define IDS_APPNAME 1101 + +LRESULT WINAPI MainProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); diff --git a/programs/uninstaller/rsrc.rc b/programs/uninstaller/rsrc.rc new file mode 100644 index 00000000000..b51512a16da --- /dev/null +++ b/programs/uninstaller/rsrc.rc @@ -0,0 +1,71 @@ +/* + * Uninstaller (rsrc.rc) + * + * Copyright 2000 Andreas Mohr + * To be distributed under the Wine License + */ + +#include +#include "main.h" + +UNINSTALLER ICON MOVEABLE +{ + '00 00 01 00 01 00 20 20 10 00 00 00 00 00 E8 02' + '00 00 16 00 00 00 28 00 00 00 20 00 00 00 40 00' + '00 00 01 00 04 00 00 00 00 00 00 02 00 00 00 00' + '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00' + '00 00 00 00 80 00 00 80 00 00 00 80 80 00 80 00' + '00 00 80 00 80 00 80 80 00 00 80 80 80 00 C0 C0' + 'C0 00 00 00 FF 00 00 FF 00 00 00 FF FF 00 FF 00' + '00 00 FF 00 FF 00 FF FF 00 00 FF FF FF 00 22 22' + '22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22' + '22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22' + '22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22' + '22 22 22 22 20 00 00 02 22 22 22 22 22 22 22 22' + '22 22 22 22 22 00 00 22 22 22 22 22 22 22 22 22' + '22 22 22 22 22 20 02 22 22 22 22 22 22 22 22 22' + '22 22 22 22 22 20 02 22 22 22 22 22 22 22 22 22' + '22 22 22 22 22 20 02 22 22 22 22 22 22 22 22 22' + '22 22 22 22 22 20 02 22 22 22 22 22 22 22 22 22' + '22 22 20 07 77 70 07 77 70 02 22 22 22 22 22 22' + '22 22 20 07 77 00 07 77 70 02 22 22 22 22 22 22' + '22 22 27 70 00 00 00 00 07 72 22 22 22 22 22 22' + '22 22 27 70 00 00 00 00 07 72 22 22 22 22 22 22' + '20 22 27 70 00 00 00 00 07 72 22 02 22 22 22 22' + '00 02 27 00 00 00 00 00 07 72 20 00 22 22 22 20' + '00 00 00 00 00 00 00 00 00 00 00 00 02 22 22 20' + '00 00 00 00 00 00 00 00 00 00 00 00 02 22 22 22' + '00 02 27 00 00 00 0F F0 08 82 20 00 22 22 22 22' + '20 22 27 70 00 00 0F F0 08 82 20 02 22 22 22 22' + '22 22 27 70 00 00 00 F0 08 82 22 22 22 22 22 22' + '22 22 27 70 00 00 00 00 08 82 22 22 22 22 22 22' + '22 22 20 07 77 00 00 88 80 02 22 22 22 22 22 22' + '22 22 20 07 78 80 08 88 80 02 22 22 22 22 22 22' + '22 22 22 22 22 20 02 22 22 22 22 22 22 22 22 22' + '22 22 22 22 22 20 02 22 22 22 22 22 22 22 22 22' + '22 22 22 22 22 20 02 22 22 22 22 22 22 22 22 22' + '22 22 22 22 22 20 02 22 22 22 22 22 22 22 22 22' + '22 22 22 22 22 00 00 22 22 22 22 22 22 22 22 22' + '22 22 22 22 20 00 00 02 22 22 22 22 22 22 22 22' + '22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22' + '22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22' + '22 22 22 22 22 22 22 22 22 22 22 22 22 22 00 00' + '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00' + '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00' + '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00' + '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00' + '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00' + '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00' + '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00' + '00 00 00 00 00 00 00 00 00 00 00 00 00 00' +} + +/* English-US Resources */ +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +STRINGTABLE { + IDS_APPNAME, "Uninstaller" + +} + +/* End of English-US Resources */ diff --git a/programs/uninstaller/uninstaller.spec b/programs/uninstaller/uninstaller.spec new file mode 100644 index 00000000000..4763ae8a145 --- /dev/null +++ b/programs/uninstaller/uninstaller.spec @@ -0,0 +1,5 @@ +name uninstaller +mode guiexe +type win32 +init WinMain +rsrc uninstaller