NSIS:删除登录用户的 AppData 文件夹
NSIS: delete AppData folder of logged in user
我有一个必须以管理员身份执行的安装程序。在安装过程中,用户可以选择执行全新安装。选择此选项应删除 AppData 目录中的数据。
当我以非管理员用户身份登录并且管理员输入凭据时,我只能访问管理员的 AppData 目录。如何删除实际登录用户AppData目录下的数据?
这当然是 UAC 设计的结果。
Microsoft 的官方建议是只留下 %AppData% 中的垃圾。
作为解决方法,您可以使用 GetUserShellFolderFromRegistry 获取其他用户的特殊文件夹。
如果您只想对与当前 RDP 会话关联的 SID 进行操作,您可以这样获取 SID:
!include LogicLib.nsh
Function GetThisSessionLogonSidFromLsa
System::Store S
StrCpy ""
System::Call KERNEL32::GetCurrentProcessId()i.s
System::Call KERNEL32::ProcessIdToSessionId(is,*i0r1)i.r0
${If} [=10=] <> 0
System::Call 'SECUR32::LsaEnumerateLogonSessions(*i0r2,*p0r3)i.r0'
${If} [=10=] = 0
IntOp - 1
${For} 0
IntOp * 8
System::Call '*(&i,l.r5)'
System::Call 'SECUR32::LsaGetLogonSessionData(*lr5,*p0r5)i.r0'
${If} [=10=] = 0
System::Call '*(p,l,p,p,p,p,p,p,i,i.r6,p.r7)'
${If} =
System::Call 'ADVAPI32::ConvertSidToStringSid(pr7,*p0r8)'
System::Call '*(&t${NSIS_MAX_STRLEN}.r9)'
System::Call 'KERNEL32::LocalFree(pr8)'
${EndIf}
System::Call SECUR32::LsaFreeReturnBuffer(pr5)
${EndIf}
${IfThen} != "" ${|} ${Break} ${|}
${Next}
System::Call SECUR32::LsaFreeReturnBuffer(pr3)
${EndIf}
${EndIf}
Push
System::Store L
FunctionEnd
...
Call GetThisSessionLogonSidFromLsa
Pop [=10=]
DetailPrint [=10=] ; S-1-... (Compare this with the parameter received in the EnumUsersReg callback)
对于您的具体情况,更丑陋的 hack 可能会起作用:
!include LogicLib.nsh
Function GetUsernameOfCurrentSessionFromWTS
Push [=11=]
Push
Push
StrCpy ""
System::Call 'WTSAPI32::WTSQuerySessionInformation(p0,i-1,i5,*p0r1,*i)i.r0'
${If} [=11=] <> 0
System::Call '*(&t${NSIS_MAX_STRLEN}.r2)'
System::Call 'WTSAPI32::WTSFreeMemory(p)'
${EndIf}
Exch 2
Pop
Pop [=11=]
Exch
FunctionEnd
Section
Call GetUsernameOfCurrentSessionFromWTS
Pop [=11=]
RMDir /R "$PROFILE\..$0\AppData\Roaming\MyApplication"
SectionEnd
这假设所有配置文件都存储在 $PROFILE\..
和硬编码 AppData\Roaming
中,并且这些东西可能在所有配置中都不正确。
我有一个必须以管理员身份执行的安装程序。在安装过程中,用户可以选择执行全新安装。选择此选项应删除 AppData 目录中的数据。 当我以非管理员用户身份登录并且管理员输入凭据时,我只能访问管理员的 AppData 目录。如何删除实际登录用户AppData目录下的数据?
这当然是 UAC 设计的结果。
Microsoft 的官方建议是只留下 %AppData% 中的垃圾。
作为解决方法,您可以使用 GetUserShellFolderFromRegistry 获取其他用户的特殊文件夹。
如果您只想对与当前 RDP 会话关联的 SID 进行操作,您可以这样获取 SID:
!include LogicLib.nsh
Function GetThisSessionLogonSidFromLsa
System::Store S
StrCpy ""
System::Call KERNEL32::GetCurrentProcessId()i.s
System::Call KERNEL32::ProcessIdToSessionId(is,*i0r1)i.r0
${If} [=10=] <> 0
System::Call 'SECUR32::LsaEnumerateLogonSessions(*i0r2,*p0r3)i.r0'
${If} [=10=] = 0
IntOp - 1
${For} 0
IntOp * 8
System::Call '*(&i,l.r5)'
System::Call 'SECUR32::LsaGetLogonSessionData(*lr5,*p0r5)i.r0'
${If} [=10=] = 0
System::Call '*(p,l,p,p,p,p,p,p,i,i.r6,p.r7)'
${If} =
System::Call 'ADVAPI32::ConvertSidToStringSid(pr7,*p0r8)'
System::Call '*(&t${NSIS_MAX_STRLEN}.r9)'
System::Call 'KERNEL32::LocalFree(pr8)'
${EndIf}
System::Call SECUR32::LsaFreeReturnBuffer(pr5)
${EndIf}
${IfThen} != "" ${|} ${Break} ${|}
${Next}
System::Call SECUR32::LsaFreeReturnBuffer(pr3)
${EndIf}
${EndIf}
Push
System::Store L
FunctionEnd
...
Call GetThisSessionLogonSidFromLsa
Pop [=10=]
DetailPrint [=10=] ; S-1-... (Compare this with the parameter received in the EnumUsersReg callback)
对于您的具体情况,更丑陋的 hack 可能会起作用:
!include LogicLib.nsh
Function GetUsernameOfCurrentSessionFromWTS
Push [=11=]
Push
Push
StrCpy ""
System::Call 'WTSAPI32::WTSQuerySessionInformation(p0,i-1,i5,*p0r1,*i)i.r0'
${If} [=11=] <> 0
System::Call '*(&t${NSIS_MAX_STRLEN}.r2)'
System::Call 'WTSAPI32::WTSFreeMemory(p)'
${EndIf}
Exch 2
Pop
Pop [=11=]
Exch
FunctionEnd
Section
Call GetUsernameOfCurrentSessionFromWTS
Pop [=11=]
RMDir /R "$PROFILE\..$0\AppData\Roaming\MyApplication"
SectionEnd
这假设所有配置文件都存储在 $PROFILE\..
和硬编码 AppData\Roaming
中,并且这些东西可能在所有配置中都不正确。