Donde se esconden los programas de inicio en Windows 10

En ocasiones algunos programas o malware se resisten a desaparecer de la pestaña "Inicio" del administrador de tareas, tienen donde esconderse.
Deberemos revisar el el registro de Windows (regedit.exe) las siguientes rutas:

HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run

HKEY_CURRENT_USER\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run
HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run

HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\Run
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\Run

Y en el explorador de ficheros:
%ProgramData%\Microsoft\Windows\Start Menu\Programs\Startup
%Appdata%\Microsoft\Windows\Start Menu\Programs\Startup





Evaluar migración a .NET Core

Tarde o temprano nos encontraremos con la migración de frameworks/tecnologías y .NET no iba a ser una excepción. Utilizaremos la herramienta .NET Portability Analyzer para un primer vistazo a nuestras librerías y aplicaciones teniendo como objetivo aplicaciones multiplataforma, microservicios, dockers... en la nube.

Debemos tener claro antes de empezar, la recomendación general de Microsoft actualmente es utilizar .NET Core si tenemos que añadir nuevas funcionalidades en background, por el momento .NET Framework y .NET Core son complementarias. La mayor parte de las API de .NET Core se comparten con .NET Framework

Aclarado esto, con la extensión para Visual Studio 2019 instalada ya podemos iniciar el análisis que nos ayudará a identificar las dependencias externas. Dentro de la configuración de la extensión podemos fijar nuestro objetivo. Todas las acciones tienen su equivalente en línea de comandos.

 

Con el botón derecho sobre el proyecto o solución iniciamos el análisis, con el resultado (en excel en este caso):

Obtenemos los porcentajes de las API de .NET Framework que estarán disponibles en cada plataforma que tengamos seleccionada:

Para revisar en profundidad, en la pestaña "Detalles" podemos ver las librerías/ensamblados no soportados para cada versión:

Los ensamblados que faltan y no han podido ser analizados en esta ejecución, deberemos incluirlos o buscar la versión más reciente:

En cualquier caso y previo a este trabajo siempre es bueno revisar las Métricas de código del proyecto propias de Visual Studio o de terceros:

  • Índice de mantenimiento
  • Complejidad ciclomática
  • Profundidad de herencia
  • Acoplamiento de clases

 

C# 9: propiedades iniciales y datos

Desde el año 2000 han sido muchas las modificaciones y mejoras en el lenguaje, a veces cuesta acostumbrarse a estas nuevas funcionalidades, veamos que nos depara 20 años después:

Es posible declarar el valor de propiedades en el momento de creación de un objeto, no es posible modificar a posteriori estos valores.

public class Vehiculo
{
    public string Marca { get; init; }
    public string Modelo { get; init; }
}

Por tanto, si todas las propiedades de un objeto con valores primitivos (int, double...) son de solo lectura (inmutables), nos acercamos a la definición de estructura (struct). Recordemos que las estructuras contienen valores y las clases referencias a valores, el ejemplo básico:

struct Vehiculo
{  
    public int Potencia;  
    public Vehiculo(int pot)  
    {  
        this.Potencia = pot;  
    }  
}  

Vehiculo a = new Vehiculo(120);  
Vehiculo b = a;  
a.Potencia = 200;  

System.Console.WriteLine(b.Potencia);

El resultado que se muestra siendo una estructura es de 120, si definimos como clase se mostraría 200. [que recuerdos de punteros ;)]

Volvamos a las novedades teniendo claras las diferencias, podemos utilizar la declaración data para las clases, aunque realmente estaremos hablando de solo DATOS:

public data class Vehiculo
{
    public string Marca { get; init; }
    public string Modelo { get; init; }
}

Pero podremos definirlos de manera rápida y equivalente:

public data class Vehiculo { string Marca; string Modelo}

Tampoco parece un gran avance... pero se añaden más características. Podemos realizar una copia del datos modificando solo una parte de manera rápida:

var vehiculo1 = new Vehiculo
{
    Marca = "Honda",
    Modelo = "Civic"
};

var vehiculo2 = vehiculo1 with { Modelo = "NSX" };

Existe un constructor por defecto que permite realizar una copia de todas las propiedades.

protected Vehiculo(Vehiculo original)

El comportamiento por defecto, cuando comparamos objetos que han sido modificados/copiados puede llegar a la situación en la que sean objectos diferentes pero el contenido sea el mismo, siguiendo con el ejemplo modificamos de nuevo la propiedad:

var vehiculo3 = vehiculo2 with { Modelo = "Civic" };

Equals(vehiculo3, vehiculo1); // TRUE
ReferenceEquals(vehiculo3, vehiculo1); // FALSE

Vamos a añadir herencia para acercarnos a escenarios reales:

public data class Vehiculo { string Marca; string Modelo}
public data class Coche : Vehiculo { string Matricula}

Vehiculo v1 = new Vehiculo {Marca = "Honda, Modelo = "Civic"}
Vehiculo v2 = new Coche {Marca = "Honda, Modelo = "Civic", Matricual = "0000LGS"}

En este caso, si comparamos v1 con v2 ¿serán iguales? C# utiliza una propiedad virtual protegida llamada "EqualityContract", cada registro derivado lo anula por lo que para poder comprar los dos objetos deben tener el mismo "EqualityContract"

Basado en las notas de Mads Togersen