web-dev-qa-db-fra.com

Qu'est-ce que et comment corriger l'erreur System.TypeInitializationException?

private static void Main(string[] args)
{
    string str = null;
    Logger.InitUserLogWithRotation();            // <--- error occur
    ...
}

Quand je construis un projet, il n'y a pas d'erreur. Mais quand je l'exécute, il avorte toujours.

J'ai essayé de déboguer le projet, mais une erreur System.TypeInitializationException s'est produite à la première ligne.

J'ai déjà essayé de googler, mais je n'ai trouvé aucune solution.

Il semble que toute variable d'initialisation de code soit fausse, mais ne le trouve pas.

Aidez-moi, s'il vous plaît. Je suis nouveau en C #.

Merci.

※ Voici le code de classe de l'enregistreur

public class Logger
{
    private static int HDLOG_PRIORITY_DEBUG = 4;
    private static int HDLOG_PRIORITY_ERROR = 1;
    private static int HDLOG_PRIORITY_FATAL = 0;
    private static int HDLOG_PRIORITY_INFO = 3;
    private static int HDLOG_PRIORITY_WARNING = 2;
    public static int LOG_LEVEL_DEBUG = 4;
    public static int LOG_LEVEL_ERROR = 2;
    public static int LOG_LEVEL_FATAL = 1;
    public static int LOG_LEVEL_INFO = 5;
    public static int LOG_LEVEL_WARNING = 3;
    private static string s_bstCommonAppData = Path.Combine(s_commonAppData, "XXXX");
    private static string s_bstUserDataDir = Path.Combine(s_bstCommonAppData, "UserData");
    private static string s_commonAppData = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
    private static bool s_consoleLogging = false;
    private static FileStream s_fileStream;
    public static HdLoggerCallback s_HdLoggerCallback;
    private static string s_logDir = null;
    private static string s_logFileName = "XXXX";
    private static string s_logFilePath = null;
    public static int s_logFileSize = 0xa00000;
    private static bool s_loggerInited = false;
    private static string s_logLevels = null;
    private static int s_logRotationTime = 0x7530;
    private static string s_logStringDebug = "DEBUG";
    private static string s_logStringError = "ERROR";
    private static string s_logStringFatal = "FATAL";
    private static string s_logStringInfo = "INFO";
    private static string s_logStringWarning = "WARNING";
    private static int s_processId = -1;
    private static string s_processName = "Unknown";
    private static object s_sync = new object();
    public static int s_totalLogFileNum = 5;
    private static TextWriter writer = Console.Error;

    private static void Close()
    {
        if (!s_consoleLogging)
        {
            writer.Close();
            s_fileStream.Dispose();
            writer.Dispose();
        }
    }

    public static void Debug(string msg)
    {
        Debug("{0}", new object[] { msg });
    }

    public static void Debug(string fmt, params object[] args)
    {
        Print(LOG_LEVEL_DEBUG, s_processName, fmt, args);
    }

    private static void DoLogRotation()
    {
    Label_0000:
        Thread.Sleep(s_logRotationTime);
        try
        {
            lock (s_sync)
            {
                FileInfo info = new FileInfo(s_logFilePath);
                if (info.Length >= s_logFileSize)
                {
                    string destFileName = s_logFilePath + ".1";
                    string path = s_logFilePath + "." + s_totalLogFileNum;
                    if (File.Exists(path))
                    {
                        File.Delete(path);
                    }
                    for (int i = s_totalLogFileNum - 1; i >= 1; i--)
                    {
                        string str3 = s_logFilePath + "." + i;
                        string str4 = s_logFilePath + "." + (i + 1);
                        if (File.Exists(str3))
                        {
                            File.Move(str3, str4);
                        }
                    }
                    File.Move(s_logFilePath, destFileName);
                }
            }
            goto Label_0000;
        }
        catch (Exception)
        {
            goto Label_0000;
        }
    }

    public static void Error(string msg)
    {
        Error("{0}", new object[] { msg });
    }

    public static void Error(string fmt, params object[] args)
    {
        Print(LOG_LEVEL_ERROR, s_processName, fmt, args);
    }

    public static void Fatal(string msg)
    {
        Fatal("{0}", new object[] { msg });
    }

    public static void Fatal(string fmt, params object[] args)
    {
        Print(LOG_LEVEL_FATAL, s_processName, fmt, args);
    }

    private static string GetLogDir(bool userSpecificLog)
    {
        string str;
        if (s_logDir != null)
        {
            return s_logDir;
        }
        try
        {
            if (userSpecificLog)
            {
                str = Path.Combine(s_bstUserDataDir, "Logs");
            }
            else
            {
                str = (string) Registry.LocalMachine.OpenSubKey(@"Software\XXXX").GetValue("LogDir");
            }
        }
        catch (Exception)
        {
            str = Path.Combine(s_bstUserDataDir, "Logs");
        }
        s_logDir = str;
        return str;
    }

    private static string GetPrefix(string tag, string logLevel)
    {
        int managedThreadId = Thread.CurrentThread.ManagedThreadId;
        DateTime now = DateTime.Now;
        return string.Format("{0:D4}-{1:D2}-{2:D2} {3:D2}:{4:D2}:{5:D2}.{6:D3} {7}:{8:X8} ({9}). {10}: ", new object[] { now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second, now.Millisecond, s_processId, managedThreadId, tag, logLevel });
    }

    public static TextWriter GetWriter()
    {
        return new Writer(delegate (string msg) {
            Print(msg);
        });
    }

    private static void HdLogger(int prio, uint tid, string tag, string msg)
    {
        int level = 0;
        if (prio == HDLOG_PRIORITY_FATAL)
        {
            level = LOG_LEVEL_FATAL;
        }
        else if (prio == HDLOG_PRIORITY_ERROR)
        {
            level = LOG_LEVEL_ERROR;
        }
        else if (prio == HDLOG_PRIORITY_WARNING)
        {
            level = LOG_LEVEL_WARNING;
        }
        else if (prio == HDLOG_PRIORITY_INFO)
        {
            level = LOG_LEVEL_INFO;
        }
        else if (prio == HDLOG_PRIORITY_DEBUG)
        {
            level = LOG_LEVEL_DEBUG;
        }
        Print(level, tag, "{0:X8}: {1}", new object[] { tid, msg });
    }

    public static void Info(string msg)
    {
        Info("{0}", new object[] { msg });
    }

    public static void Info(string fmt, params object[] args)
    {
        Print(LOG_LEVEL_INFO, s_processName, fmt, args);
    }

    public static void InitConsoleLog()
    {
        InitLog("-", true, false);
    }

    public static void InitLog(string logFileName, bool userSpecificLog, bool doLogRotation)
    {
        s_loggerInited = true;
        s_HdLoggerCallback = new HdLoggerCallback(Logger.HdLogger);
        s_processId = Process.GetCurrentProcess().Id;
        s_processName = Process.GetCurrentProcess().ProcessName;
        if (logFileName == "-")
        {
            writer = Console.Error;
            s_consoleLogging = true;
        }
        else
        {
            if (logFileName == null)
            {
                logFileName = s_logFileName;
            }
            if (userSpecificLog)
            {
                logFileName = logFileName + "Users";
            }
            string logDir = GetLogDir(userSpecificLog);
            string str2 = string.Format(@"{0}\{1}.log", logDir, logFileName);
            if (!Directory.Exists(logDir))
            {
                Directory.CreateDirectory(logDir);
            }
            s_logFilePath = str2;
            LogLevelsInit();
            lock (s_sync)
            {
                Open();
            }
            if (doLogRotation)
            {
                new Thread(() => DoLogRotation()) { IsBackground = true }.Start();
            }
        }
    }

    public static void InitSystemLog()
    {
        InitLog(null, false, false);
    }

    public static void InitSystemLogWithRotation()
    {
        InitLog(null, false, true);
    }

    public static void InitUserLog()
    {
        InitLog(null, true, false);
    }

    public static void InitUserLogWithRotation()
    {
        InitLog(null, true, true);
    }

    private static bool IsLogLevelEnabled(string tag, string level)
    {
        if (s_logLevels == null)
        {
            return false;
        }
        return (s_logLevels.StartsWith("ALL") || s_logLevels.Contains((tag + ":" + level).ToUpper()));
    }

    private static void LogLevelsInit()
    {
        string name = @"Software\XXXX\Config";
        try
        {
            using (RegistryKey key = Registry.LocalMachine.OpenSubKey(name))
            {
                s_logLevels = (string) key.GetValue("DebugLogs");
            }
        }
        catch (Exception)
        {
            return;
        }
        if (s_logLevels != null)
        {
            s_logLevels = s_logLevels.ToUpper();
        }
    }

    private static void Open()
    {
        if (!s_consoleLogging)
        {
            if (!s_loggerInited)
            {
                InitLog("-", false, false);
                s_loggerInited = true;
            }
            else
            {
                s_fileStream = new FileStream(s_logFilePath, FileMode.Append, FileAccess.Write, FileShare.Delete | FileShare.ReadWrite);
                writer = new StreamWriter(s_fileStream, Encoding.UTF8);
            }
        }
    }

    public static void Print(string msg)
    {
        Print("{0}", new object[] { msg });
    }

    public static void Print(string fmt, params object[] args)
    {
        Print(LOG_LEVEL_INFO, s_processName, fmt, args);
    }

    public static void Print(int level, string tag, string fmt, params object[] args)
    {
        string str = "UNKNOWN";
        if (level == LOG_LEVEL_FATAL)
        {
            str = s_logStringFatal;
        }
        else if (level == LOG_LEVEL_ERROR)
        {
            str = s_logStringError;
        }
        else if (level == LOG_LEVEL_WARNING)
        {
            str = s_logStringWarning;
        }
        else if (level == LOG_LEVEL_INFO)
        {
            str = s_logStringInfo;
        }
        else if (level == LOG_LEVEL_DEBUG)
        {
            str = s_logStringDebug;
        }
        if ((level != LOG_LEVEL_DEBUG) || IsLogLevelEnabled(tag, str))
        {
            lock (s_sync)
            {
                Open();
                writer.WriteLine(GetPrefix(tag, str) + fmt, args);
                writer.Flush();
                Close();
            }
        }
    }

    public static void SetLogDir(string logDir)
    {
        s_logDir = logDir;
    }

    public static void Warning(string msg)
    {
        Warning("{0}", new object[] { msg });
    }

    public static void Warning(string fmt, params object[] args)
    {
        Print(LOG_LEVEL_WARNING, s_processName, fmt, args);
    }

    public delegate void HdLoggerCallback(int prio, uint tid, string tag, string msg);

    public class Writer : TextWriter
    {
        private WriteFunc writeFunc;

        public Writer(WriteFunc writeFunc)
        {
            this.writeFunc = writeFunc;
        }

        public override void WriteLine(string msg)
        {
            this.writeFunc(msg);
        }

        public override void WriteLine(string fmt, object obj)
        {
            this.writeFunc(string.Format(fmt, obj));
        }

        public override void WriteLine(string fmt, object[] objs)
        {
            this.writeFunc(string.Format(fmt, objs));
        }

        public override System.Text.Encoding Encoding
        {
            get
            {
                return System.Text.Encoding.UTF8;
            }
        }

        public delegate void WriteFunc(string msg);
    }
}
33
bTagTiger

A chaque fois qu'une TypeInitializationException est lancée, vérifiez toute la logique d'initialisation du type auquel vous faites référence pour la première fois dans l'instruction où l'exception est levée - dans votre cas: Logger.

La logique d'initialisation inclut: le constructeur statique du type (qui - si je ne l'ai pas manqué - vous avez non _ pour Logger) et l'initialisation du champ.

L'initialisation du champ est à peu près "non critique" dans Logger à l'exception des lignes suivantes:

private static string s_bstCommonAppData = Path.Combine(s_commonAppData, "XXXX");
private static string s_bstUserDataDir = Path.Combine(s_bstCommonAppData, "UserData");
private static string s_commonAppData = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);

s_commonAppData est null au point où Path.Combine(s_commonAppData, "XXXX"); est appelé. En ce qui me concerne, ces initialisations se produisent dans l'ordre exact que vous avez écrit - donc mettez s_commonAppData d'au moins deux lignes;)

30
olydis

System.TypeInitializationException se produit lorsque le code qui est exécuté pendant le processus de chargement du type lève une exception.

Lorsque .NET charge le type, il doit préparer tous ses champs statiques avant la première utilisation du type. Parfois, l'initialisation nécessite l'exécution de code. C'est quand ce code échoue que vous obtenez un System.TypeInitializationException.

Dans votre cas spécifique, les trois champs statiques suivants exécutent du code:

private static string s_bstCommonAppData = Path.Combine(s_commonAppData, "XXXX");
private static string s_bstUserDataDir = Path.Combine(s_bstCommonAppData, "UserData");
private static string s_commonAppData = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);

Notez que s_bstCommonAppData dépend de s_commonAppData, mais il est déclaré en avance de sa dépendance. Par conséquent, la valeur de s_commonAppData est null au moment de l'appel du Path.Combine, entraînant ArgumentNullException. Il en va de même pour les s_bstUserDataDir et s_bstCommonAppData: ils sont déclarés dans l'ordre inverse de l'ordre d'initialisation souhaité.

Réorganisez les lignes pour résoudre ce problème:

private static string s_commonAppData = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
private static string s_bstCommonAppData = Path.Combine(s_commonAppData, "XXXX");
private static string s_bstUserDataDir = Path.Combine(s_bstCommonAppData, "UserData");
15
dasblinkenlight

Ces lignes sont votre problème (ou au moins un de vos problèmes, s’il y en a plus):

private static string s_bstCommonAppData = Path.Combine(s_commonAppData, "XXXX");
private static string s_bstUserDataDir = Path.Combine(s_bstCommonAppData, "UserData");
private static string s_commonAppData = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);

Vous référencez des membres statiques dans les initialiseurs pour d'autres membres statiques. C'est une mauvaise idée, car le compilateur ne sait pas dans quel ordre les initialiser. Par conséquent, lors de l'initialisation de s_bstCommonAppData, le champ dépendant s_commonAppData n'a pas encore été initialisé. Vous appelez donc Path.Combine(null, "XXXX") et cette méthode n'accepte pas les arguments nuls.

Vous pouvez résoudre ce problème en vous assurant que les champs utilisés lors de l'initialisation d'autres champs sont d'abord déclarés:

private static string s_commonAppData = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
private static string s_bstCommonAppData = Path.Combine(s_commonAppData, "XXXX");
private static string s_bstUserDataDir = Path.Combine(s_bstCommonAppData, "UserData");

Ou utilisez un constructeur statique pour ordonner explicitement les assignations:

private static string s_bstCommonAppData;
private static string s_bstUserDataDir;
private static string s_commonAppData;

static Logger()
{
    s_commonAppData = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
    s_bstCommonAppData = Path.Combine(s_commonAppData, "XXXX");
    s_bstUserDataDir = Path.Combine(s_bstCommonAppData, "UserData");
}
4
cdhowie

je. Veuillez vérifier la propriété InnerException de la TypeInitializationException

ii. Cela peut également être dû à une incompatibilité entre les versions d'exécution des assemblys. Veuillez vérifier les versions d'exécution de l'assembly principal (application appelante) et de l'assembly référé.

4
ShivanandSK

J'ai rencontré System.TypeInitializationException en raison d'une erreur différente dans le fichier app.config de mon projet .NET Framework 4. Merci à pStan de m'avoir fait regarder le fichier app.config. Mes configSections ont été correctement définis. Cependant, un élément non défini dans l'une des sections a provoqué la levée de l'exception.

En bout de ligne, des problèmes dans le fichier app.config peuvent générer cette très variable TypeInitializationException.

Une ConfigurationErrorsException plus significative peut être générée par la même erreur dans app.config en attendant d'accéder aux valeurs de configuration jusqu'à ce que vous soyez dans une méthode plutôt qu'au niveau classe du code.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Collections.Specialized;

namespace ConfigTest
{
    class Program
    {
        public static string machinename;
        public static string hostname;
        public static NameValueCollection _AppSettings;

        static void Main(string[] args)
        {
            machinename = System.Net.Dns.GetHostName().ToLower();
            hostname = "abc.com";// System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName()).HostName.ToLower().Replace(machinename + ".", "");
            _AppSettings = ConfigurationManager.GetSection("domain/" + hostname) as System.Collections.Specialized.NameValueCollection;
        }
    }
}
2
Jeff

Si vous avez des attributs personnalisés dans la définition d'applications. bouger ton 

     <configSections> 
     </configSections>

balise vers le premier enfant dans le <confuguration>

1
Telwa Gangnam

Je sais que c'est une question un peu ancienne, mais j'avais récemment une erreur, alors je pensais transmettre ma solution. 

Mes erreurs semblent provenir d'un ancien fichier App.Config et de la mise à niveau "en place" de .Net 4.0 à .Net 4.5.1. 

Lorsque j'ai démarré l'ancien projet après la mise à niveau vers Framework 4.5.1, j'ai obtenu dès le départ l'erreur TypeInitializationException ... sans même pouvoir parcourir une seule ligne de code. 

Après avoir créé un tout nouveau projet wpf à tester, j’ai constaté que le fichier App.Config, plus récent, souhaitait ce qui suit.

  <configSections>
    <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
      <section name="YourAppName.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
    </sectionGroup>
  </configSections>  

Une fois que j'ai laissé tomber ça, j'étais dans les affaires. 

Notez que vos besoins peuvent être légèrement différents. Je voudrais créer un projet factice, consulter le fichier App.Config généré et voir s'il vous manque quelque chose d'autre. 

J'espère que ça aide quelqu'un. Bon codage!

1
pStan

J'ai l'erreur de system.typeintialzationException, ce qui est dû au moment où j'ai essayé de déplacer le fichier comme ceci:

 File.Move(DestinationFilePath, SourceFilePath)

Cette erreur était due au fait que j'avais échangé le chemin, la bonne est:

 File.Move(SourceFilePath, DestinationFilePath)
0
Vishal

La TypeInitializationException est renvoyée comme enveloppe autour de l'exception émise par l'initialiseur de classe. Cette classe ne peut pas être héritée.

TypeInitializationException est également appelé constructeur statique.

0
Hitesh Modha

Avait un problème similaire obtenir la même exception. Il a fallu du temps pour localiser. Dans mon cas, j'avais une classe utilitaire statique avec un constructeur qui lançait l'exception (en l'enveloppant). Donc, mon problème était dans le constructeur statique.

0
Acorax