Невозможно загрузить ошибку DLL `e_sqlite3` на платформе без кодаC#

Место общения программистов C#
Ответить
Anonymous
 Невозможно загрузить ошибку DLL `e_sqlite3` на платформе без кода

Сообщение Anonymous »

Я просмотрел Интернет в надежде найти ответ на свой вопрос, но случай особенный, поэтому я обратился за помощью сюда.
Мы используем платформа без кода, где она похожа на дизайнер рабочих процессов Elsa — у вас есть различные узлы, представляющие определенные функции, и вы соединяете узлы вместе, чтобы заставить их выполнять определенные действия, что может быть так же просто, как взять файл и поместить его в другое место. Он также похож на Power Automate от Microsoft.
Платформа написана на C#, и каждый узел рабочего процесса представляет собой сборку класса, упакованную в NuGet. Этот процесс выглядит так: мы, разработчики, создаем класс C# с определенной функциональностью, собираем и упаковываем код в пакет NuGet, а затем загружаем пакет в частный репозиторий NuGet платформы без кода. Пользователи, которые позже захотят использовать нашу функциональность, просто вставляют узел, и платформа загружает NuGet, устанавливает зависимости, запускает Initialize() для класса, а затем остается открытой, слушая триггерные сигналы от других узлов.
Узел, который у меня сейчас есть, отвечает за получение информации из API и использование sqlite для кэширования результатов (назовем его №1). Я могу использовать один или два таких узла в одном рабочем процессе (процессе), и это работает хорошо. Проблема начала возникать, когда я загрузил другой узел (# 2), он работает так же, но вызывает другой API. Что платформа делает с зависимостями, так это то, что для каждого типа узла она устанавливает зависимости один раз, а затем повторно использует их для других узлов того же типа. Это то же самое, что загрузить класс с отражением один раз, а затем вызвать его много раз. Поскольку узел №2 был введен в рабочий процесс, зависимости внедряются дважды (у меня нет доступа к коду платформы, поэтому все, что я пишу о том, как работает платформа, основано на тщательных наблюдениях), во время «загрузки» Microsoft.Data.SQLite< /code> зависимость. Я вижу следующую ошибку:

Невозможно загрузить DLL «e_sqlite3» или одну из ее зависимостей: указанный модуль не найден. . (0x8007007E)

Метод Initialize(), о котором я упоминал ранее, запускается для каждого узла (подумайте об узле как об объекте, который НЕ static), я не заметил проблем, когда он вызывается дважды (это происходит, когда есть два узла №1).
Платформа и узлы работают в NET 6.

Код: Выделить всё

Microsoft.Data.SQLite
имеет версию 8.0.8
Я подозреваю, что проблема может заключаться в том, что во время загрузки пакета происходит взаимодействие с неуправляемым кодом (бинарные файлы SQLitePCL.raw?), который не может обработать этот случай. , но я не уверен.
Ниже приведен код одного из узлов, для второго узла вызов API существенно отличается. Некоторые ненужные части вырезаны.

Код: Выделить всё

[Export(typeof(ICustomProcessAdapter))]
public class Startup : CustomProcessAdapter
{
private bool _isDisposed;
private HttpClient _httpClient;
private SqliteConnection _sqliteConnection;
private bool _useCache;
private string _authKey;

public override async Task InitializeAsync()
{
if (!IsInitialized)
{
NodeParams p = NodeParams.Extract(NodeParamList); // User defined settings

// Validate URL
if (string.IsNullOrWhiteSpace(p.EndpointUrl) || !Uri.TryCreate(p.EndpointUrl, UriKind.Absolute, out var _))
{
throw new ArgumentException("Invalid Endpoint URL.");
}

// Validate Authentication key
if (string.IsNullOrWhiteSpace(p.AuthenticationKey))
{
throw new ArgumentException("Invalid Authentication key.");
}

_authKey = XmlEncodeValue(p.AuthenticationKey);

_httpClient = new HttpClient()
{
DefaultRequestHeaders =
{
{ "Accept", "application/xml" }
}
};

if (!string.IsNullOrWhiteSpace(p.CachePath))
{
if (string.Equals(p.CachePath, ":memory:", StringComparison.OrdinalIgnoreCase))
throw new InvalidOperationException("In-memory database is not supported.");
var filePathSanitized = System.IO.Path.GetFullPath(p.CachePath);

// Initialize SQLite table if it does not exist
SQLitePCL.Batteries_V2.Init();
_sqliteConnection = new($"Data Source={filePathSanitized}");
bool dbFileExists = System.IO.File.Exists(filePathSanitized);
await _sqliteConnection.OpenAsync();

await using (var cmd = _sqliteConnection.CreateCommand())
{
cmd.CommandText = "CREATE TABLE IF NOT EXISTS cache (location_name TEXT PRIMARY KEY, location_signature TEXT, expires_at TEXT)";
await cmd.ExecuteNonQueryAsync();
}

_useCache = true;

if (p.WriteAheadLogging && !dbFileExists)
{
await using var cmd = _sqliteConnection.CreateCommand();
cmd.CommandText = "PRAGMA journal_mode=WAL";
await cmd.ExecuteNonQueryAsync();
}

if (p.InvalidateCache)
{
await using var cmd = _sqliteConnection.CreateCommand();
cmd.CommandText = "DELETE FROM cache";
await cmd.ExecuteNonQueryAsync();
}

}

}

return await base.InitializeAsync();
}

protected override void Dispose(bool disposing)
{
if (_isDisposed)
{
return;
}
if (disposing)
{
_httpClient?.Dispose();
_sqliteConnection?.Dispose();
}

base.Dispose(disposing);
_isDisposed = true;
}

public override async Task[*]>  ProcessMessageAsync(AdapterMessage message)
{
try
{
Tracer.WriteBegin();

// ...

// Check cache
bool cacheExpired = false;
string expiredCacheValue = string.Empty;
if (_useCache)
{
// Reconnect if connection broke
if (_sqliteConnection.State == System.Data.ConnectionState.Closed)
{
await _sqliteConnection.OpenAsync();
}

await using var cmd = _sqliteConnection.CreateCommand();
cmd.CommandText = "SELECT location_signature, expires_at FROM cache WHERE location_name = @location_name";
cmd.Parameters.AddWithValue("@location_name", p.LocationName);

await using var reader = await cmd.ExecuteReaderAsync();
if (await reader.ReadAsync())
{
if (!await reader.IsDBNullAsync(1))
{
var expiresAt = DateTime.ParseExact(reader.GetString(1), "yyyy-MM-ddTHH:mm:ssZ", CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal);
if (expiresAt > DateTime.UtcNow)
{
// ...
}
else
{
cacheExpired = true;
if (p.ReuseExpiredCache && !await reader.IsDBNullAsync(0))
expiredCacheValue = reader.GetString(0);
}
}
else
{
/ ...
}

}
}

// Call API
// ...

// Parse Location signature
// Use XmlReader.
await using var xmlStream = await response.Content.ReadAsStreamAsync();
using var xmlReader = XmlReader.Create(xmlStream, new() { Async = true });
var locationSignature = string.Empty;
if (xmlReader.ReadToFollowing("LocationSignature"))
locationSignature = await xmlReader.ReadElementContentAsStringAsync();

// Cache asset number
if (_useCache)
{
await using var cmd = _sqliteConnection.CreateCommand();
cmd.CommandText = "INSERT OR REPLACE INTO cache (location_name, location_signature, expires_at) VALUES (@location_name, @location_signature, @expires_at)";
cmd.Parameters.AddWithValue("@location_name", p.LocationName);
cmd.Parameters.AddWithValue("@location_signature", string.IsNullOrEmpty(locationSignature) ? DBNull.Value : locationSignature);

var expiresAt = string.IsNullOrEmpty(locationSignature) ? DateTime.UtcNow.AddMinutes(p.CacheNullTime) : DateTime.UtcNow.AddMinutes(p.CacheTime);
cmd.Parameters.AddWithValue("@expires_at", expiresAt.ToString("yyyy-MM-ddTHH:mm:ssZ"));

await cmd.ExecuteNonQueryAsync();
}

// ...
}
catch (Exception ex)
{
Tracer.WriteException(ex);
throw;
}
finally
{
Tracer.WriteEnd();
}
}

private static async Task CreateAPIException(HttpResponseMessage response)
{
return new APIException(
$@"API call failed
Status code: {response.StatusCode}
Reason: {response.ReasonPhrase},
Response content: {await response.Content.ReadAsStringAsync()}");
}

private static string XmlEncodeValue(string value)
{
return System.Security.SecurityElement.Escape(value);
}
}
Я попробовал следующее:
  • Укажите
  • Укажите
  • Вызовите SQLitePCL.Batteries.Init()
  • Вызовите SQLitePCL.Batteries_V2. Init()
  • Проверено, совпадают ли версии зависимостей.
  • Пыталась сослаться на последнюю версию пакета sqlite3.
    < li>Пытался упаковать «отсутствующий» .dll в NuGet.
Я не только пробовал одно за другим из вышеперечисленного, я пробовал различные смеси вышеперечисленного (например, 1, 2 и 4 вместе).

Подробнее здесь: https://stackoverflow.com/questions/790 ... e-platform
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»