David Bohm

Hay dos frases que definen mi manera de pensar:
Realmente no hemos prestado mucha atención al pensamiento como un proceso; hemos participado en pensamientos, pero sólo hemos prestado atención al contenido, no al proceso.
La capacidad de percibir o pensar de manera diferente es más importante que el conocimiento adquirido.
Ambas son de David Bohm.

sábado, 8 de octubre de 2016

Variable JAVA_HOME siempre actualizada con script Powershell

Aunque ha sido una cuestión de trabajo, he tenido que invertir cierto tiempo personal para definir un procedimiento sencillo, a mi alcance,  y sobretodo que se pueda implantar rápido en ciertos archivos .bat de una aplicación.

La idea es muy básica, aunque estuve estudiando otras posibilidades, coger del registro de Windows la versión actual de Java, y dentro de esta el valor de la variable JavaHome, donde está la ruta del JRE que queremos actualizar en la variable de sistema JAVA_HOME.

Por lo que he ido comprobando es un problema recurrente, al actualizar la versión de Java, cambia la ruta y la variable ya no apunta a donde debería. Pero claro, esto a la hora de gestionarlo en cientos de usuarios y equipos, pues no es como cuando te pasa a ti, que identificas el problema, cambias el valor de la variable y listo.

Bien, la idea es crear un archivo .bat que realizará la llamada a un powershell .ps1 y después realizará la limpieza de archivos temporales. Esto se va a integrar en el lanzamiento de la aplicación, pero esta parte ya no puedo ponerla aquí, se complicaría mucho la entrada.

Veamos el script powershell donde está el meollo de la cuestión. Este sería el archivo .bat que realiza la llama al powershell simplificado y sin los condicionantes que pondría la aplicación que utilizamos.

REM---Comienzo de script .bat---

REM version_java.bat
powershell -noprofile ".\ruta_java.ps1" C:\ruta_java_current.txt C:\ruta_java.txt C:\ruta_java_final.txt
del C:\ruta_jav*.txt

REM---Fin de script .bat---

A continuación el script powershell que realiza el proceso de identificar la versión actual de java, voy a ir poniendo comentarios que no están en el script para que se entienda a rasgos generales que hace cada parte:

#version_java.ps1
#Tomamos los argumentos que nos pasa al .ps1 el script .bat. Esos argumentos son las rutas y nombres de archivos que utilizaremos posteriormente en el script.

$ruta_current=$args[0]
$ruta=$args[1]
$ruta_final=$args[2]

# Obtenemos la version actual, accediendo a la ruta concreta del registro de windows y lo almacenamos en el primer argumento ($ruta_current). Después le hacemos una limpieza quedándonos con lo que nos interesa, que sería un valor tal que 1.8 por ejemplo.

  $ruta_java=get-ItemProperty -Path "HKLM:\SOFTWARE\JavaSoft\Java Runtime Environment" -name CurrentVersion
  #Write-Host $ruta_java
  $ruta_java | Out-File $ruta_current
  (Get-Content -Path $ruta_current) | Where-Object -FilterScript {$_.Trim() -ne '' } | Set-Content -Path $ruta_current
  $texto_current = Get-Content -Path $ruta_current | Select-Object -Last 1
  $texto_current | Out-File $ruta_final
  (Get-Content $ruta_final) | ForEach-Object { $_ -replace "CurrentVersion", "" } | Set-Content $ruta_final
  (Get-Content $ruta_final) | ForEach-Object { $_ -replace ":", "" } | Set-Content $ruta_final
  (Get-Content $ruta_final) | ForEach-Object { $_ -replace " ", "" } | Set-Content $ruta_final
  $texto_current = Get-Content -Path $ruta_final
  #Write-Host $texto_current

# Obtenemos la ruta de la version actual. Ahora ya podemos profundizar un poco mas en la ruta del registro de windows añadiendo el valor obtenido en las lineas anteriores. Vamos a realizar un proceso muy parecido al anterior, una vez obtenida la ruta almacenada en JavaHome, le hacemos una limpieza y finalmente esa ruta la dejamos en una ruta final.

  $ruta_current = "HKLM:\SOFTWARE\JavaSoft\Java Runtime Environment\"+$texto_current
  $ruta_java=get-ItemProperty -Path $ruta_current -name "JavaHome"
  #Write-Host $ruta_java
  $ruta_java | Out-File $ruta
  (Get-Content -Path $ruta) | Where-Object -FilterScript {$_.Trim() -ne '' } | Set-Content -Path $ruta
  $texto = Get-Content -Path $ruta | Select-Object -Last 1
  $texto | Out-File $ruta_final
  (Get-Content $ruta_final) | ForEach-Object { $_ -replace "JavaHome     : ", "" } | Set-Content $ruta_final

  $variable = Get-Content -Path $ruta_final

# Cambiamos las variables de entorno. Una vez que ya tenemos almacenada la ruta exacta, la utilizamos para actualizar la variable JAVA_HOME. Tenemos en cuenta si existe alguna que sea de usuario y la borramos, siempre utilizaremos la variable de entorno pero de máquina.

  [Environment]::SetEnvironmentVariable("JAVA_HOME",$null,"User")
  [Environment]::SetEnvironmentVariable("JAVA_HOME", $variable, "Machine")
  $env:JAVA_HOME = $variable

A partir de aqui lo único que hace el .bat es borrar los archivos temporales.

En principio los resultados son muy buenos en equipos con Windows 7 SP1, veremos si no se estropea con alguna actualización de Java o de Windows.

SaluDOS