- Creación de la clase SoftRegister
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management;
/*
* Se requiere agregar la referencia System.Management
*/
namespace ImplementacionRegistroSoftware
{
/// <summary>
/// Clase para manejar el registro del software
/// </summary>
class GestorRegistro
{
#region Paso 1: Obtener etiqueta de volumen y CPU para generar código máquina
///<summary>
/// Obtiene el número de serie del volumen del disco
///</summary>
///<returns></returns>
public string ObtenerNumeroSerieDisco()
{
ManagementClass mc = new ManagementClass("win32_NetworkAdapterConfiguration");
ManagementObject disk = new ManagementObject("win32_logicaldisk.deviceid=\"c:\"");
disk.Get();
return disk.GetPropertyValue("VolumeSerialNumber").ToString();
}
///<summary>
/// Obtiene el número de serie de la CPU
///</summary>
///<returns></returns>
public string ObtenerNumeroCPU()
{
string strCpu = null;
ManagementClass miCpu = new ManagementClass("win32_Processor");
ManagementObjectCollection coleccionCpu = miCpu.GetInstances();
foreach (ManagementObject objeto in coleccionCpu)
{
strCpu = objeto.Properties["Processorid"].Value.ToString();
}
return strCpu;
}
///<summary>
/// Genera código máquina (combina CPU y disco)
///</summary>
///<returns></returns>
public string ObtenerCodigoMaquina()
{
string strNum = ObtenerNumeroCPU() + ObtenerNumeroSerieDisco();
string strCodigoMaquina = strNum.Substring(0, 24); // Tomar primeros 24 caracteres
return strCodigoMaquina;
}
public int[] clavesNumericas = new int[127]; // Almacena claves de cifrado
public char[] caracteresASCII = new char[25]; // Almacena caracteres ASCII
public int[] valoresASCII = new int[25]; // Almacena valores ASCII
/// <summary>
/// Inicializa las claves de cifrado
/// </summary>
public void InicializarClavesNumericas()
{
for (int i = 1; i < clavesNumericas.Length; i++)
{
clavesNumericas[i] = i % 9; // Secuencia: 0,1,2,3,4,5,6,7,8,0,1,2,3...
}
}
#endregion
#region Paso 2: Generar código de registro basado en el código máquina
///<summary>
/// Genera código de registro a partir del código máquina
///</summary>
///<returns></returns>
public string GenerarCodigoRegistro()
{
InicializarClavesNumericas();
string strCodigoMaquina = ObtenerCodigoMaquina();
for (int i = 1; i < caracteresASCII.Length; i++) // Almacenar código máquina
{
caracteresASCII[i] = Convert.ToChar(strCodigoMaquina.Substring(i - 1, 1));
}
for (int j = 1; j < valoresASCII.Length; j++) // Modificar valores ASCII
{
valoresASCII[j] = Convert.ToInt32(caracteresASCII[j]) + clavesNumericas[Convert.ToInt32(caracteresASCII[j])];
}
string strNombreAscii = ""; // Código de registro
for (int k = 1; k < valoresASCII.Length; k++) // Generar código de registro
{
if ((valoresASCII[k] >= 48 && valoresASCII[k] <= 57) ||
(valoresASCII[k] >= 65 && valoresASCII[k] <= 90) ||
(valoresASCII[k] >= 97 && valoresASCII[k] <= 122)) // Rango: 0-9, A-Z, a-z
{
strNombreAscii += Convert.ToChar(valoresASCII[k]).ToString();
}
else if (valoresASCII[k] > 122) // Mayor que 'z'
{
strNombreAscii += Convert.ToChar(valoresASCII[k] - 10).ToString();
}
else
{
strNombreAscii += Convert.ToChar(valoresASCII[k] - 9).ToString();
}
}
return strNombreAscii;
}
#endregion
}
}
- Agregar evento Load en el formulario principal
private void MainForm_Load(object sender, EventArgs e)
{
#region Verificación de registro del software
GestorRegistro gestorReg = new GestorRegistro();
// Verificar si el software está registrado
RegistryKey llaveRegistro = Registry.CurrentUser.OpenSubKey("SOFTWARE", true)
.CreateSubKey("miSoftware").CreateSubKey("Configuracion");
// Recorrer todos los subelementos
foreach (string strCodigoRegistro in llaveRegistro.GetSubKeyNames())
{
if (strCodigoRegistro == gestorReg.GenerarCodigoRegistro()) // Comparar con código generado
{
this.lblEstadoRegistro.Text = "Software registrado!";
this.btnRegistrar.Enabled = false;
return;
}
}
this.Text = "Software no registrado!";
this.btnRegistrar.Enabled = true;
MessageBox.Show("Está usando la versión de prueba. Puede usarla gratuitamente 30 veces!",
"Información", MessageBoxButtons.OK, MessageBoxIcon.Information);
Int32 contadorUso; // Contador de usos
try
{
// Obtener valor del registro o usar valor por defecto
contadorUso = (Int32)Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\miSoftware",
"ContadorUso", 0);
MessageBox.Show("Ha usado el software " + contadorUso + " veces!",
"Información", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch
{
MessageBox.Show("Bienvenido al software!", "Información",
MessageBoxButtons.OK, MessageBoxIcon.Information);
Registry.SetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\miSoftware",
"ContadorUso", 0, RegistryValueKind.DWord);
}
// Verificar si se puede continuar usando
contadorUso = (Int32)Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\miSoftware",
"ContadorUso", 0);
if (contadorUso < 30)
{
int nuevoContador = contadorUso + 1;
Registry.SetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\miSoftware",
"ContadorUso", nuevoContador);
}
else
{
DialogResult resultado = MessageBox.Show("¡Se ha agotado el período de prueba! ¿Desea registrar el software?",
"Información", MessageBoxButtons.YesNo, MessageBoxIcon.Information);
if (resultado == DialogResult.Yes)
{
FormularioRegistro.estado = false;
this.btnRegistrar_Click(sender, e);
}
else
{
Application.Exit();
}
}
#endregion
}
- Agregar un botón y una etiqueta en el formulario principal
Código para el botón de registro:
private void btnRegistrar_Click(object sender, EventArgs e)
{
FormularioRegistro formularioRegistro = new FormularioRegistro() { };
// formularioRegistro.ShowDialog(); // 【Importante】 sin 'this', el formulario de registro se cierra automáticamente
formularioRegistro.ShowDialog(this);
}
- Solución a problemas de acceso al registro
Solución 1: Modificar propiedades del archivo del programa
Haga clic derecho en el archivo del programa, en el cuadro de diálogo de propiedades, en la pestaña "Compatibilidad":
Marque "Ejecutar este programa como administrador".
Solución 2: Usar System.Diagnostics.Process.Start() (no se puede depurar)
Modifique el código generado por defecto en Program:
static class Program
{
/// <summary>
/// Punto de entrada principal de la aplicación.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
//Application.Run(new MainForm());
#region Reemplazar Application.Run(new MainForm()); con lo siguiente
/**
* Si el usuario actual es administrador, inicia la aplicación directamente
* Si no es administrador, usa un objeto de inicio para asegurar que se ejecute con privilegios de administrador
*/
// Obtener la identidad del usuario de Windows actual
System.Security.Principal.WindowsIdentity identidad = System.Security.Principal.WindowsIdentity.GetCurrent();
System.Security.Principal.WindowsPrincipal principal = new System.Security.Principal.WindowsPrincipal(identidad);
// Verificar si el usuario actual es administrador
if (principal.IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator))
{
// Si es administrador, ejecutar directamente
Application.Run(new MainForm());
}
else
{
// Crear objeto de inicio
System.Diagnostics.ProcessStartInfo infoInicio = new System.Diagnostics.ProcessStartInfo();
infoInicio.UseShellExecute = true;
infoInicio.WorkingDirectory = Environment.CurrentDirectory;
infoInicio.FileName = Application.ExecutablePath;
// Establecer acción de inicio para asegurar ejecución como administrador
infoInicio.Verb = "runas";
try
{
System.Diagnostics.Process.Start(infoInicio); // 【Nota】 este método inicia externamente, no se puede depurar con puntos de interrupción
}
catch
{
return;
}
// Salir
Application.Exit();
}
#endregion
}
}
Solución 3: Solucionar el problema de depuración
En el proyecto, agregue un nuevo elemento: "Archivo de manifiesto de aplicación". Haga clic en "Agregar".
Después de agregar, se abrirá el archivo app.manifest de forma predeterminada. Cambie:
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
a:
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
Luego, abra las propiedades del proyecto, en la pestaña "Aplicación", en "Recursos", cambie "Manifiesto" al app.manifest recién creado.
Vuelva a generar el proyecto. Al abrir el programa, solicitará permisos de administrador.
Nota: Si inicia la depuración en Visual Studio, se mostrará un mensaje que dice: "Esta tarea requiere que la aplicación tenga privilegios elevados". Seleccione "Reiniciar con otras credenciales".