Winforms app runs fine from bin/debug or bin/release, but not outside

huangapple go评论64阅读模式
英文:

Winforms app runs fine from bin/debug or bin/release, but not outside

问题

我已经开发了一个Winforms C#应用程序(.NET Framework 4.8),以前一切都正常。最后一次更改,我决定使用 Gmap.NET 添加了一个地图控件。一开始一切都看起来正常,在调试时一切正常,于是尝试构建发布版本(重要说明:我的解决方案包含2个项目 - 第一个包含Winform应用程序,第二个是使用Microsoft Visual Studio Installer Projects 2022扩展创建的安装项目)。

从那个起点:

  1. 发布构建成功。安装新版本后,启动时崩溃(启动画面短暂显示,然后消失,主窗体不加载)。
  2. 我进行了一些研究,看起来GMap.net存在一些问题,我不得不手动编辑.csproj文件以正确获取所有依赖项(在此问题中有解释)。
  3. 显然,还有其他引用错误,因为它仍然无法正常工作。我清理了解决方案的NuGet包和引用的dll。

当前状态:

  • 没有抛出异常。程序在调试模式下正常运行。
  • 如果我在Winform项目的bin/debug或bin/release中点击.exe文件,程序也能正常运行。
  • 如果我将整个bin/debug或bin/release复制到其他位置并从那里启动,程序会在启动时挂起。
  • 如果我安装并正常启动程序,程序会在启动时崩溃。

我感到困惑。我尝试过使用程序集日志绑定查看器,但只有一些关于XML.Serialzers的消息,根据这个问题来看,可以忽略它们。我尝试过在没有“只有我的代码”选项的情况下进行调试,但我没有看到任何信息。我还在我的代码中加入了写入日志文件的代码,我可以看到:

  • 从bin(调试或发布)文件夹的副本启动时,程序将日志记录,就好像它已完全初始化,但主窗体挂起,不显示控件。
  • 从bin(调试或发布)文件夹启动后,按预期运行。
  • 从安装路径启动时,程序会立即崩溃,并且日志显示跟踪一直到对InitializeComponent()的调用:
public Form1()
{
    using (StreamWriter sw = File.AppendText(Application.UserAppDataPath + @"\mainlog.txt"))
    {
        sw.WriteLine("Initializing Form 1 components");
    }

    InitializeComponent();

    using (StreamWriter sw = File.AppendText(Application.UserAppDataPath + @"\mainlog.txt"))
    {
        sw.WriteLine("Form 1 components initialized");
    }
}

确切地说,日志文件中的最后一条消息是“Initializing Form 1 components”,但如果我尝试在InitializeComponent()内逐步进行调试,我看不到异常,并且它可以正常工作(与在Visual Studio的调试模式下一样)。

我怀疑我的某些代码引用了一个DLL,当在bin文件夹之外运行时,无法找到它。然而,它应该包含在安装程序中,我找不到任何异常(尝试在周围放置一些try-catch块也没有成功)或给我提示的消息。所以我愿意尝试任何选项...只要友善和建设性,因为我是一个超出自己舒适区域的硬件工程师,我的一些代码可能混乱。如果需要,我可以根据要求粘贴特定的代码块,但整个应用程序现在大约有30,000行代码,所以最好是具体(这也是为什么我不想将其扔进垃圾桶并重新开始的原因)。

编辑1: 根据@Deolus的评论,我再次查看事件查看器,看到了这个:

Application: DatacardGenerator.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.DllNotFoundException
   at System.Data.SQLite.UnsafeNativeMethods.sqlite3_libversion()
   at GMap.NET.CacheProviders.SQLitePureImageCache.Ping()
   at GMap.NET.WindowsForms.GMapControl..cctor()

Exception Info: System.TypeInitializationException
   at GMap.NET.WindowsForms.GMapControl..ctor()
   at WindowsFormsApp2.Form1.InitializeComponent()
   at WindowsFormsApp2.Form1..ctor()
   at WindowsFormsApp2.MyApp.OnCreateMainForm()
   at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
   at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
   at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(System.String[])
   at WindowsFormsApp2.Program.Main(System.String[])
英文:

I have developed a Winforms C# app (.NET Framework 4.8), which used to run fine. Last change, I decided to add a Map control using Gmap.NET. At first everything looked fine, in debug, so gave it a go, and built a release version (IMPORTANT NOTE: my solution has 2 Projects - the first contains the Winform app, and the second is a Setup Project created with the Microsoft Visual Studio Installer Projects 2022 extension).

From that starting point:

  1. The Release build was succesful. Installed the new version --> crashes on start (splash screen briefly shows, and then disappears. Main form does not load)
  2. I did some research, and it looks like GMap.net has some issues, and I had to manually edit the .csproj file to get all dependencies right (explained in this question)
    3.Apparently some other reference was wrong, as it was still not working. I cleaned up Nuget packages for the solution, as well as referenced dlls

Current status:

  • No exception thrown. Program runs fine on debug mode
  • Program runs fine if I click on the .exe in bin/debug or bin/release of the Winform project
  • Program hangs on start f I copy the whole bin/debug or bin/release to other location and start from there
  • Program crashes on start if I install it and launch normally

I am at a loss here. I have tried Assembly Log Binding Viewer but only some messages about XML.Serialzers there and, according to this question it is fine to ignore them. I have tried debugging without the "Just my code" option, but I do not see anything there. I have also populated my code with writes to a log file and I can see there that:

  • When launched from a copy of the bin (debug or release)folder elsewhere, the program writes the log as if it was completely initialized, but the main form is hung and does not show the controls

  • When launched from the bin (debug or release) folder, runs as intended

  • When launched from the instalation path it crashes immediately and the log shows traces up to the call to InitializeComponent() :

public Form1()
        {
            using (StreamWriter sw = File.AppendText(Application.UserAppDataPath + @"\mainlog.txt"))
            {
                sw.WriteLine("Initializing Form 1 components");
            }

            InitializeComponent();

            using (StreamWriter sw = File.AppendText(Application.UserAppDataPath + @"\mainlog.txt"))
            {
                sw.WriteLine("Form 1 components initialized");
            }

to be precise, last message in the log file is "Initializing Form 1 components" but, if I try to debug step by step inside InitializeComponent() I see no exception, and it works (as always in DEbug mode from Visual Studio)

I am suspecting that some of my code is referencing a DLL and, when it is run outside the bin folder, it cannot find it. It should be included by the installer, though, and I am not able to find any exception (tried placing some try-catch blocks around to no avail) or message giving me a hint. So I am open to test any options... just be kind and constructive, as I am a HW guy out of his comfort zone, and some of my code might be a mess. I can paste specific code blocks per request, but the whole app is now sitting at roughly 30K lines, so we better be specific (also that is the reason I don not throw this into the bin and start all over).

EDIT1: after @Deolus comment, I looked again in the Event Viewer and I see this:

Application: DatacardGenerator.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.DllNotFoundException
   at System.Data.SQLite.UnsafeNativeMethods.sqlite3_libversion()
   at GMap.NET.CacheProviders.SQLitePureImageCache.Ping()
   at GMap.NET.WindowsForms.GMapControl..cctor()

Exception Info: System.TypeInitializationException
   at GMap.NET.WindowsForms.GMapControl..ctor()
   at WindowsFormsApp2.Form1.InitializeComponent()
   at WindowsFormsApp2.Form1..ctor()
   at WindowsFormsApp2.MyApp.OnCreateMainForm()
   at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
   at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
   at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(System.String[])
   at WindowsFormsApp2.Program.Main(System.String[])
    Faulting application name: DatacardGenerator.exe, version: 1.7.1.0, time stamp: 0x9971e3f6
Faulting module name: KERNELBASE.dll, version: 10.0.19041.2546, time stamp: 0xe8e9ac9b
Exception code: 0xe0434352
Fault offset: 0x000000000002cd29
Faulting process id: 0x844
Faulting application start time: 0x01d951b04b7a219a
Faulting application path: C:\Program Files (x86)\GV5Js\GV5JsDatacardGenerator\DatacardGenerator.exe
Faulting module path: C:\WINDOWS\System32\KERNELBASE.dll
Report Id: 2d3c200b-e6e6-4be2-bbd3-9efd45f05bfe
Faulting package full name: 
Faulting package-relative application ID: 

答案1

得分: 1

好的,这是翻译好的部分:

Ok, it finally works.

It all boils down to not having the right version of SQLite.Interop.dll. As my "\packages\System.Data.SQLite.Core.1.0.117.0" and "\packages\System.Data.SQLite.1.0.117.0" folders only showed a .p7s and .nupkg file, and now dlls at all, I had downloaded the dlls, and it seems they were wrong. Making a search for SQLite.Interop.dll in my ackages folder found the right ones under "\packages\Stub.System.Data.SQLite.Core.NetFramework.1.0.117.0\build\net46\x64" and "\packages\Stub.System.Data.SQLite.Core.NetFramework.1.0.117.0\build\net46\x86".

Adding those files, as explained here did the trick Winforms app runs fine from bin/debug or bin/release, but not outside

英文:

Ok, it finally works.

It all boils down to not having the right version of SQLite.Interop.dll. As my "\packages\System.Data.SQLite.Core.1.0.117.0" and "\packages\System.Data.SQLite.1.0.117.0" folders only showed a .p7s and .nupkg file, and now dlls at all, I had downloaded the dlls, and it seems they were wrong. Making a search for SQLite.Interop.dll in my ackages folder found the right ones under "\packages\Stub.System.Data.SQLite.Core.NetFramework.1.0.117.0\build\net46\x64" and "\packages\Stub.System.Data.SQLite.Core.NetFramework.1.0.117.0\build\net46\x86".

Adding those files, as explained here did the trick Winforms app runs fine from bin/debug or bin/release, but not outside

huangapple
  • 本文由 发表于 2023年3月8日 18:33:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/75671902.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定