Подтвердить что ты не робот

Что такое и как исправить ошибку System.TypeInitializationException?

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

Когда я создаю проект, он не имеет ошибки. Но когда я его выполняю, он всегда прерывается.

Я попытался отладить проект, но в первой строке произошла ошибка System.TypeInitializationException.

Я уже пробовал искать в Google, но не нашел решения.

Кажется, что любой код инициализации переменной ошибочен, но не может найти его.

Пожалуйста, помогите мне. Я новичок в С#.

Спасибо.

※ Вот код класса Logger

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);
    }
}
4b9b3361

Ответ 1

Всякий раз, когда вызывается TypeInitializationException, проверяйте всю логику инициализации типа, к которому вы обращаетесь в первый раз в инструкции, в которой вызывается исключение - в вашем случае: Logger.

Логика инициализации включает в себя: статический конструктор типа (который - если бы я не пропустил его - вы не для Logger) и инициализации поля.

Инициализация поля в значительной степени "некритична" в Logger, за исключением следующих строк:

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 null в точке, где вызывается Path.Combine(s_commonAppData, "XXXX");. Насколько мне известно, эти инициализации происходят в точном порядке, на который вы их написали, поэтому поместите s_commonAppData вверх по крайней мере двумя строками;)

Ответ 2

System.TypeInitializationException происходит, когда код, который запускается во время загрузки типа, выдает исключение.

Когда .NET загружает тип, он должен подготовить все свои статические поля до того, как вы впервые используете этот тип. Иногда инициализация требует запуска кода. Когда этот код выходит из строя, вы получаете System.TypeInitializationException.

В вашем конкретном случае следующие три статических поля запускают некоторый код:

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_bstCommonAppData зависит от s_commonAppData, но объявляется перед его зависимостью. Поэтому значение s_commonAppData равно null во время вызова Path.Combine, в результате чего ArgumentNullException. То же самое относится к s_bstUserDataDir и s_bstCommonAppData: они объявляются в обратном порядке до нужного порядка инициализации.

Переупорядочить строки, чтобы исправить эту проблему:

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");

Ответ 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);

Вы ссылаетесь на некоторые статические члены в инициализаторах для других статических членов. Это плохая идея, поскольку компилятор не знает, в каком порядке их инициализировать. Результатом является то, что во время инициализации s_bstCommonAppData зависимое поле s_commonAppData еще не было инициализировано, поэтому вы вызываете Path.Combine(null, "XXXX"), и этот метод не принимает нулевые аргументы.

Вы можете исправить это, убедившись, что сначала будут объявлены поля, используемые при инициализации других полей:

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");

Или используйте статический конструктор для явного упорядочения назначений:

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

я. Проверьте свойство InnerException TypeInitializationException

II. Кроме того, это может произойти из-за несоответствия между версиями версий сборки. Проверьте версии исполнения основной сборки (вызывающего приложения) и указанной сборки

Ответ 5

Я испытал System.TypeInitializationException из-за другой ошибки в моем проекте .NET framework 4 project.config. Спасибо, pStan за то, что заставил меня посмотреть приложение app.config. Мои конфигурации были правильно определены. Однако элемент undefined в одном из разделов вызывал исключение исключения.

Нижняя строка заключается в том, что проблемы в app.config могут создать этот очень вводящий в заблуждение TypeInitializationException.

Более значимый ConfigurationErrorsException может быть сгенерирован той же ошибкой в ​​app.config, ожидая доступа к значениям конфигурации до тех пор, пока вы не будете в пределах метода, а не на уровне класса кода.

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;
        }
    }
}

Ответ 6

Если у вас есть пользовательские атрибуты в appsetting. переместите

     <configSections> 
     </configSections>
тег

для первого дочернего элемента в <confuguration>.

Ответ 7

TypeInitializationException, который создается как обертка вокруг исключения, созданного инициализатором класса. Этот класс нельзя унаследовать.

TypeInitializationException также называют статическими конструкторами.

Ответ 8

У меня есть ошибка system.typeintialzationException, из-за которой я попытался переместить файл, например:

 File.Move(DestinationFilePath, SourceFilePath)

Эта ошибка произошла из-за того, что я поменял путь на самом деле, правильный:

 File.Move(SourceFilePath, DestinationFilePath)

Ответ 9

Я знаю, что это немного старый вопрос, но у меня недавно была эта ошибка, поэтому я решил передать свое решение.

Мои ошибки, похоже, связаны с старым файлом App.Config и обновлением "на месте" с .Net 4.0 до .Net 4.5.1.

Когда я запустил старый проект после обновления до Framework 4.5.1, я получил исключение TypeInitializationException... сразу с места в карьер... даже не смог выполнить одну строку кода.

После создания совершенно нового проекта wpf для тестирования я обнаружил, что новый файл App.Config нуждается в следующем.

  <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>  

Как только я бросил это, я был в бизнесе.

Обратите внимание, что ваша потребность может немного отличаться. Я бы создал фиктивный проект, проверил сгенерированный файл App.Config и посмотрел, нет ли у вас чего-либо еще.

Надеюсь, это поможет кому-то. Счастливое кодирование!

Ответ 10

Если у вас возникли проблемы с одинаковым исключением. Потратил некоторое время на поиск. В моем случае у меня был статический класс утилиты с конструктором, который бросил исключение (обертывание). Поэтому моя проблема была в статическом конструкторе.

Ответ 11

У меня была эта проблема. Как было сказано, это, вероятно, статическая декларация. В моем случае это было потому, что у меня была статика в предложении DEBUG. Это (в С#)

#if DEBUG
    public static bool DOTHISISINDEBUGONLY = false;
#endif

Все работало нормально, пока я не выполнил версию версии Release, и после этого я получил эту ошибку - даже в старых версиях кода. Как только я взял переменную из предложения DEBUG, все вернулось в норму.