converted RMDir back from SHFileOperation to the good old manual method
- RMDir can now be used with both /r and /REBOOTOK - RMDir /r no longer leaves lots of files behind if one file removal failed - The plug-ins directory is now always deleted, if not immediately, then after reboot - RMDir /r prints a detailed log of its actions git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@3597 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
parent
7270abe8d3
commit
010dc75a71
8 changed files with 141 additions and 87 deletions
|
@ -66,9 +66,9 @@ See \R{file}{File} for more information about the parameters.
|
||||||
|
|
||||||
\S2{rmdir} RMDir
|
\S2{rmdir} RMDir
|
||||||
|
|
||||||
\c [/r|/REBOOTOK] directory_name
|
\c [/r] [/REBOOTOK] directory_name
|
||||||
|
|
||||||
Remove the specified directory (which should be a full path). Without /r, the directory will only be removed if it is completely empty. If /r is specified, the directory will be removed recursively, so all directories and files in the specified directory will be removed. If /REBOOTOK is specified, and the directory cannot be overwritten, then the directory will be deleted when the system reboots -- if the directory will be removed on a reboot, the reboot flag will be set. The error flag is set if the directory cannot be removed.
|
Remove the specified directory (which should be a full path). Without /r, the directory will only be removed if it is completely empty. If /r is specified, the directory will be removed recursively, so all directories and files in the specified directory will be removed. If /REBOOTOK is specified, any file or directory which could not have been removed during the process will be removed on reboot -- if any file or directory will be removed on a reboot, the reboot flag will be set. The error flag is set if any file or directory cannot be removed.
|
||||||
|
|
||||||
\S2{setoutpath} SetOutPath
|
\S2{setoutpath} SetOutPath
|
||||||
|
|
||||||
|
|
|
@ -278,6 +278,6 @@ void NSISCALL CleanUp()
|
||||||
#endif
|
#endif
|
||||||
#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
|
#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
|
||||||
// Clean up after plug-ins
|
// Clean up after plug-ins
|
||||||
doRMDir(state_plugins_dir, 1);
|
myDelete(state_plugins_dir, DEL_DIR | DEL_RECURSE | DEL_REBOOT);
|
||||||
#endif // NSIS_CONFIG_PLUGIN_SUPPORT
|
#endif // NSIS_CONFIG_PLUGIN_SUPPORT
|
||||||
}
|
}
|
||||||
|
|
|
@ -487,46 +487,9 @@ static int NSISCALL ExecuteEntry(entry *entry_)
|
||||||
#ifdef NSIS_SUPPORT_DELETE
|
#ifdef NSIS_SUPPORT_DELETE
|
||||||
case EW_DELETEFILE:
|
case EW_DELETEFILE:
|
||||||
{
|
{
|
||||||
HANDLE h;
|
char *buf0=GetStringFromParm(0x00);
|
||||||
WIN32_FIND_DATA fd;
|
|
||||||
char *buf1=GetStringFromParm(0x10);
|
|
||||||
mystrcpy(buf0,buf1);
|
|
||||||
log_printf2("Delete: \"%s\"",buf0);
|
log_printf2("Delete: \"%s\"",buf0);
|
||||||
trimslashtoend(buf0);
|
myDelete(buf0,parm1);
|
||||||
h=FindFirstFile(buf1,&fd);
|
|
||||||
if (h != INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
|
|
||||||
{
|
|
||||||
wsprintf(buf1,"%s\\%s",buf0,fd.cFileName);
|
|
||||||
if (fd.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
|
|
||||||
SetFileAttributes(buf1,fd.dwFileAttributes^FILE_ATTRIBUTE_READONLY);
|
|
||||||
if (DeleteFile(buf1))
|
|
||||||
{
|
|
||||||
log_printf2("Delete: DeleteFile(\"%s\")",buf1);
|
|
||||||
update_status_text_buf1(LANG_DELETEFILE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifdef NSIS_SUPPORT_MOVEONREBOOT
|
|
||||||
if (parm1)
|
|
||||||
{
|
|
||||||
log_printf2("Delete: DeleteFile on Reboot(\"%s\")",buf1);
|
|
||||||
update_status_text_buf1(LANG_DELETEONREBOOT);
|
|
||||||
MoveFileOnReboot(buf1,NULL);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
exec_error++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (FindNextFile(h,&fd));
|
|
||||||
FindClose(h);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif//NSIS_SUPPORT_DELETE
|
#endif//NSIS_SUPPORT_DELETE
|
||||||
|
@ -558,9 +521,7 @@ static int NSISCALL ExecuteEntry(entry *entry_)
|
||||||
char *buf1=GetStringFromParm(-0x10);
|
char *buf1=GetStringFromParm(-0x10);
|
||||||
log_printf2("RMDir: \"%s\"",buf1);
|
log_printf2("RMDir: \"%s\"",buf1);
|
||||||
|
|
||||||
doRMDir(buf1,parm1);
|
myDelete(buf1,parm1);
|
||||||
if (file_exists(buf1) && parm1!=2) exec_error++;
|
|
||||||
else update_status_text_buf1(LANG_REMOVEDIR);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif//NSIS_SUPPORT_RMDIR
|
#endif//NSIS_SUPPORT_RMDIR
|
||||||
|
@ -1178,7 +1139,7 @@ static int NSISCALL ExecuteEntry(entry *entry_)
|
||||||
{
|
{
|
||||||
char *buf3=GetStringFromParm(0x33);
|
char *buf3=GetStringFromParm(0x33);
|
||||||
res = RegDeleteValue(hKey,buf3);
|
res = RegDeleteValue(hKey,buf3);
|
||||||
log_printf4("DeleteRegValue: %d\\%s\\%s",rootkey,buf2,buf3);
|
log_printf4("DeleteRegValue: %d\\%s\\%s",parm1,buf2,buf3);
|
||||||
RegCloseKey(hKey);
|
RegCloseKey(hKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -432,6 +432,11 @@ typedef struct {
|
||||||
int flags;
|
int flags;
|
||||||
} ctlcolors;
|
} ctlcolors;
|
||||||
|
|
||||||
|
// constants for myDelete (util.c)
|
||||||
|
#define DEL_DIR 1
|
||||||
|
#define DEL_RECURSE 2
|
||||||
|
#define DEL_REBOOT 4
|
||||||
|
|
||||||
// $0..$9, $INSTDIR, etc are encoded as ASCII bytes starting from this value.
|
// $0..$9, $INSTDIR, etc are encoded as ASCII bytes starting from this value.
|
||||||
// Added by ramon 3 jun 2003
|
// Added by ramon 3 jun 2003
|
||||||
#define NS_SKIP_CODE 252
|
#define NS_SKIP_CODE 252
|
||||||
|
|
|
@ -94,36 +94,110 @@ void * NSISCALL my_GlobalAlloc(DWORD dwBytes) {
|
||||||
return (void *)GlobalAlloc(GPTR, dwBytes);
|
return (void *)GlobalAlloc(GPTR, dwBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef NSIS_SUPPORT_RMDIR
|
void NSISCALL myDelete(char *buf, int flags)
|
||||||
void NSISCALL doRMDir(char *buf, int flags) // 1 - recurse, 2 - rebootok
|
|
||||||
{
|
{
|
||||||
if (is_valid_instpath(buf))
|
static char lbuf[NSIS_MAX_STRLEN];
|
||||||
{
|
|
||||||
if (flags&1) {
|
|
||||||
SHFILEOPSTRUCT op;
|
|
||||||
|
|
||||||
op.hwnd=g_hwnd;
|
HANDLE h;
|
||||||
op.wFunc=FO_DELETE;
|
WIN32_FIND_DATA fd;
|
||||||
buf[mystrlen(buf)+1]=0;
|
char *fn;
|
||||||
op.pFrom=buf;
|
|
||||||
op.pTo=0;
|
|
||||||
|
|
||||||
op.fFlags=FOF_NOERRORUI|FOF_SILENT|FOF_NOCONFIRMATION;
|
#ifdef NSIS_SUPPORT_RMDIR
|
||||||
|
if (!(flags & DEL_DIR) || (is_valid_instpath(buf) && (flags & DEL_RECURSE)))
|
||||||
SHFileOperation(&op);
|
|
||||||
}
|
|
||||||
#ifdef NSIS_SUPPORT_MOVEONREBOOT
|
|
||||||
else if (!RemoveDirectory(buf) && flags&2) {
|
|
||||||
log_printf2("Remove folder on reboot: %s",buf);
|
|
||||||
MoveFileOnReboot(buf,0);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
else RemoveDirectory(buf);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
log_printf2("RMDir: RemoveDirectory(\"%s\")",buf);
|
|
||||||
}
|
|
||||||
#endif//NSIS_SUPPORT_RMDIR
|
#endif//NSIS_SUPPORT_RMDIR
|
||||||
|
{
|
||||||
|
mystrcpy(lbuf,buf);
|
||||||
|
#ifdef NSIS_SUPPORT_RMDIR
|
||||||
|
if (flags & DEL_DIR)
|
||||||
|
lstrcat(lbuf,"\\*.*");
|
||||||
|
else
|
||||||
|
#endif//NSIS_SUPPORT_RMDIR
|
||||||
|
trimslashtoend(buf);
|
||||||
|
|
||||||
|
lstrcat(buf,"\\");
|
||||||
|
|
||||||
|
fn=buf+mystrlen(buf);
|
||||||
|
|
||||||
|
h = FindFirstFile(lbuf,&fd);
|
||||||
|
if (h != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
#ifdef NSIS_SUPPORT_RMDIR
|
||||||
|
if (fd.cFileName[0] != '.' ||
|
||||||
|
(fd.cFileName[1] != '.' && fd.cFileName[1]))
|
||||||
|
#endif//NSIS_SUPPORT_RMDIR
|
||||||
|
{
|
||||||
|
mystrcpy(fn,fd.cFileName);
|
||||||
|
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||||
|
{
|
||||||
|
#ifdef NSIS_SUPPORT_RMDIR
|
||||||
|
if ((flags & DEL_DIR | DEL_RECURSE) == (DEL_DIR | DEL_RECURSE))
|
||||||
|
{
|
||||||
|
myDelete(buf,flags);
|
||||||
|
}
|
||||||
|
#endif//NSIS_SUPPORT_RMDIR
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log_printf2("Delete: DeleteFile(\"%s\")",buf);
|
||||||
|
SetFileAttributes(buf,fd.dwFileAttributes&(~FILE_ATTRIBUTE_READONLY));
|
||||||
|
if (!DeleteFile(buf))
|
||||||
|
{
|
||||||
|
#ifdef NSIS_SUPPORT_MOVEONREBOOT
|
||||||
|
if (flags & DEL_REBOOT)
|
||||||
|
{
|
||||||
|
log_printf2("Delete: DeleteFile on Reboot(\"%s\")",buf);
|
||||||
|
update_status_text(LANG_DELETEONREBOOT,buf);
|
||||||
|
MoveFileOnReboot(buf,NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif//NSIS_SUPPORT_MOVEONREBOOT
|
||||||
|
{
|
||||||
|
log_printf2("Delete: DeleteFile failed(\"%s\")",buf);
|
||||||
|
g_exec_flags.exec_error++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
update_status_text(LANG_DELETEFILE,buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (FindNextFile(h,&fd));
|
||||||
|
FindClose(h);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef NSIS_SUPPORT_RMDIR
|
||||||
|
if (flags & DEL_DIR)
|
||||||
|
fn[-1]=0;
|
||||||
|
#endif//NSIS_SUPPORT_RMDIR
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef NSIS_SUPPORT_RMDIR
|
||||||
|
if (flags & DEL_DIR)
|
||||||
|
{
|
||||||
|
addtrailingslash(buf);
|
||||||
|
log_printf2("RMDir: RemoveDirectory(\"%s\")",buf);
|
||||||
|
if (!RemoveDirectory(buf))
|
||||||
|
{
|
||||||
|
#ifdef NSIS_SUPPORT_MOVEONREBOOT
|
||||||
|
if (flags & DEL_REBOOT)
|
||||||
|
{
|
||||||
|
log_printf2("RMDir: RemoveDirectory on Reboot(\"%s\")",buf);
|
||||||
|
update_status_text(LANG_DELETEONREBOOT,buf);
|
||||||
|
MoveFileOnReboot(buf,NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif//NSIS_SUPPORT_MOVEONREBOOT
|
||||||
|
{
|
||||||
|
log_printf2("RMDir: RemoveDirectory failed(\"%s\")",buf);
|
||||||
|
g_exec_flags.exec_error++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
update_status_text(LANG_REMOVEDIR,buf);
|
||||||
|
}
|
||||||
|
#endif//NSIS_SUPPORT_RMDIR
|
||||||
|
}
|
||||||
|
|
||||||
char *NSISCALL addtrailingslash(char *str)
|
char *NSISCALL addtrailingslash(char *str)
|
||||||
{
|
{
|
||||||
|
|
|
@ -54,7 +54,7 @@ HANDLE NSISCALL myCreateProcess(char *cmd, char *dir);
|
||||||
int NSISCALL my_MessageBox(const char *text, UINT type);
|
int NSISCALL my_MessageBox(const char *text, UINT type);
|
||||||
void * NSISCALL my_GlobalAlloc(DWORD dwBytes);
|
void * NSISCALL my_GlobalAlloc(DWORD dwBytes);
|
||||||
|
|
||||||
void NSISCALL doRMDir(char *buf, int recurse);
|
void NSISCALL myDelete(char *buf, int flags);
|
||||||
|
|
||||||
HANDLE NSISCALL myOpenFile(const char *fn, DWORD da, DWORD cd);
|
HANDLE NSISCALL myOpenFile(const char *fn, DWORD da, DWORD cd);
|
||||||
int NSISCALL validpathspec(char *ubuf);
|
int NSISCALL validpathspec(char *ubuf);
|
||||||
|
|
|
@ -3929,7 +3929,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
|
||||||
if (!stricmp(line.gettoken_str(a),"/REBOOTOK"))
|
if (!stricmp(line.gettoken_str(a),"/REBOOTOK"))
|
||||||
{
|
{
|
||||||
a++;
|
a++;
|
||||||
ent.offsets[1]=1;
|
ent.offsets[1]=DEL_REBOOT;
|
||||||
#ifndef NSIS_SUPPORT_MOVEONREBOOT
|
#ifndef NSIS_SUPPORT_MOVEONREBOOT
|
||||||
ERROR_MSG("Error: /REBOOTOK specified, NSIS_SUPPORT_MOVEONREBOOT not defined\n");
|
ERROR_MSG("Error: /REBOOTOK specified, NSIS_SUPPORT_MOVEONREBOOT not defined\n");
|
||||||
PRINTHELP()
|
PRINTHELP()
|
||||||
|
@ -3958,23 +3958,37 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
|
||||||
{
|
{
|
||||||
int a=1;
|
int a=1;
|
||||||
ent.which=EW_RMDIR;
|
ent.which=EW_RMDIR;
|
||||||
if (!stricmp(line.gettoken_str(1),"/r"))
|
ent.offsets[1]=DEL_DIR;
|
||||||
|
while (line.gettoken_str(a)[0]=='/')
|
||||||
{
|
{
|
||||||
if (line.getnumtokens() < 3) PRINTHELP()
|
if (!stricmp(line.gettoken_str(a),"/r"))
|
||||||
a++;
|
{
|
||||||
ent.offsets[1]=1;
|
if (a == 3) PRINTHELP();
|
||||||
|
a++;
|
||||||
|
ent.offsets[1]|=DEL_RECURSE;
|
||||||
|
}
|
||||||
|
else if (!stricmp(line.gettoken_str(a),"/REBOOTOK"))
|
||||||
|
{
|
||||||
|
if (a == 3) PRINTHELP();
|
||||||
|
a++;
|
||||||
|
ent.offsets[1]|=DEL_REBOOT;
|
||||||
|
}
|
||||||
|
else PRINTHELP();
|
||||||
}
|
}
|
||||||
else if (!stricmp(line.gettoken_str(1),"/REBOOTOK"))
|
if (a < line.getnumtokens() - 1) PRINTHELP();
|
||||||
{
|
|
||||||
if (line.getnumtokens() < 3) PRINTHELP()
|
|
||||||
a++;
|
|
||||||
ent.offsets[1]=2;
|
|
||||||
}
|
|
||||||
else if (line.gettoken_str(1)[0]=='/') PRINTHELP()
|
|
||||||
ent.offsets[0]=add_string(line.gettoken_str(a));
|
ent.offsets[0]=add_string(line.gettoken_str(a));
|
||||||
SCRIPT_MSG("RMDir: %s%s\"%s\"\n",a==1?"":line.gettoken_str(1),ent.offsets[1]?" ":"",line.gettoken_str(a));
|
SCRIPT_MSG("RMDir: ");
|
||||||
|
if (a>1)
|
||||||
|
SCRIPT_MSG("%s ",line.gettoken_str(1));
|
||||||
|
if (a>2)
|
||||||
|
SCRIPT_MSG("%s ",line.gettoken_str(2));
|
||||||
|
SCRIPT_MSG("\"%s\"\n",line.gettoken_str(a));
|
||||||
|
|
||||||
DefineInnerLangString(NLF_REMOVE_DIR);
|
DefineInnerLangString(NLF_REMOVE_DIR);
|
||||||
|
DefineInnerLangString(NLF_DEL_FILE);
|
||||||
|
#ifdef NSIS_SUPPORT_MOVEONREBOOT
|
||||||
|
DefineInnerLangString(NLF_DEL_ON_REBOOT);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return add_entry(&ent);
|
return add_entry(&ent);
|
||||||
#else//!NSIS_SUPPORT_RMDIR
|
#else//!NSIS_SUPPORT_RMDIR
|
||||||
|
|
|
@ -146,7 +146,7 @@ static tokenType tokenlist[TOK__LAST] =
|
||||||
{TOK_REGDLL,"RegDLL",1,1,"dll_path_on_target.dll [entrypoint_symbol]",TP_CODE},
|
{TOK_REGDLL,"RegDLL",1,1,"dll_path_on_target.dll [entrypoint_symbol]",TP_CODE},
|
||||||
{TOK_RENAME,"Rename",2,1,"[/REBOOTOK] source_file destination_file",TP_CODE},
|
{TOK_RENAME,"Rename",2,1,"[/REBOOTOK] source_file destination_file",TP_CODE},
|
||||||
{TOK_RET,"Return",0,0,"",TP_CODE},
|
{TOK_RET,"Return",0,0,"",TP_CODE},
|
||||||
{TOK_RMDIR,"RMDir",1,1,"[/r|/REBOOTOK] directory_name",TP_CODE},
|
{TOK_RMDIR,"RMDir",1,2,"[/r] [/REBOOTOK] directory_name",TP_CODE},
|
||||||
{TOK_SECTION,"Section",0,3,"[/0] [-][un.][section_name] [section index output]",TP_GLOBAL},
|
{TOK_SECTION,"Section",0,3,"[/0] [-][un.][section_name] [section index output]",TP_GLOBAL},
|
||||||
{TOK_SECTIONEND,"SectionEnd",0,0,"",TP_SEC},
|
{TOK_SECTIONEND,"SectionEnd",0,0,"",TP_SEC},
|
||||||
{TOK_SECTIONIN,"SectionIn",1,-1,"InstTypeIdx [InstTypeIdx [...]]",TP_SEC},
|
{TOK_SECTIONIN,"SectionIn",1,-1,"InstTypeIdx [InstTypeIdx [...]]",TP_SEC},
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue