SQLite 的 System.AccessViolationException

2024-01-25

现在,我正在处理这个错误:

An unhandled exception of type 'System.AccessViolationException' occurred in Unknown Module.

Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

它没有调用堆栈,因为没有为抛出它的 DLL 加载模块。我有一个应用程序,它枚举整个注册表并尝试将所有键/值保存到 SQLite 数据库文件中,作为注册表快照。它不是贪婪的,因为如果它无法访问某些密钥,那么这些密钥将被丢弃,等等:

using Microsoft.Win32;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data;
using System.Data.SQLite;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace RegistryMonitor
{
    class Program
    {

        static void Main(string[] args)
        {
            GenerateRegistrySnapshot("SnapshotOne.sqlite");
            Console.ReadLine();   
        }

        static void GenerateRegistrySnapshot(string filename)
        {
            File.Delete(filename);
            SQLiteConnection.CreateFile(filename);
            using (SQLiteConnection connection = new SQLiteConnection("Data Source=" + filename + ";Version=3;"))
            {
                connection.Open();
                CreateTable(connection);
                Stopwatch watch = new Stopwatch();
                Console.WriteLine("Started walking the registry into file {0}.", filename);
                watch.Start();
                transaction = connection.BeginTransaction();
                WalkTheRegistryAndPopulateTheSnapshot(connection);
                try
                {
                    transaction.Commit();
                    transaction.Dispose();
                }
                catch { }
                Console.WriteLine("Finished walking the registry and populating the snapshot.");
                watch.Stop();
                Console.WriteLine("Finished walking the registry in {0} seconds.", watch.Elapsed.TotalSeconds);
                connection.Close();
            }
        }

        static void CreateTable(SQLiteConnection connection)
        {
            SQLiteCommand command = new SQLiteCommand("CREATE TABLE Snapshot (ID INTEGER PRIMARY KEY AUTOINCREMENT, RegistryView INTEGER NULL, Path TEXT NULL, IsKey BOOLEAN NULL, RegistryValueKind INTEGER NULL, ValueName TEXT NULL, Value BLOB NULL, HashValue INTEGER NULL)", connection);
            command.ExecuteNonQuery();
        }

        static SQLiteTransaction transaction = null;
        static int insertions = 0;
        static object transactionLock = new object();

        static void AddEntry(SQLiteConnection connection, RegistryPath path)
        {
            SQLiteCommand command = new SQLiteCommand("INSERT INTO Snapshot (RegistryView, Path, IsKey, RegistryValueKind, ValueName, Value, HashValue) VALUES (@RegistryView, @Path, @IsKey, @RegistryValueKind, @ValueName, @Value, @HashValue)", connection);
            command.Parameters.Add("@RegistryView", DbType.Int32).Value = path.View;
            command.Parameters.Add("@Path", DbType.String).Value = path.Path;
            command.Parameters.Add("@IsKey", DbType.Boolean).Value = path.IsKey;
            command.Parameters.Add("@RegistryValueKind", DbType.Int32).Value = path.ValueKind;
            command.Parameters.Add("@ValueName", DbType.String).Value = path.ValueName;
            command.Parameters.Add("@Value", DbType.Object).Value = path.Value;
            command.Parameters.Add("@HashValue", DbType.Int32).Value = path.HashValue;
            command.ExecuteNonQuery();
            lock (transactionLock)
            {
                insertions++;
                if (insertions > 100000)
                {
                    insertions = 0;
                    transaction.Commit();
                    transaction.Dispose();
                    transaction = connection.BeginTransaction();
                }
            }
        }

        private static void WalkTheRegistryAndPopulateTheSnapshot(SQLiteConnection connection)
        {
            List<ManualResetEvent> handles = new List<ManualResetEvent>();
            foreach (RegistryHive hive in Enum.GetValues(typeof(RegistryHive)))
            {
                foreach (RegistryView view in Enum.GetValues(typeof(RegistryView)).Cast<RegistryView>().ToList().Where(x => x != RegistryView.Default))
                {
                    ManualResetEvent manualResetEvent = new ManualResetEvent(false);
                    handles.Add(manualResetEvent);
                    new Thread(() =>
                    {
                        Console.WriteLine("Walking hive {0} in registry view {1}.", hive.ToString(), view.ToString());
                        WalkKey(connection, view, RegistryKey.OpenBaseKey(hive, view));
                        Console.WriteLine("Finished walking hive {0} in registry view {1}.", hive.ToString(), view.ToString());
                        manualResetEvent.Set();
                        Console.WriteLine("Finished setting event for hive {0} in registry view {1}.", hive.ToString(), view.ToString());
                    }).Start();
                }
            }
            ManualResetEvent.WaitAll(handles.ToArray());
        }

        private static void WalkKey(SQLiteConnection connection, RegistryView view, RegistryKey key)
        {
            RegistryPath path = new RegistryPath(view, key.Name);
            AddEntry(connection, path);
            string[] valueNames = null;
            try
            {
                valueNames = key.GetValueNames();
            }
            catch { }
            if (valueNames != null)
            {
                foreach (string valueName in valueNames)
                {
                    RegistryValueKind valueKind = RegistryValueKind.Unknown;
                    try
                    {
                        valueKind = key.GetValueKind(valueName);
                    }
                    catch { }
                    object value = key.GetValue(valueName);
                    RegistryPath pathForValue = new RegistryPath(view, key.Name, valueKind, valueName, value);
                    AddEntry(connection, pathForValue);
                }
            }
            string[] subKeyNames = null;
            try
            {
                subKeyNames = key.GetSubKeyNames();
            }
            catch { }
            if (subKeyNames != null)
            {
                foreach (string subKeyName in subKeyNames)
                {
                    try
                    {
                        WalkKey(connection, view, key.OpenSubKey(subKeyName));
                    }
                    catch { }
                }
            }
        }

        class RegistryPath
        {
            public RegistryView View;
            public string Path;
            public bool IsKey;
            public RegistryValueKind ValueKind;
            public string ValueName;
            public object Value;
            public int HashValue;

            public RegistryPath(RegistryView view, string path)
            {
                View = view;
                Path = path;
                IsKey = true;
                HashValue = (view.GetHashCode() ^ path.GetHashCode()).GetHashCode();
            }

            public RegistryPath(RegistryView view, string path, RegistryValueKind valueKind, string valueName, object value)
            {
                View = view;
                Path = path;
                IsKey = false;
                ValueKind = valueKind;
                ValueName = valueName;
                Value = value;
                if (value != null)
                {
                    HashValue = (view.GetHashCode() ^ path.GetHashCode() ^ valueKind.GetHashCode() ^ valueName.GetHashCode() ^ value.GetHashCode()).GetHashCode();
                }
                else
                {
                    HashValue = (view.GetHashCode() ^ path.GetHashCode() ^ valueKind.GetHashCode() ^ valueName.GetHashCode()).GetHashCode();
                }
            }
        }
    }
}

由于应用程序是线程化的,AddEntry 在事务周围使用并发性。最初,我没有使用插入计数器,但后来我很快意识到,由于我的应用程序是为 x86 构建并使用 .NET Framework 4.5.1,每当应用程序有近 2GB RAM 时,它就会完全冻结,导致我相信这是由于 x86 系统上的 SQLite 中的另一个问题造成的,例如 x86 上 .NET 中集合的 2GB RAM 限制。我使用插入计数器尝试经常提交事务,以免遇到大型事务队列。现在,即使我这样做了,我仍然留下了这个 AccessViolationException。我不确定是什么原因造成的。有人有任何线索吗?完整的代码在这里,您可以将其复制并粘贴到控制台应用程序中并亲自查看。我只是希望你有一个相当强大的注册表。非常感谢您的帮助;提前致谢!


CL. https://stackoverflow.com/users/11654/cl这值得赞扬;他提到SQLite 可以安全地由多个线程使用,前提是两个或多个线程中没有同时使用单个数据库连接 https://www.sqlite.org/threadsafe.html.

这种方法解决了这个问题:

using Microsoft.Win32;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data;
using System.Data.SQLite;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace RegistryMonitor
{
    class Program
    {

        static void Main(string[] args)
        {
            GenerateRegistrySnapshot("SnapshotOne.sqlite");
            Console.ReadLine();   
        }

        static void GenerateRegistrySnapshot(string filename)
        {
            File.Delete(filename);
            SQLiteConnection.CreateFile(filename);
            bool finished = false;
            ConcurrentQueue<RegistryPath> queue = new ConcurrentQueue<RegistryPath>();
            Thread worker = new Thread(() =>
            {
                using (SQLiteConnection connection = new SQLiteConnection("Data Source=" + filename + ";Version=3;"))
                {
                    connection.Open();
                    CreateTable(connection);
                    SQLiteTransaction transaction = connection.BeginTransaction();
                    RegistryPath path;
                    while (!finished)
                    {
                        while (queue.TryDequeue(out path))
                        {
                            AddEntry(connection, path);
                        }
                        Thread.Sleep(100);
                    }
                    transaction.Commit();
                    transaction.Dispose();
                    connection.Close();
                }
            });
            worker.Start();
            Stopwatch watch = new Stopwatch();
            Console.WriteLine("Started walking the registry into file {0}.", filename);
            watch.Start();
            WalkTheRegistryAndPopulateTheSnapshot(queue);
            finished = true;
            worker.Join();
            watch.Stop();
            Console.WriteLine("Finished walking the registry in {0} seconds.", watch.Elapsed.TotalSeconds);
        }

        static void CreateTable(SQLiteConnection connection)
        {
            SQLiteCommand command = new SQLiteCommand("CREATE TABLE Snapshot (ID INTEGER PRIMARY KEY AUTOINCREMENT, RegistryView INTEGER NULL, Path TEXT NULL, IsKey BOOLEAN NULL, RegistryValueKind INTEGER NULL, ValueName TEXT NULL, Value BLOB NULL, HashValue INTEGER NULL)", connection);
            command.ExecuteNonQuery();
        }

        static void AddEntry(SQLiteConnection connection, RegistryPath path)
        {
            SQLiteCommand command = new SQLiteCommand("INSERT INTO Snapshot (RegistryView, Path, IsKey, RegistryValueKind, ValueName, Value, HashValue) VALUES (@RegistryView, @Path, @IsKey, @RegistryValueKind, @ValueName, @Value, @HashValue)", connection);
            command.Parameters.Add("@RegistryView", DbType.Int32).Value = path.View;
            command.Parameters.Add("@Path", DbType.String).Value = path.Path;
            command.Parameters.Add("@IsKey", DbType.Boolean).Value = path.IsKey;
            command.Parameters.Add("@RegistryValueKind", DbType.Int32).Value = path.ValueKind;
            command.Parameters.Add("@ValueName", DbType.String).Value = path.ValueName;
            command.Parameters.Add("@Value", DbType.Object).Value = path.Value;
            command.Parameters.Add("@HashValue", DbType.Int32).Value = path.HashValue;
            command.ExecuteNonQuery();
        }

        private static void WalkTheRegistryAndPopulateTheSnapshot(ConcurrentQueue<RegistryPath> queue)
        {
            List<ManualResetEvent> handles = new List<ManualResetEvent>();
            foreach (RegistryHive hive in Enum.GetValues(typeof(RegistryHive)))
            {
                foreach (RegistryView view in Enum.GetValues(typeof(RegistryView)).Cast<RegistryView>().ToList().Where(x => x != RegistryView.Default))
                {
                    ManualResetEvent manualResetEvent = new ManualResetEvent(false);
                    handles.Add(manualResetEvent);
                    new Thread(() =>
                    {
                        WalkKey(queue, view, RegistryKey.OpenBaseKey(hive, view));
                        manualResetEvent.Set();
                    }).Start();
                }
            }
            ManualResetEvent.WaitAll(handles.ToArray());
        }

        private static void WalkKey(ConcurrentQueue<RegistryPath> queue, RegistryView view, RegistryKey key)
        {
            RegistryPath path = new RegistryPath(view, key.Name);
            queue.Enqueue(path);
            string[] valueNames = null;
            try
            {
                valueNames = key.GetValueNames();
            }
            catch { }
            if (valueNames != null)
            {
                foreach (string valueName in valueNames)
                {
                    RegistryValueKind valueKind = RegistryValueKind.Unknown;
                    try
                    {
                        valueKind = key.GetValueKind(valueName);
                    }
                    catch { }
                    object value = key.GetValue(valueName);
                    RegistryPath pathForValue = new RegistryPath(view, key.Name, valueKind, valueName, value);
                    queue.Enqueue(pathForValue);
                }
            }
            string[] subKeyNames = null;
            try
            {
                subKeyNames = key.GetSubKeyNames();
            }
            catch { }
            if (subKeyNames != null)
            {
                foreach (string subKeyName in subKeyNames)
                {
                    try
                    {
                        WalkKey(queue, view, key.OpenSubKey(subKeyName));
                    }
                    catch { }
                }
            }
        }

        class RegistryPath
        {
            public RegistryView View;
            public string Path;
            public bool IsKey;
            public RegistryValueKind ValueKind;
            public string ValueName;
            public object Value;
            public int HashValue;

            public RegistryPath(RegistryView view, string path)
            {
                View = view;
                Path = path;
                IsKey = true;
                HashValue = (view.GetHashCode() ^ path.GetHashCode()).GetHashCode();
            }

            public RegistryPath(RegistryView view, string path, RegistryValueKind valueKind, string valueName, object value)
            {
                View = view;
                Path = path;
                IsKey = false;
                ValueKind = valueKind;
                ValueName = valueName;
                Value = value;
                if (value != null)
                {
                    HashValue = (view.GetHashCode() ^ path.GetHashCode() ^ valueKind.GetHashCode() ^ valueName.GetHashCode() ^ value.GetHashCode()).GetHashCode();
                }
                else
                {
                    HashValue = (view.GetHashCode() ^ path.GetHashCode() ^ valueKind.GetHashCode() ^ valueName.GetHashCode()).GetHashCode();
                }
            }
        }
    }
}

Edit:甚至可能是这样的(内存使用量非常少)......

using Microsoft.Win32;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data;
using System.Data.SQLite;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace RegistryMonitor
{
    class Program
    {

        static void Main(string[] args)
        {
            GenerateRegistrySnapshot("Snapshot.sqlite");
            Console.ReadLine();   
        }

        static object writeLock = new object();
        static AutoResetEvent writeReady = new AutoResetEvent(false);
        static AutoResetEvent writeCompleted = new AutoResetEvent(false);
        static RegistryPath pathToWrite;

        static void GenerateRegistrySnapshot(string filename)
        {
            File.Delete(filename);
            SQLiteConnection.CreateFile(filename);
            bool finished = false;
            Thread worker = new Thread(() =>
            {
                using (SQLiteConnection connection = new SQLiteConnection("Data Source=" + filename + ";Version=3;"))
                {
                    connection.Open();
                    CreateTable(connection);
                    SQLiteTransaction transaction = connection.BeginTransaction();
                    while (!finished)
                    {
                        writeReady.WaitOne();
                        if (finished)
                        {
                            break;
                        }
                        AddEntry(connection, pathToWrite);
                        writeCompleted.Set();
                    }
                    transaction.Commit();
                    transaction.Dispose();
                    connection.Close();
                }
            });
            worker.Start();
            Stopwatch watch = new Stopwatch();
            Console.WriteLine("Started walking the registry into file {0}.", filename);
            watch.Start();
            WalkTheRegistryAndPopulateTheSnapshot();
            finished = true;
            writeReady.Set();
            worker.Join();
            watch.Stop();
            Console.WriteLine("Finished walking the registry in {0} seconds.", watch.Elapsed.TotalSeconds);
        }

        static void CreateTable(SQLiteConnection connection)
        {
            SQLiteCommand command = new SQLiteCommand("CREATE TABLE Snapshot (ID INTEGER PRIMARY KEY AUTOINCREMENT, RegistryView INTEGER NULL, Path TEXT NULL, IsKey BOOLEAN NULL, RegistryValueKind INTEGER NULL, ValueName TEXT NULL, Value BLOB NULL, HashValue INTEGER NULL)", connection);
            command.ExecuteNonQuery();
        }

        static void AddEntry(SQLiteConnection connection, RegistryPath path)
        {
            SQLiteCommand command = new SQLiteCommand("INSERT INTO Snapshot (RegistryView, Path, IsKey, RegistryValueKind, ValueName, Value, HashValue) VALUES (@RegistryView, @Path, @IsKey, @RegistryValueKind, @ValueName, @Value, @HashValue)", connection);
            command.Parameters.Add("@RegistryView", DbType.Int32).Value = path.View;
            command.Parameters.Add("@Path", DbType.String).Value = path.Path;
            command.Parameters.Add("@IsKey", DbType.Boolean).Value = path.IsKey;
            command.Parameters.Add("@RegistryValueKind", DbType.Int32).Value = path.ValueKind;
            command.Parameters.Add("@ValueName", DbType.String).Value = path.ValueName;
            command.Parameters.Add("@Value", DbType.Object).Value = path.Value;
            command.Parameters.Add("@HashValue", DbType.Int32).Value = path.HashValue;
            command.ExecuteNonQuery();
        }

        private static void WalkTheRegistryAndPopulateTheSnapshot()
        {
            List<ManualResetEvent> handles = new List<ManualResetEvent>();
            foreach (RegistryHive hive in Enum.GetValues(typeof(RegistryHive)))
            {
                foreach (RegistryView view in Enum.GetValues(typeof(RegistryView)).Cast<RegistryView>().ToList().Where(x => x != RegistryView.Default))
                {
                    ManualResetEvent manualResetEvent = new ManualResetEvent(false);
                    handles.Add(manualResetEvent);
                    new Thread(() =>
                    {
                        WalkKey(view, RegistryKey.OpenBaseKey(hive, view));
                        manualResetEvent.Set();
                    }).Start();
                }
            }
            ManualResetEvent.WaitAll(handles.ToArray());
        }

        private static void WalkKey(RegistryView view, RegistryKey key)
        {
            RegistryPath path = new RegistryPath(view, key.Name);
            Write(path);
            string[] valueNames = null;
            try
            {
                valueNames = key.GetValueNames();
            }
            catch { }
            if (valueNames != null)
            {
                foreach (string valueName in valueNames)
                {
                    RegistryValueKind valueKind = RegistryValueKind.Unknown;
                    try
                    {
                        valueKind = key.GetValueKind(valueName);
                    }
                    catch { }
                    object value = key.GetValue(valueName);
                    RegistryPath pathForValue = new RegistryPath(view, key.Name, valueKind, valueName, value);
                    Write(pathForValue);
                }
            }
            string[] subKeyNames = null;
            try
            {
                subKeyNames = key.GetSubKeyNames();
            }
            catch { }
            if (subKeyNames != null)
            {
                foreach (string subKeyName in subKeyNames)
                {
                    try
                    {
                        WalkKey(view, key.OpenSubKey(subKeyName));
                    }
                    catch { }
                }
            }
        }

        private static void Write(RegistryPath path)
        {
            lock (writeLock)
            {
                pathToWrite = path;
                writeReady.Set();
                writeCompleted.WaitOne();
            }
        }

        class RegistryPath
        {
            public RegistryView View;
            public string Path;
            public bool IsKey;
            public RegistryValueKind ValueKind;
            public string ValueName;
            public object Value;
            public int HashValue;

            public RegistryPath(RegistryView view, string path)
            {
                View = view;
                Path = path;
                IsKey = true;
                HashValue = (view.GetHashCode() ^ path.GetHashCode()).GetHashCode();
            }

            public RegistryPath(RegistryView view, string path, RegistryValueKind valueKind, string valueName, object value)
            {
                View = view;
                Path = path;
                IsKey = false;
                ValueKind = valueKind;
                ValueName = valueName;
                Value = value;
                if (value != null)
                {
                    HashValue = (view.GetHashCode() ^ path.GetHashCode() ^ valueKind.GetHashCode() ^ valueName.GetHashCode() ^ value.GetHashCode()).GetHashCode();
                }
                else
                {
                    HashValue = (view.GetHashCode() ^ path.GetHashCode() ^ valueKind.GetHashCode() ^ valueName.GetHashCode()).GetHashCode();
                }
            }
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SQLite 的 System.AccessViolationException 的相关文章

随机推荐

  • Python - calendar.timegm() 与 time.mktime()

    我似乎很难理解这个问题 有什么区别calendar timegm and time mktime 说我有一个datetime datetime如果没有附加 tzinfo 两者不应该给出相同的输出吗 它们不都给出纪元和作为参数传递的日期之间的
  • C++:固定但运行时定义长度数组的向量

    我知道我可以使用 std vector
  • 使用 Linq 从数据表中获取不同的行(多列不同)

    我试图区分多个列并从数据表中获取数据行 但出现错误 Dim query As IEnumerable Of DataRow From row As DataRow In SourceTable AsEnumerable Select row
  • C# 和元数据文件错误

    我使用 MSDN 上的教程创建了自己的小型 C 编译器 但它无法正常工作 我遇到一些错误 然后修复它们 然后我遇到新的 不同的错误 然后修复它们 等等 最新的错误真的让我很困惑 Line number 0 Error number CS00
  • CSS 覆盖规则和特殊性

    我经常对 CSS 覆盖规则感到困惑 一般来说 我意识到更具体的样式表会覆盖不太具体的样式表 并且特异性取决于指定的选择器数量 还有 important关键字 也发挥着作用 因此 这是一个简单的示例 我有一个包含两个表格单元格的表格 表格本身
  • sklearn的MLP Predict_proba函数内部是如何工作的?

    我想了解如何sklearn的 MLP 分类器 https scikit learn org stable modules generated sklearn neural network MLPClassifier html检索其结果pre
  • 将 png 图像转换为有损 avif

    我尝试压缩大约 1MB 的 png 以获得更小的图像 当我使用以下命令将图像压缩为 jpeg 时 for i in card png do convert resize 445x625 background white flatten i
  • Metro 应用程序中的 ListView 没有垂直滚动条

    我对 Windows Store 又名 Metro 应用程序 XAML 没有经验 所以也许我忽略了一些简单的东西 但根据书籍和示例 垂直滚动条是 ListView 控件的自然组成部分 除非明确禁用 否则会在出现时显示是 ListView 中
  • 获取画布中两点之间的距离

    我有画布绘图选项卡 并希望 lineWidth 基于最后两次鼠标移动坐标更新之间的距离 我将自己将距离转换为宽度 我只需要知道如何获得这些点之间的距离 我已经有了这些点的坐标 你可以用毕达哥拉斯定理来做 如果有两个点 x1 y1 和 x2
  • Python 和 Rust 之间零拷贝共享 Polars 数据帧的示例?

    我有一个Python函数 例如 def add data input df 对 input df Polars 数据框 进行一些操作 例如用新值填充某些列 我想在 Rust 函数中使用这个函数 input df 可能有几十兆字节大 所以我想
  • 使用 process.start 打开文本文件

    在计算皮尔逊相关并将结果写入文本文件后 我一直试图从系统中打开一个文本文件 但到目前为止 由于某种原因 代码没有打开任何记事本文件 我尝试打开其他文件 它们可以工作很好 但 txt 文件没有专门打开 甚至 docx 文件也使用相同的代码打开
  • 允许递归构造函数可能有什么好处(如果有)?

    在 Java 中 构造函数不能是递归的 编译时错误 递归构造函数调用 假设我们没有这个限制 要记住的事情 构造函数的返回类型为 void 由于它是一个 void 方法 因此您无法利用递归的完整功能 构造函数可以使用 this 调用自身 或任
  • FileChannel#force 和缓冲

    我现在想澄清一下 并在 FileOutputStream 和 FileChannel 之间画出一些相似之处 所以首先 似乎使用标准 Java io 写入文件的最有效方法是使用用 BufferedOutputStream 包装的 FileOu
  • WPF MVVM取消窗口关闭

    我是 WPF 和 MVVM 新手 我想最小化窗口而不是关闭它 换句话说 我想取消Closing窗口事件并最小化该窗口 我应该如何以 MVVM 方式进行操作 如果相关的话 最后我会设置ShowInTaskbar to false并使用WinF
  • 刷新有嵌套路由的页面时出现“404 not found”,因为Vite没有将所有路由重定向到index.html

    我可以使用 React 路由器useNavigate钩子去一个嵌套的路线 比如localhost 3000 nested route 但是一旦重新加载 我就会收到 404 未找到错误 因为它正在尝试查找localhost 3000 nest
  • 键绑定的 Atom 数据语法

    有人可以完整解释 Atom 的数据语法属性 用于键绑定选择器 的语法吗 例如 有什么区别 data grammar source example and data grammar source example 另外 如何指定多种语法 例如
  • 删除重复项,但忽略空值

    所以我知道你可以使用类似的方法来删除重复的行 the data drop duplicates subset the key 然而 如果the key对于某些值来说为 null 如下所示 the key C D 1 NaN 2 NaN 3
  • Swift 包管理器找不到模块

    我正在尝试熟悉 Swift 包管理器 这就是我所做的 swift package init type executable 在 Package swift 中添加了依赖项 swift build 一切都很好 但在我尝试之后import De
  • 禁用反应形式的输入字段

    我已经尝试遵循此处其他答案的示例 但没有成功 我创建了一个反应式表单 即动态 并且我想在任何给定时间禁用某些字段 我的表单代码 this form this fb group name Validators required options
  • SQLite 的 System.AccessViolationException

    现在 我正在处理这个错误 An unhandled exception of type System AccessViolationException occurred in Unknown Module Additional inform