Verificando assemblies em modo debug, v2.0 by Rafael & Henrique

Conversando com dois colegas, o Rafael Marrara e o Henrique da Silva (ambos PFEs de IIS aqui comigo na Microsoft), eles comentaram que fizeram um script muito similar ao que eu havia publicado a algum tempo atrás para identificar aplicações em modo debug.

O interessante é que eles criaram esse script para resolver um pequeno “side effect” da versão inicial que eu havia escrito: o meu script carregava a DLL via powershell, e por consequência ela ficava bloqueada (durante o tempo de execução do script) não podendo sofrer nenhuma alteração.

Com isso, se a aplicação fosse recompilada naquele período de tempo, isso poderia gerar um erro. Além disso, a forma de verificar se os assemplies estão compilados em modo debug foi aperfeiçoada e dados adicionais são exibidos. O resultado final ficou muito bom e por isso eu pedi a autorização deles para publicar o script aqui no blog.

Segue:

 

##

if ($args[0] -eq $null) {
$path = $(Split-Path $MyInvocation.InvocationName)
} else {
if (Test-Path($args[0])) {
$path = $args[0]
} else {
write-host "O diretório" $args[0] "não existe!"
Break
}
}

##

function Get-DotNetDebuggableAttribute
{
[CmdletBinding()]
Param(
[Parameter(
Mandatory=$True,
ValueFromPipeline=$True
)] [string[]]$files
)

    Begin
{
$list = @()
}

    Process
{
foreach ( $filename in $files )
{
if ( Test-Path $filename )
{
$file = Get-Item $filename
if ( $file.Extension -eq '.dll' )
{
try
{
$assembly = [System.Reflection.Assembly]::Load([System.IO.File]::ReadAllBytes($file.FullName))
$file | Add-Member NoteProperty ImageRuntimeVersion $assembly.ImageRuntimeVersion

$modules = $assembly.GetModules($false)
if ($modules.Length -gt 0) {
$portableExecutableKinds = New-Object System.Reflection.portableExecutableKinds
$imageFileMachine = New-Object System.Reflection.imageFileMachine
$modules[0].GetPEKind([ref]$portableExecutableKinds, [ref]$imageFileMachine)

                            $file | Add-Member NoteProperty PortableExecutableKinds $portableExecutableKinds
$file | Add-Member NoteProperty ImageFileMachine $imageFileMachine

                            Switch($portableExecutableKinds.ToString().Split(',').Trim()){
"Required32Bit" {$platformTarget = "x86"}
"PE32Plus" {$platformTarget = "x64"}
"ILOnly" {$platformTarget = "Any CPU"}
default {$platformTarget = "Unknown"}
}

                            $file | Add-Member NoteProperty PlatformTarget $platformTarget

                        } else {
$file | Add-Member NoteProperty PortableExecutableKinds $null
$file | Add-Member NoteProperty ImageFileMachine $null
$file | Add-Member NoteProperty PlatformTarget $null
}

                        $attrs = $assembly.GetCustomAttributes([System.Type]::GetType("System.Diagnostics.DebuggableAttribute"), 0)
if ($attrs.Count -eq 1) {
$attr = $attrs[0]
$file | Add-Member NoteProperty IsJITTrackingEnabled $attr.IsJITTrackingEnabled
$file | Add-Member NoteProperty IsJITOptimizerDisabled $attr.IsJITOptimizerDisabled
} else {
$file | Add-Member NoteProperty IsJITTrackingEnabled $null
$file | Add-Member NoteProperty IsJITOptimizerDisabled $null
}
$list += $file
}
catch
{
Write-Debug "Error trying to access the file using System.Reflection.Assembly"
Write-Debug "Error: $_"
}
}
}
}
}

    End
{
if ( $list.Count -gt 0 )
{
#Write-Output $list | Format-Table Mode, LastWriteTime, Length, Name, IsJITOptimizerDisabled, IsJITTrackingEnabled -AutoSize
return $list
}
}
}

get-childitem $path -Recurse -include *.dll | Get-DotNetDebuggableAttribute | Format-Table LastWriteTime, Name, ImageRuntimeVersion, PlatformTarget, IsJITOptimizerDisabled -AutoSize

Lembrando que este script não é suportado de forma alguma pela Microsoft, use por sua conta e risco.

PS: ele não faz nenhuma alteração no seu ambiente, e portanto, não deveria causar problemas. De qualquer forma, eu recomendo utilizado em ambientes de teste, homologação ou pré-produção.

 

abraços,

Paulo.