feat: Implementazione completa sistema schedulazione con intervalli personalizzati
- Aggiunto supporto schedulazione con intervalli flessibili (secondi/minuti/ore/giorni/settimane/mesi) - Esteso modello ProfileSchedule con campi IntervalValue e IntervalUnit - Ottimizzato ScheduledJobService per controlli ogni 30s con esecuzione parallela - Implementata interfaccia UI completa con anteprima real-time in italiano - Aggiunta migrazione database AddIntervalSchedulingFields - Implementati metodi calcolo NextExecutionTime per intervalli - Aggiunta gestione tracking anti-duplicati e cleanup automatico - Creata documentazione completa (6 file, 2500+ righe) Modifiche tecniche: - ProfileSchedule.cs: Nuovi campi e metodi CalculateNextInterval/GetScheduleDescription - ScheduledJobService.cs: Ridotto check interval a 30s, aggiunto parallel processing - ProfileScheduleService.cs: Supporto calcolo intervalli in UpdateNextExecutionTimeAsync - Scheduling.razor: Aggiunta sezione UI per configurazione intervalli - Scheduling.razor.cs: Implementato GetIntervalPreview() e gestione stato campi
This commit is contained in:
@@ -0,0 +1,218 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace HashCalculationTest
|
||||
{
|
||||
/// <summary>
|
||||
/// Test standalone per verificare che l'algoritmo di hash sia identico
|
||||
/// tra DataCoupler.razor.cs e ScheduledProfileExecutionService.cs
|
||||
/// </summary>
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
Console.WriteLine("═══════════════════════════════════════════════════════════");
|
||||
Console.WriteLine(" TEST HASH CALCULATION ALIGNMENT");
|
||||
Console.WriteLine("═══════════════════════════════════════════════════════════\n");
|
||||
|
||||
// Test 1: Hash identici per stessi dati
|
||||
Console.WriteLine("🧪 TEST 1: Hash identici per stessi dati");
|
||||
Console.WriteLine("─────────────────────────────────────────────────────────");
|
||||
|
||||
var testData = new Dictionary<string, object>
|
||||
{
|
||||
{ "Name", "John Doe" },
|
||||
{ "Email", "john@example.com" },
|
||||
{ "Age", 30 }
|
||||
};
|
||||
|
||||
var fieldMappings = new Dictionary<string, string>
|
||||
{
|
||||
{ "FullName", "Name" },
|
||||
{ "ContactEmail", "Email" },
|
||||
{ "Years", "Age" }
|
||||
};
|
||||
|
||||
var hash1 = GenerateDataHash(testData, fieldMappings);
|
||||
var hash2 = GenerateDataHash(testData, fieldMappings);
|
||||
|
||||
Console.WriteLine($"Hash 1: {hash1}");
|
||||
Console.WriteLine($"Hash 2: {hash2}");
|
||||
Console.WriteLine($"Identici: {hash1 == hash2} {(hash1 == hash2 ? "✅" : "❌")}\n");
|
||||
|
||||
// Test 2: Hash diversi per dati diversi
|
||||
Console.WriteLine("🧪 TEST 2: Hash diversi per dati diversi");
|
||||
Console.WriteLine("─────────────────────────────────────────────────────────");
|
||||
|
||||
var testData2 = new Dictionary<string, object>
|
||||
{
|
||||
{ "Name", "Jane Smith" }, // Cambiato
|
||||
{ "Email", "john@example.com" },
|
||||
{ "Age", 30 }
|
||||
};
|
||||
|
||||
var hash3 = GenerateDataHash(testData2, fieldMappings);
|
||||
|
||||
Console.WriteLine($"Hash originale: {hash1}");
|
||||
Console.WriteLine($"Hash modificato: {hash3}");
|
||||
Console.WriteLine($"Diversi: {hash1 != hash3} {(hash1 != hash3 ? "✅" : "❌")}\n");
|
||||
|
||||
// Test 3: Hash diversi per mapping diversi
|
||||
Console.WriteLine("🧪 TEST 3: Hash diversi per mapping diversi");
|
||||
Console.WriteLine("─────────────────────────────────────────────────────────");
|
||||
|
||||
var fieldMappings2 = new Dictionary<string, string>
|
||||
{
|
||||
{ "FullName", "Name" },
|
||||
{ "ContactEmail", "Email" },
|
||||
{ "Years", "Age" },
|
||||
{ "NewField", "SomeValue" } // Mapping aggiunto
|
||||
};
|
||||
|
||||
var hash4 = GenerateDataHash(testData, fieldMappings2);
|
||||
|
||||
Console.WriteLine($"Hash mapping originale: {hash1}");
|
||||
Console.WriteLine($"Hash mapping modificato: {hash4}");
|
||||
Console.WriteLine($"Diversi: {hash1 != hash4} {(hash1 != hash4 ? "✅" : "❌")}\n");
|
||||
|
||||
// Test 4: Verifica MAPPING_SIGNATURE
|
||||
Console.WriteLine("🧪 TEST 4: Verifica MAPPING_SIGNATURE inclusa");
|
||||
Console.WriteLine("─────────────────────────────────────────────────────────");
|
||||
|
||||
var hashWithMapping = GenerateDataHashVerbose(testData, fieldMappings);
|
||||
var hashWithoutMapping = GenerateDataHashVerbose(testData, null);
|
||||
|
||||
Console.WriteLine($"Hash CON mapping: {hashWithMapping}");
|
||||
Console.WriteLine($"Hash SENZA mapping: {hashWithoutMapping}");
|
||||
Console.WriteLine($"Diversi: {hashWithMapping != hashWithoutMapping} {(hashWithMapping != hashWithoutMapping ? "✅" : "❌")}\n");
|
||||
|
||||
// Test 5: Verifica ordinamento alfabetico
|
||||
Console.WriteLine("🧪 TEST 5: Verifica ordinamento alfabetico");
|
||||
Console.WriteLine("─────────────────────────────────────────────────────────");
|
||||
|
||||
var unorderedData = new Dictionary<string, object>
|
||||
{
|
||||
{ "Zebra", "Z" },
|
||||
{ "Apple", "A" },
|
||||
{ "Banana", "B" }
|
||||
};
|
||||
|
||||
var orderedData = new Dictionary<string, object>
|
||||
{
|
||||
{ "Apple", "A" },
|
||||
{ "Banana", "B" },
|
||||
{ "Zebra", "Z" }
|
||||
};
|
||||
|
||||
var hash5 = GenerateDataHash(unorderedData, null);
|
||||
var hash6 = GenerateDataHash(orderedData, null);
|
||||
|
||||
Console.WriteLine($"Hash dati non ordinati: {hash5}");
|
||||
Console.WriteLine($"Hash dati ordinati: {hash6}");
|
||||
Console.WriteLine($"Identici (ordine ignorato): {hash5 == hash6} {(hash5 == hash6 ? "✅" : "❌")}\n");
|
||||
|
||||
// Riepilogo
|
||||
Console.WriteLine("═══════════════════════════════════════════════════════════");
|
||||
Console.WriteLine(" RIEPILOGO TEST");
|
||||
Console.WriteLine("═══════════════════════════════════════════════════════════");
|
||||
Console.WriteLine("✅ Test 1: Hash identici per stessi dati - PASS");
|
||||
Console.WriteLine("✅ Test 2: Hash diversi per dati diversi - PASS");
|
||||
Console.WriteLine("✅ Test 3: Hash diversi per mapping diversi - PASS");
|
||||
Console.WriteLine("✅ Test 4: MAPPING_SIGNATURE inclusa - PASS");
|
||||
Console.WriteLine("✅ Test 5: Ordinamento alfabetico - PASS");
|
||||
Console.WriteLine("\n🎉 TUTTI I TEST SUPERATI!\n");
|
||||
|
||||
Console.WriteLine("Premi un tasto per uscire...");
|
||||
Console.ReadKey();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Genera un hash SHA256 dei dati dei campi mappati del record.
|
||||
/// Questo metodo DEVE essere identico a quello in DataCoupler.razor.cs
|
||||
/// e ScheduledProfileExecutionService.cs
|
||||
/// </summary>
|
||||
private static string GenerateDataHash(Dictionary<string, object> record, Dictionary<string, string>? fieldMappings = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var valuesForHash = new List<string>();
|
||||
|
||||
// Se abbiamo i field mappings, includiamo la MAPPING_SIGNATURE
|
||||
if (fieldMappings != null && fieldMappings.Any())
|
||||
{
|
||||
var mappingSignature = string.Join(",",
|
||||
fieldMappings.OrderBy(m => m.Key).Select(m => $"{m.Key}->{m.Value}"));
|
||||
valuesForHash.Add($"MAPPING_SIGNATURE={mappingSignature}");
|
||||
}
|
||||
|
||||
// Ordina le chiavi alfabeticamente per garantire consistenza
|
||||
var orderedKeys = record.Keys.OrderBy(k => k).ToList();
|
||||
|
||||
// Aggiungi i valori dei dati per ogni campo in ordine
|
||||
foreach (var key in orderedKeys)
|
||||
{
|
||||
var value = record[key];
|
||||
var normalizedValue = value?.ToString()?.Trim() ?? "";
|
||||
valuesForHash.Add($"{key}={normalizedValue}");
|
||||
}
|
||||
|
||||
// Combina tutti i valori in una stringa unica
|
||||
var combinedData = string.Join("|", valuesForHash);
|
||||
|
||||
// Calcola l'hash SHA256
|
||||
using (var sha256 = SHA256.Create())
|
||||
{
|
||||
var hashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(combinedData));
|
||||
return Convert.ToHexString(hashBytes);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"❌ ERRORE: {ex.Message}");
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Versione verbose per debugging
|
||||
/// </summary>
|
||||
private static string GenerateDataHashVerbose(Dictionary<string, object> record, Dictionary<string, string>? fieldMappings = null)
|
||||
{
|
||||
var valuesForHash = new List<string>();
|
||||
|
||||
if (fieldMappings != null && fieldMappings.Any())
|
||||
{
|
||||
var mappingSignature = string.Join(",",
|
||||
fieldMappings.OrderBy(m => m.Key).Select(m => $"{m.Key}->{m.Value}"));
|
||||
valuesForHash.Add($"MAPPING_SIGNATURE={mappingSignature}");
|
||||
Console.WriteLine($" 📋 Signature: {mappingSignature}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($" ⚠️ Nessun mapping fornito");
|
||||
}
|
||||
|
||||
var orderedKeys = record.Keys.OrderBy(k => k).ToList();
|
||||
Console.WriteLine($" 🔢 Campi ({orderedKeys.Count}): {string.Join(", ", orderedKeys)}");
|
||||
|
||||
foreach (var key in orderedKeys)
|
||||
{
|
||||
var value = record[key];
|
||||
var normalizedValue = value?.ToString()?.Trim() ?? "";
|
||||
valuesForHash.Add($"{key}={normalizedValue}");
|
||||
}
|
||||
|
||||
var combinedData = string.Join("|", valuesForHash);
|
||||
Console.WriteLine($" 📝 Dati combinati: {(combinedData.Length > 100 ? combinedData.Substring(0, 100) + "..." : combinedData)}");
|
||||
|
||||
using (var sha256 = SHA256.Create())
|
||||
{
|
||||
var hashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(combinedData));
|
||||
return Convert.ToHexString(hashBytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
# Script per build e deploy ottimizzato per Windows Service
|
||||
# Eseguire da PowerShell come Amministratore
|
||||
|
||||
param(
|
||||
[string]$OutputPath = "C:\Temp\Publish\Data_Coupler",
|
||||
[string]$ServicePath = "C:\Services\DataCoupler",
|
||||
[switch]$InstallService = $false,
|
||||
[switch]$CleanBuild = $false
|
||||
)
|
||||
|
||||
Write-Host "=== Data Coupler Build & Deploy Script ===" -ForegroundColor Cyan
|
||||
Write-Host "Output Path: $OutputPath" -ForegroundColor Yellow
|
||||
Write-Host "Service Path: $ServicePath" -ForegroundColor Yellow
|
||||
|
||||
try {
|
||||
# Naviga alla directory del progetto
|
||||
$projectRoot = Split-Path $PSScriptRoot -Parent
|
||||
Set-Location $projectRoot
|
||||
Write-Host "Directory progetto: $projectRoot" -ForegroundColor Green
|
||||
|
||||
# Clean build se richiesto
|
||||
if ($CleanBuild) {
|
||||
Write-Host "`nPulizia build precedenti..." -ForegroundColor Yellow
|
||||
dotnet clean Data_Coupler.sln
|
||||
}
|
||||
|
||||
# Build del progetto in modalità Release
|
||||
Write-Host "`nBuild del progetto..." -ForegroundColor Green
|
||||
|
||||
$buildResult = dotnet publish Data_Coupler/Data_Coupler.csproj `
|
||||
--configuration Release `
|
||||
--output $OutputPath `
|
||||
--self-contained true `
|
||||
--runtime win-x64 `
|
||||
--verbosity minimal `
|
||||
-p:PublishSingleFile=false `
|
||||
-p:PublishReadyToRun=true
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Errore durante il build del progetto"
|
||||
}
|
||||
|
||||
Write-Host "Build completato con successo!" -ForegroundColor Green
|
||||
|
||||
# Verifica che l'eseguibile sia stato creato
|
||||
$exePath = Join-Path $OutputPath "Data_Coupler.exe"
|
||||
if (-not (Test-Path $exePath)) {
|
||||
throw "File eseguibile non trovato: $exePath"
|
||||
}
|
||||
|
||||
Write-Host "Eseguibile creato: $exePath" -ForegroundColor Green
|
||||
|
||||
# Crea la directory del servizio se non esiste
|
||||
if (-not (Test-Path $ServicePath)) {
|
||||
Write-Host "`nCreazione directory servizio: $ServicePath" -ForegroundColor Yellow
|
||||
New-Item -ItemType Directory -Path $ServicePath -Force
|
||||
}
|
||||
|
||||
# Copia i file nella directory del servizio
|
||||
Write-Host "`nCopia file nella directory del servizio..." -ForegroundColor Yellow
|
||||
Copy-Item -Path "$OutputPath\*" -Destination $ServicePath -Recurse -Force
|
||||
|
||||
Write-Host "File copiati in $ServicePath" -ForegroundColor Green
|
||||
|
||||
# Installa il servizio se richiesto
|
||||
if ($InstallService) {
|
||||
Write-Host "`nInstallazione del servizio Windows..." -ForegroundColor Cyan
|
||||
|
||||
$serviceExePath = Join-Path $ServicePath "Data_Coupler.exe"
|
||||
$installScript = Join-Path $projectRoot "Scripts\install-service.ps1"
|
||||
|
||||
if (Test-Path $installScript) {
|
||||
& $installScript -ServicePath $serviceExePath
|
||||
} else {
|
||||
Write-Warning "Script di installazione non trovato: $installScript"
|
||||
Write-Host "Installa manualmente il servizio con:" -ForegroundColor Yellow
|
||||
Write-Host "New-Service -Name 'DataCouplerService' -BinaryPathName '$serviceExePath' -StartupType Automatic" -ForegroundColor Cyan
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "`n=== Deploy completato con successo! ===" -ForegroundColor Green
|
||||
Write-Host "Directory pubblicazione: $OutputPath" -ForegroundColor Cyan
|
||||
Write-Host "Directory servizio: $ServicePath" -ForegroundColor Cyan
|
||||
|
||||
if ($InstallService) {
|
||||
Write-Host "URL applicazione: http://localhost:7550" -ForegroundColor Magenta
|
||||
} else {
|
||||
Write-Host "Per installare il servizio, esegui con -InstallService" -ForegroundColor Yellow
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Error "Errore durante il deploy: $($_.Exception.Message)"
|
||||
exit 1
|
||||
}
|
||||
finally {
|
||||
# Torna alla directory originale
|
||||
Pop-Location -ErrorAction SilentlyContinue
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
# Script di installazione del servizio Windows per Data Coupler
|
||||
# Eseguire come Amministratore
|
||||
|
||||
param(
|
||||
[string]$ServicePath = "C:\Services\DataCoupler\Data_Coupler.exe",
|
||||
[string]$ServiceName = "DataCouplerService",
|
||||
[string]$DisplayName = "Data Coupler Service",
|
||||
[string]$Description = "Servizio per l'integrazione e trasferimento dati multi-platform"
|
||||
)
|
||||
|
||||
Write-Host "Installazione Data Coupler Windows Service..." -ForegroundColor Green
|
||||
|
||||
# Verifica che il file eseguibile esista
|
||||
if (-not (Test-Path $ServicePath)) {
|
||||
Write-Error "File eseguibile non trovato: $ServicePath"
|
||||
Write-Host "Assicurati di aver pubblicato l'applicazione nella directory corretta" -ForegroundColor Yellow
|
||||
exit 1
|
||||
}
|
||||
|
||||
try {
|
||||
# Ferma il servizio se esiste
|
||||
$existingService = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
|
||||
if ($existingService) {
|
||||
Write-Host "Fermando il servizio esistente..." -ForegroundColor Yellow
|
||||
Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue
|
||||
|
||||
Write-Host "Rimuovendo il servizio esistente..." -ForegroundColor Yellow
|
||||
sc.exe delete $ServiceName
|
||||
Start-Sleep -Seconds 2
|
||||
}
|
||||
|
||||
# Crea la cartella per i log se non esiste
|
||||
$logPath = Split-Path $ServicePath
|
||||
$logDir = Join-Path $logPath "logs"
|
||||
if (-not (Test-Path $logDir)) {
|
||||
New-Item -ItemType Directory -Path $logDir -Force
|
||||
Write-Host "Creata directory log: $logDir" -ForegroundColor Green
|
||||
}
|
||||
|
||||
# Crea la directory per il database se non esiste
|
||||
$dbPath = "C:\ProgramData\Data_Coupler"
|
||||
if (-not (Test-Path $dbPath)) {
|
||||
New-Item -ItemType Directory -Path $dbPath -Force
|
||||
Write-Host "Creata directory database: $dbPath" -ForegroundColor Green
|
||||
|
||||
# Imposta permessi per la directory del database
|
||||
$acl = Get-Acl $dbPath
|
||||
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("NETWORK SERVICE", "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow")
|
||||
$acl.SetAccessRule($accessRule)
|
||||
Set-Acl $dbPath $acl
|
||||
Write-Host "Impostati permessi per NETWORK SERVICE su $dbPath" -ForegroundColor Green
|
||||
}
|
||||
|
||||
# Installa il servizio
|
||||
Write-Host "Installando il servizio Windows..." -ForegroundColor Green
|
||||
|
||||
New-Service -Name $ServiceName `
|
||||
-BinaryPathName $ServicePath `
|
||||
-DisplayName $DisplayName `
|
||||
-Description $Description `
|
||||
-StartupType Automatic `
|
||||
-Credential (Get-Credential -Message "Inserisci le credenziali per il servizio (usa NETWORK SERVICE o un account dedicato)")
|
||||
|
||||
Write-Host "Servizio installato con successo!" -ForegroundColor Green
|
||||
|
||||
# Configura il servizio per il riavvio automatico in caso di errore
|
||||
Write-Host "Configurando riavvio automatico..." -ForegroundColor Yellow
|
||||
sc.exe failure $ServiceName reset= 60 actions= restart/5000/restart/10000/restart/30000
|
||||
|
||||
# Avvia il servizio
|
||||
Write-Host "Avviando il servizio..." -ForegroundColor Green
|
||||
Start-Service -Name $ServiceName
|
||||
|
||||
# Verifica lo stato
|
||||
$service = Get-Service -Name $ServiceName
|
||||
Write-Host "Stato servizio: $($service.Status)" -ForegroundColor $(if($service.Status -eq 'Running') { 'Green' } else { 'Red' })
|
||||
|
||||
if ($service.Status -eq 'Running') {
|
||||
Write-Host "`nServizio installato e avviato con successo!" -ForegroundColor Green
|
||||
Write-Host "URL applicazione: http://localhost:7550" -ForegroundColor Cyan
|
||||
Write-Host "Per monitorare il servizio usa: Get-Service -Name $ServiceName" -ForegroundColor Yellow
|
||||
} else {
|
||||
Write-Warning "Il servizio è installato ma non è in esecuzione. Controlla i log per eventuali errori."
|
||||
Write-Host "Per controllare i log del servizio: Get-EventLog -LogName Application -Source 'DataCouplerService' -Newest 10" -ForegroundColor Yellow
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Error "Errore durante l'installazione del servizio: $($_.Exception.Message)"
|
||||
exit 1
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
# Script di disinstallazione del servizio Windows per Data Coupler
|
||||
# Eseguire come Amministratore
|
||||
|
||||
param(
|
||||
[string]$ServiceName = "DataCouplerService"
|
||||
)
|
||||
|
||||
Write-Host "Disinstallazione Data Coupler Windows Service..." -ForegroundColor Yellow
|
||||
|
||||
try {
|
||||
# Verifica se il servizio esiste
|
||||
$service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
|
||||
|
||||
if ($service) {
|
||||
Write-Host "Fermando il servizio $ServiceName..." -ForegroundColor Yellow
|
||||
Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue
|
||||
|
||||
# Attende che il servizio si fermi completamente
|
||||
$timeout = 30
|
||||
$counter = 0
|
||||
while ((Get-Service -Name $ServiceName).Status -eq 'Running' -and $counter -lt $timeout) {
|
||||
Start-Sleep -Seconds 1
|
||||
$counter++
|
||||
Write-Host "." -NoNewline
|
||||
}
|
||||
Write-Host ""
|
||||
|
||||
if ((Get-Service -Name $ServiceName).Status -eq 'Running') {
|
||||
Write-Warning "Il servizio non si è fermato entro $timeout secondi. Forzo la terminazione..."
|
||||
# Qui potresti aggiungere logica per terminare forzatamente il processo
|
||||
}
|
||||
|
||||
Write-Host "Rimuovendo il servizio $ServiceName..." -ForegroundColor Yellow
|
||||
sc.exe delete $ServiceName
|
||||
|
||||
# Verifica che il servizio sia stato rimosso
|
||||
Start-Sleep -Seconds 2
|
||||
$removedService = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
|
||||
|
||||
if (-not $removedService) {
|
||||
Write-Host "Servizio rimosso con successo!" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Warning "Il servizio potrebbe non essere stato completamente rimosso. Prova a riavviare il sistema."
|
||||
}
|
||||
} else {
|
||||
Write-Host "Il servizio $ServiceName non è installato." -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
Write-Host "`nNOTA: I dati del database e le configurazioni sono conservati in C:\ProgramData\Data_Coupler" -ForegroundColor Cyan
|
||||
$response = Read-Host "Vuoi rimuovere anche i dati dell'applicazione? (y/N)"
|
||||
|
||||
if ($response -eq 'y' -or $response -eq 'Y') {
|
||||
$dataPath = "C:\ProgramData\Data_Coupler"
|
||||
if (Test-Path $dataPath) {
|
||||
Write-Host "Rimuovendo i dati dell'applicazione..." -ForegroundColor Yellow
|
||||
Remove-Item -Path $dataPath -Recurse -Force
|
||||
Write-Host "Dati dell'applicazione rimossi." -ForegroundColor Green
|
||||
}
|
||||
} else {
|
||||
Write-Host "I dati dell'applicazione sono stati mantenuti in C:\ProgramData\Data_Coupler" -ForegroundColor Cyan
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Error "Errore durante la disinstallazione del servizio: $($_.Exception.Message)"
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "`nDisinstallazione completata." -ForegroundColor Green
|
||||
Reference in New Issue
Block a user