Gestione degli errori quando non si accede a Visual Studio o al punto di inizio dell'applicazione

2

Ho recentemente aderito a un progetto in cui stiamo estendendo le funzionalità di un'applicazione esterna acquistata dalla nostra azienda.

È un componente aggiuntivo di Office con una console di amministrazione che consente di creare moduli di stile Windows Form con file code-behind e di fornire un unico luogo in cui memorizzare codice comune. Questo può essere piuttosto difficile quando si implementa un codice che sarebbe semplice in un'applicazione Windows Form "normale".

Come posso implementare la gestione globale degli errori in modo che possiamo registrare tutti gli errori?

Non utilizziamo Visual Studio e non abbiamo accesso ai file csproj, quindi non possiamo usare IL weaving / AOP. Non abbiamo accesso al punto di partenza dell'applicazione, quindi non possiamo sottoscrivere eventi di eccezione non gestiti relativi a thread o applicazioni. Sospetto che questo sia già stato sottoscritto nel codice esterno, poiché le eccezioni non gestite sono esposte in una finestra di messaggio di errore personalizzata per impostazione predefinita.

Attualmente sto cercando di estendere le DLL esterne; tuttavia non vedo dove chiamerò il nostro codice esteso.

L'alternativa è passare attraverso ogni metodo e aggiungere un blocco try / catch solo per registrare gli errori, il che mi fa accapponare la pelle! Questo progetto è in corso da un anno senza occuparsi della gestione degli errori, quindi ci vorrà anche molto tempo per implementare questo approccio.

Classe Pseudo-Esempio:

namespace Scriptlets
{
  using System;
  using System.Windows.Forms;

  public partial class NewClient : FormScriptType
  {
    protected override void PageChanged(object sender, PageChangedEventArgs e)
    {
        ChangeAddressLabels();
    }

    ...
  }
}
    
posta Catherine 24.04.2014 - 15:03
fonte

1 risposta

1

Informazioni sulla registrazione - se vuoi risparmiare qualche digitazione di blocchi try/catch , puoi creare un metodo che richiede un Func o Action e avvolge l'esecuzione in un blocco try/catch :

public T ExecuteAndLogIfFail<T>(Func<T> action)
{
    try
    {           
        return action();
    }
    catch (Exception exception)
    {
        Console.WriteLine("Implement your logger here: {0}", exception.Message);
    }
    return default(T);
}

Ora puoi avvolgere il tuo nuovo codice in questo e avrai sempre una gestione delle eccezioni.

Utilizzo del wrapper:

ExecuteAndLogIfFail<Boolean>(() =>
{
    Console.WriteLine("Do something without output");
    return true;
});

var zero = 0;
List<Int32> items = new List<Int32> { 10, 20, 30, 40, 50 };
var result = ExecuteAndLogIfFail<Int32>(() =>
{
    return items.Sum(i => i / 10);
});
Console.WriteLine(result);

ExecuteAndLogIfFail<Boolean>(() =>
{
    result /= zero; // catch and log!
    return true;
});

Se non l'hai già provato, potresti provare a utilizzare l' oggetto AppDomain.CurentDomain e aggancia l' evento di eccezione non gestito :

AppDomain.CurrentDomain.UnhandledException += (s, e) =>
{
    Console.WriteLine("something happened ...");
};

Se hai capito che il nuovo avvio della finestra è racchiuso in un blocco try/catch , puoi provare a modificare (se questo è ok) l'assembly usando Cecil e aggiungi un'istruzione throw nel blocco catch . Una volta ho usato il plug-in Reflexil Reflector per iniettare il codice in un assembly e salvare l'eseguibile modificato - non sono necessari punti di avvio dell'app. Il sito plug-in afferma che funziona anche con Telerik's JustDecompile .

La conclusione è che mantenere sistemi legacy chiusi è PITA. : -)

    
risposta data 25.04.2014 - 19:17
fonte

Leggi altre domande sui tag