Search code examples
c#sqliteunc

How to Open SQLite3 on Network Share in C# C-Sharp


I'm having trouble with a very simple C# program that opens two SQLite files and reads the contents.

Program works fine (button1) when database file is on local machine, but I cannot get it to work (button2) when the file is on another LAN PC (both running Windows 10).

I'm using Visual Studio 2019 to write this Windows Application using .Net Framework 4.7.2

My code is simple. It's two buttons that do the same thing, but one for a local file and the other for a file on the LAN PC. Here's my code:

using System;
using System.Data.SQLite;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Windows.Forms;

namespace Oak_SQLite3
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        //-----------------------------------------------------------------------------
        // Local Database
        //-----------------------------------------------------------------------------
        private void button1_Click(object sender, EventArgs e)
        {
            string dbPath = Path.Combine(@"C:\Temp\", @"testing.db");
            string connString = string.Format("Data Source={0}", dbPath);
            Debug.Print(connString);

            using (SQLiteConnection conn = new SQLiteConnection(connString))
            {
                StringBuilder query = new StringBuilder();
                query.Append("SELECT * ");
                query.Append("FROM TEST");

                using (SQLiteCommand cmd = new SQLiteCommand(query.ToString(), conn))
                {
                    conn.Open();

                    using (SQLiteDataReader dr = cmd.ExecuteReader())
                    {
                        while (dr.Read())
                        {
                            Console.WriteLine("{0} {1} {2}",
                                dr.GetValue(0),
                                dr.GetValue(1),
                                dr.GetValue(2));
                        }
                    }
                }
            }
        }

        //-----------------------------------------------------------------------------
        // LAN PC Database  (Named Oak with OCH-POS share)
        //-----------------------------------------------------------------------------
        private void button2_Click(object sender, EventArgs e)
        {
            //string dbPath = Path.Combine(@"\\OAK\OCH-POS\", @"testing.db");
            string dbPath = Path.Combine("\\\\OAK\\OCH-POS\\", @"testing.db");
            string connString = string.Format("Data Source={0}", dbPath);
            Debug.Print(connString);

            using (SQLiteConnection conn = new SQLiteConnection(connString))
            {
                StringBuilder query = new StringBuilder();
                query.Append("SELECT * ");
                query.Append("FROM TEST");

                using (SQLiteCommand cmd = new SQLiteCommand(query.ToString(), conn))
                {
                    conn.Open();

                    using (SQLiteDataReader dr = cmd.ExecuteReader())
                    {
                        while (dr.Read())
                        {
                            Console.WriteLine("{0} {1} {2}",
                                dr.GetValue(0),
                                dr.GetValue(1),
                                dr.GetValue(2));
                        }
                    }
                }
            }
        }
    }
}

Local Button Output is Perfect:

Data Source=C:\Temp\testing.db
Native library pre-loader is trying to load native SQLite library "C:\Users\Jason\Documents\Visual Studio 2019\Projects\Oak-SQLite3\Oak-SQLite3\bin\Debug\x86\SQLite.Interop.dll"...
'Oak-SQLite3.exe' (CLR v4.0.30319: Oak-SQLite3.exe): Loaded 'C:\WINDOWS\Microsoft.Net\assembly\GAC_32\System.EnterpriseServices\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.EnterpriseServices.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'Oak-SQLite3.exe' (CLR v4.0.30319: Oak-SQLite3.exe): Loaded 'C:\WINDOWS\Microsoft.Net\assembly\GAC_32\System.EnterpriseServices\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.EnterpriseServices.Wrapper.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
1 John Doe
2 Jane Smith

LAN PC Output Results in Error:

Data Source=\\OAK\OCH-POS\testing.db
SQLite error (14): os_win.c:47433: (3) winOpen(C:\OAK\OCH-POS\testing.db) - The system cannot find the path specified.
SQLite error (14): cannot open file at line 47434 of [bed3e2b686]
Exception thrown: 'System.Data.SQLite.SQLiteException' in System.Data.SQLite.dll
System.Transactions Critical: 0 : <TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Critical"><TraceIdentifier>http://msdn.microsoft.com/TraceCodes/System/ActivityTracing/2004/07/Reliability/Exception/Unhandled</TraceIdentifier><Description>Unhandled exception</Description><AppDomain>Oak-SQLite3.exe</AppDomain><Exception><ExceptionType>System.Data.SQLite.SQLiteException, System.Data.SQLite, Version=1.0.114.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139</ExceptionType><Message>unable to open database file</Message><StackTrace>   at System.Data.SQLite.SQLite3.Open(String strFilename, String vfsName, SQLiteConnectionFlags connectionFlags, SQLiteOpenFlagsEnum openFlags, Int32 maxPoolSize, Boolean usePool)
   at System.Data.SQLite.SQLiteConnection.Open()
   at Oak_SQLite3.Form1.button2_Click(Object sender, EventArgs e) in C:\Users\Jason\Documents\Visual Studio 2019\Projects\Oak-SQLite3\Oak-SQLite3\Form1.cs:line 68
   at System.Windows.Forms.Control.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   at System.Windows.Forms.Control.WmMouseUp(Message&amp;amp; m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message&amp;amp; m)
   at System.Windows.Forms.ButtonBase.WndProc(Message&amp;amp; m)
   at System.Windows.Forms.Button.WndProc(Message&amp;amp; m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message&amp;amp; m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message&amp;amp; m)
   at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
   at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG&amp;amp; msg)
   at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.Run(Form mainForm)
   at Oak_SQLite3.Program.Main() in C:\Users\Jason\Documents\Visual Studio 2019\Projects\Oak-SQLite3\Oak-SQLite3\Program.cs:line 19</StackTrace><ExceptionString>code = CantOpen (14), message = System.Data.SQLite.SQLiteException (0x800007FF): unable to open database file
   at System.Data.SQLite.SQLite3.Open(String strFilename, String vfsName, SQLiteConnectionFlags connectionFlags, SQLiteOpenFlagsEnum openFlags, Int32 maxPoolSize, Boolean usePool)
   at System.Data.SQLite.SQLiteConnection.Open()
   at Oak_SQLite3.Form1.button2_Click(Object sender, EventArgs e) in C:\Users\Jason\Documents\Visual Studio 2019\Projects\Oak-SQLite3\Oak-SQLite3\Form1.cs:line 68
   at System.Windows.Forms.Control.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   at System.Windows.Forms.Control.WmMouseUp(Message&amp;amp; m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message&amp;amp; m)
   at System.Windows.Forms.ButtonBase.WndProc(Message&amp;amp; m)
   at System.Windows.Forms.Button.WndProc(Message&amp;amp; m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message&amp;amp; m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message&amp;amp; m)
   at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
   at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG&amp;amp; msg)
   at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.Run(Form mainForm)
   at Oak_SQLite3.Program.Main() in C:\Users\Jason\Documents\Visual Studio 2019\Projects\Oak-SQLite3\Oak-SQLite3\Program.cs:line 19</ExceptionString></Exception></TraceRecord>
An unhandled exception of type 'System.Data.SQLite.SQLiteException' occurred in System.Data.SQLite.dll
unable to open database file

'Oak-SQLite3.exe' (CLR v4.0.30319: Oak-SQLite3.exe): Loaded 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\Common7\IDE\PrivateAssemblies\Runtime\Microsoft.VisualStudio.Debugger.Runtime.Desktop.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
The program '[13128] Oak-SQLite3.exe' has exited with code -1 (0xffffffff).

I think are most relevant errors are:

  • SQLite error (14): os_win.c:47433: (3) winOpen(C:\OAK\OCH-POS\testing.db) - The system cannot find the path specified.
  • SQLite error (14): cannot open file at line 47434 of [bed3e2b686]

It looks like my UNC path Path.Combine("\\OAK\OCH-POS\", @"testing.db"); is being converted into winOpen(C:\OAK\OCH-POS\testing.db) and I can't figure out why.

I got this to work when I mapped a drive to a letter however, doing that crashes other programs on my client machine, so I really want to avoid that. In fact, I had to remove the mapping because other programs would get confused.

Does anyone have any idea how I can fix this?

Thank you, Jason


Solution

  • Bob Hodge is right, you have to change this line:

    string dbPath = Path.Combine("\\\OAK\\OCH-POS\\", @"testing.db");

    to

    string dbPath = Path.Combine("\\\\\\OAK\\OCH-POS\\", @"testing.db");

    or

    string dbPath = Path.Combine(@"\\\OAK\OCH-POS\", @"testing.db");