Merge branch 'bugfix/IDFGH-2036' into 'master'

Fix for Windows Defender PS task hanging (IDF tools installation)

Closes IDFGH-2036

See merge request espressif/esp-idf!6796
This commit is contained in:
Ivan Grokhotkov
2019-12-04 03:00:23 +08:00
5 changed files with 389 additions and 304 deletions

View File

@@ -229,14 +229,14 @@ end;
{ ------------------------------ Start menu shortcut ------------------------------ } { ------------------------------ Start menu shortcut ------------------------------ }
procedure CreateIDFCommandPromptShortcut(); procedure CreateIDFCommandPromptShortcut(LnkString: String);
var var
Destination: String; Destination: String;
Description: String; Description: String;
Command: String; Command: String;
begin begin
ForceDirectories(ExpandConstant('{group}')); ForceDirectories(ExpandConstant(LnkString));
Destination := ExpandConstant('{group}\{#IDFCmdExeShortcutFile}'); Destination := ExpandConstant(LnkString + '\{#IDFCmdExeShortcutFile}');
Description := '{#IDFCmdExeShortcutDescription}'; Description := '{#IDFCmdExeShortcutDescription}';
{ If cmd.exe command argument starts with a quote, the first and last quote chars in the command { If cmd.exe command argument starts with a quote, the first and last quote chars in the command
will be removed by cmd.exe; each argument needs to be surrounded by quotes as well. } will be removed by cmd.exe; each argument needs to be surrounded by quotes as well. }
@@ -267,3 +267,42 @@ begin
Log('Registering IDF Tools executables in Windows Defender: ' + CmdLine); Log('Registering IDF Tools executables in Windows Defender: ' + CmdLine);
DoCmdlineInstall('Finishing ESP-IDF installation', 'Registering IDF Tools executables in Windows Defender', CmdLine); DoCmdlineInstall('Finishing ESP-IDF installation', 'Registering IDF Tools executables in Windows Defender', CmdLine);
end; end;
<event('CurPageChanged')>
procedure CheckWinDefenderAvailable(CurPageID: Integer);
var
bHasWD: Boolean;
szHasWD: String;
szWDPath: String;
listPSModulePath: TStringList;
x: Integer;
begin
if CurPageID = wpSelectTasks then
begin
listPSModulePath := TStringList.Create;
listPSModulePath.Delimiter := ';';
listPSModulePath.StrictDelimiter := True;
listPSModulePath.DelimitedText := GetEnv('PsModulePath');
Log('Checking PSMODULEPATH for Windows Defender module...');
for x:=0 to (listPSModulePath.Count-1) do
begin
szWDPath := listPSModulePath[x] + '\Defender'
bHasWD := DirExists(szWDPath);
if bHasWD then
begin
szHasWD := 'YES (' + szWDPath + ')';
Break;
end
else
szHasWD := 'NO';
end;
Log('CheckWinDefenderAvailable: ' + szHasWD);
WizardForm.TasksList.ItemEnabled[1] := bHasWD;
WizardForm.TasksList.Checked[1] := bHasWD;
end;
end;

View File

@@ -73,16 +73,18 @@ Type: filesandordirs; Name: "{app}\dist"
Type: filesandordirs; Name: "{app}\releases" Type: filesandordirs; Name: "{app}\releases"
Type: filesandordirs; Name: "{app}\tools" Type: filesandordirs; Name: "{app}\tools"
Type: filesandordirs; Name: "{app}\python_env" Type: filesandordirs; Name: "{app}\python_env"
Type: files; Name: "{autostartmenu}\Programs\ESP-IDF\{#IDFCmdExeShortcutFile}"
Type: files; Name: "{autodesktop}\{#IDFCmdExeShortcutFile}"
[Tasks] [Tasks]
Name: createlnk; Description: "Create Desktop shortcut for ESP-IDF Tools Command Line"; Name: createlnk; Description: "Create Start Menu shortcut for the ESP-IDF Tools Command Prompt";
Name: wdexcl; Description: "Register ESP-IDF Tools executables as Windows Defender exclusions (improves compilation speed, requires elevation)"; Name: createdsk; Description: "Create Desktop shortcut for the ESP-IDF Tools Command Prompt";
Name: wdexcl; Description: "Register the ESP-IDF Tools executables as Windows Defender exclusions (improves compilation speed, requires elevation)";
[Run] [Run]
Filename: "{app}\dist\{#PythonInstallerName}"; Parameters: "/passive PrependPath=1 InstallLauncherAllUsers=0 Include_dev=0 Include_tcltk=0 Include_launcher=0 Include_test=0 Include_doc=0"; Description: "Installing Python"; Check: PythonInstallRequired Filename: "{app}\dist\{#PythonInstallerName}"; Parameters: "/passive PrependPath=1 InstallLauncherAllUsers=0 Include_dev=0 Include_tcltk=0 Include_launcher=0 Include_test=0 Include_doc=0"; Description: "Installing Python"; Check: PythonInstallRequired
Filename: "{app}\dist\{#GitInstallerName}"; Parameters: "/silent /tasks="""" /norestart"; Description: "Installing Git"; Check: GitInstallRequired Filename: "{app}\dist\{#GitInstallerName}"; Parameters: "/silent /tasks="""" /norestart"; Description: "Installing Git"; Check: GitInstallRequired
Filename: "{group}\{#IDFCmdExeShortcutFile}"; Flags: postinstall shellexec; Description: "Run ESP-IDF Command Prompt (cmd.exe)"; Check: InstallationSuccessful Filename: "{autostartmenu}\Programs\ESP-IDF\{#IDFCmdExeShortcutFile}"; Flags: postinstall shellexec; Description: "Run ESP-IDF Command Prompt (cmd.exe)"; Check: InstallationSuccessful
[UninstallRun] [UninstallRun]
Filename: "powershell.exe"; \ Filename: "powershell.exe"; \

View File

@@ -122,7 +122,12 @@ begin
if WizardIsTaskSelected('createlnk') then if WizardIsTaskSelected('createlnk') then
begin begin
CreateIDFCommandPromptShortcut(); CreateIDFCommandPromptShortcut('{autostartmenu}\Programs\ESP-IDF');
end;
if WizardIsTaskSelected('createdsk') then
begin
CreateIDFCommandPromptShortcut('{autodesktop}');
end; end;
if WizardIsTaskSelected('wdexcl') then if WizardIsTaskSelected('wdexcl') then

View File

@@ -19,8 +19,6 @@ Param
[String]$logFile [String]$logFile
) )
Import-Module Defender
function Check-Command($cmdname) function Check-Command($cmdname)
{ {
return [bool](Get-Command -Name $cmdname -ErrorAction SilentlyContinue) return [bool](Get-Command -Name $cmdname -ErrorAction SilentlyContinue)
@@ -33,9 +31,18 @@ function Log-Msg($msg, $logF = $null)
[Console]::Out.Flush() [Console]::Out.Flush()
} }
$retVal = 1
Try Try
{ {
#check the Defender module availability
if (!(Get-Module "Defender")) {
Write-Output "Windows Defender module not available, aborting"
[Environment]::Exit(0)
}
Import-Module Defender
#self-elevation support #self-elevation support
$myWindowsID=[System.Security.Principal.WindowsIdentity]::GetCurrent() $myWindowsID=[System.Security.Principal.WindowsIdentity]::GetCurrent()
$myWindowsPrincipal=new-object System.Security.Principal.WindowsPrincipal($myWindowsID) $myWindowsPrincipal=new-object System.Security.Principal.WindowsPrincipal($myWindowsID)
@@ -156,11 +163,17 @@ Try
else { Log-Msg -msg "WARNING: Processed only $cntRemovedTotal out of $(cntRemovedTotal+cntMissedTotal) relevat items" -logF $logFile } else { Log-Msg -msg "WARNING: Processed only $cntRemovedTotal out of $(cntRemovedTotal+cntMissedTotal) relevat items" -logF $logFile }
Log-Msg -msg "`nDone" -logF $logFile Log-Msg -msg "`nDone" -logF $logFile
$retVal = 0
} }
Catch Catch
{ {
if( ![string]::IsNullOrEmpty($logFile) ) { Write-Error -Exception $_.Exception *>> $logFile } if( ![string]::IsNullOrEmpty($logFile) ) { Write-Error -Exception $_.Exception *>> $logFile }
Write-Error -Exception $_.Exception Write-Error -Exception $_.Exception
exit -1 [Environment]::Exit($retVal)
}
Finally
{
[Environment]::Exit($retVal)
} }

View File

@@ -58,7 +58,6 @@ Param
[String]$logFile [String]$logFile
) )
Import-Module Defender
function Check-Command($cmdname) function Check-Command($cmdname)
{ {
@@ -72,9 +71,32 @@ function Log-Msg($msg, $logF = $null)
[Console]::Out.Flush() [Console]::Out.Flush()
} }
$retVal = 1
Try Try
{ {
$bDebug = $false
#parameter sanity check
if( $Args.Count -gt 0 ) {
if( $Args.Count -eq 1 -And $Args[0] -eq "Debug" ) {
$bDebug = $true
}
else {
$Exception = [ArgumentException]::new("Invalid parameters: $Args")
throw $Exception
}
}
#check the Defender module availability
$wdModuleDir = Join-Path -Path $env:SystemRoot -ChildPath "System32\WindowsPowerShell\v1.0\Modules\Defender"
if( -not (Test-Path -Path $wdModuleDir) ) {
Write-Output "Windows Defender module not found, aborting"
[Environment]::Exit($retVal)
}
Import-Module Defender
#self-elevation support #self-elevation support
$myWindowsID=[System.Security.Principal.WindowsIdentity]::GetCurrent() $myWindowsID=[System.Security.Principal.WindowsIdentity]::GetCurrent()
$myWindowsPrincipal=new-object System.Security.Principal.WindowsPrincipal($myWindowsID) $myWindowsPrincipal=new-object System.Security.Principal.WindowsPrincipal($myWindowsID)
@@ -87,17 +109,26 @@ Try
$params = -join( $params, "-", $key, " `"", $PSBoundParameters[$key], "`"" ) $params = -join( $params, "-", $key, " `"", $PSBoundParameters[$key], "`"" )
} }
#running elevated and logFile not set $arguments = ""
if( [string]::IsNullOrEmpty($logFile) ) { foreach($a in $Args) {
$tempFileName = Get-Date -UFormat "%Y%m%d%H%M%s" $arguments = -join( $arguments, "-", $a )
$lf = Join-Path -Path $env:TEMP -ChildPath "WDEspLog$tempFileName.log"
#Write-Output "Logfile: $lf"
} }
#running elevated and logFile not set
$bOwnLogFile = [string]::IsNullOrEmpty($logFile)
if( $bOwnLogFile ) {
$tempFileName = Get-Date -UFormat "%Y%m%d%H%M%s"
$lf = Join-Path -Path $env:TEMP -ChildPath "WDEspLog$tempFileName.log"
Write-Output "Logfile: $lf"
}
else { $lf = $logFile }
$newProcess = new-object System.Diagnostics.ProcessStartInfo "PowerShell" $newProcess = new-object System.Diagnostics.ProcessStartInfo "PowerShell"
$newProcess.Arguments = "-ExecutionPolicy ByPass -File " + $script:MyInvocation.MyCommand.Definition + " " + $params + " -logFile $lf" $newProcess.Arguments = "-ExecutionPolicy ByPass -File " + $script:MyInvocation.MyCommand.Definition + " " + $params + " -logFile $lf " + $arguments
$newProcess.Verb = "RunAs" $newProcess.Verb = "RunAs"
$newProcess.WindowStyle = [System.Diagnostics.ProcessWindowStyle]::Hidden
#show the process window for -Debug
if( !$bDebug ) { $newProcess.WindowStyle = [System.Diagnostics.ProcessWindowStyle]::Hidden }
$proc = [System.Diagnostics.Process]::Start($newProcess) $proc = [System.Diagnostics.Process]::Start($newProcess)
$proc.WaitForExit() $proc.WaitForExit()
@@ -106,24 +137,14 @@ Try
foreach($line in Get-Content $lf) { foreach($line in Get-Content $lf) {
Log-Msg -msg $line Log-Msg -msg $line
} }
Remove-Item $lf
} }
#Write-Output "Process finished with code " $proc.ExitCode if( $bDebug ) { Log-Msg -msg "Process finished with code " + $proc.ExitCode -logF $lf }
exit $proc.ExitCode if( $bOwnLogFile -And !$bDebug) { Remove-Item $lf }
[Environment]::Exit($proc.ExitCode)
} }
#parameter sanity check
if( $Args.Count -gt 0 ) {
$Exception = [ArgumentException]::new("Only named parameters are supported: $Args")
throw $Exception
}
#check WinDefender cmdlets are available
if (!(Check-Command -cmdname 'Add-MpPreference')) {
$Exception = [NotSupportedException ]::new("Windows Defender cmdlets not available")
throw $Exception
}
$pathsToExclude = New-Object 'System.Collections.Generic.List[String]' $pathsToExclude = New-Object 'System.Collections.Generic.List[String]'
$filesToExclude = New-Object 'System.Collections.Generic.List[String]' $filesToExclude = New-Object 'System.Collections.Generic.List[String]'
@@ -138,8 +159,7 @@ Try
$bRmFile = ![string]::IsNullOrEmpty($RmExclFile) $bRmFile = ![string]::IsNullOrEmpty($RmExclFile)
if( !$bAddPath -And !$bAddFile -And !$bRmPath -And !$bRmFile ) { if( !$bAddPath -And !$bAddFile -And !$bRmPath -And !$bRmFile ) {
$Exception = [ArgumentException]::new("Invalid parameter(s): $Args") throw (New-Object -TypeName System.ArgumentException -ArgumentList "Invalid parameter(s)")
throw $Exception
} }
#ADD exclusion paths #ADD exclusion paths
@@ -176,8 +196,7 @@ Try
} }
#default: throw exception #default: throw exception
else { else {
$Exception = [ArgumentException]::new("Mandatory parameter missing") throw (New-Object -TypeName System.ArgumentException -ArgumentList "Mandatory parameter(s) missing")
throw $Exception
} }
@@ -229,10 +248,17 @@ Try
} }
Log-Msg -msg "Done (processed $itemCount items)" -logF $logFile Log-Msg -msg "Done (processed $itemCount items)" -logF $logFile
$retVal = 0
[Environment]::Exit($retVal)
} }
Catch Catch
{ {
if( ![string]::IsNullOrEmpty($logFile) ) { Write-Error -Exception $_.Exception *>> $logFile } if( ![string]::IsNullOrEmpty($logFile) ) { Write-Error -Exception $_.Exception *>> $logFile }
Write-Error -Exception $_.Exception Write-Error -Exception $_.Exception -ErrorAction Stop
exit -1 [Environment]::Exit($retVal)
}
Finally
{
[Environment]::Exit($retVal)
} }