none
Getting an Assertion Failure, but I have no Assertions RRS feed

  • Question

  • I am trying to read from a .DBF file in C#. I can open the file without issue in DBFView. I do not want to open the associated .DBT file or .MDX file. I just want the table that is available and viewable through DBFView. When I try to open it without the .DBT file in the same directory, I get an error saying it cannot find the correct resource. When the .DBT file is in the same directory, I get an Assertion Failure (apparently the file is already in use). Here is my code:

    static void Main(string[] args)
            {
                const string strDbPath = "c:\\";
                string strPath = "c:\\Temp\\";
                DateTime dtFirstSunday = FirstSunday();
                TimeSpan dateDiff = DateTime.Now.Date.Subtract(dtFirstSunday);
                int weekNum = dateDiff.Days / 7 + 1;
                string strFileName = "W" + weekNum.ToString("D2") + DateTime.Now.ToString("yy") + ".DBF";
                if (!Directory.Exists(strPath))
                    Directory.CreateDirectory(strPath);
                File.Copy(strDbPath + "CARD.DBF", strPath + "CARD.DBF",true);
                File.Copy(strDbPath + "CARD.DBT", strPath + "CARD.DBT",true);
                File.Copy(strDbPath + "CARD.MDX", strPath + "CARD.MDX",true);
                File.Copy(strDbPath + "MSGS.DBF", strPath + "MSGS.DBF",true);
                File.Copy(strDbPath + "MSGS.MDX", strPath + "MSGS.MDX",true);
                File.Copy(strDbPath + strFileName, strPath + strFileName,true);
                File.Copy(strDbPath + strFileName.Replace(".DBF", ".MDX"), strPath + strFileName.Replace(".DBF", ".MDX"),true);
                
                TimeSpan secDiff = DateTime.Now.ToUniversalTime().Subtract(DateTime.Parse("1-1-1970"));
                TimeSpan secToDayStart = DateTime.Now.Date.ToUniversalTime().Subtract(DateTime.Parse("1-1-1970"));
                OleDbConnection conn = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + strPath + ";Extended Properties=dBASE IV;");
                try
                {
                    conn.Open();
                    OleDbCommand cmd = new OleDbCommand("SELECT N.FNAME, N.LNAME, T.[TIMEDATE], M.TXT " +
                        "FROM ([" + strFileName + "] AS T " +
                        "INNER JOIN [CARD.DBF] AS N " +
                        "ON T.KEYNUM = N.CNUM) " +
                        "INNER JOIN [MSGS.DBF] AS M " +
                        "ON T.TYPE = M.[ID] " +
                        "WHERE EXISTS   (SELECT KEYNUM " +
                                        "FROM " + strFileName + " " +
                                        "WHERE KEYNUM = T.KEYNUM " +
                                        "AND [TIMEDATE] >= " + (secDiff.Seconds - 3600).ToString() + ") " +
                        "AND    (EXISTS (SELECT T1.[TIMEDATE], COUNT(T2.[TIMEDATE]) " +
                                        "FROM " + strFileName + " AS T1 " +
                                        "INNER JOIN " + strFileName + " AS T2 " +
                                        "ON T1.KEYNUM = T2.KEYNUM " +
                                        "WHERE T1.KEYNUM = T.KEYNUM " +
                                        "AND T1.[TIMEDATE] >= " + (secDiff.Seconds - 3600).ToString() + " " +
                                        "AND T1.TYPE = 1 " +
                                        "AND T2.TYPE = 1 " +
                                        "AND T2.[TIMEDATE] > T1.[TIMEDATE]-3600 " +
                                        "AND T2.[TIMEDATE] <= T1.[TIMEDATE] " +
                                        "GROUP BY T1.[TIMEDATE] " +
                                        "HAVING COUNT(T2.[TIMEDATE]) > 1 ) " +
                                "OR EXISTS  (SELECT KEYNUM, COUNT(KEYNUM) " +
                                        "FROM " + strFileName + " " +
                                        "WHERE KEYNUM = T.KEYNUM " +
                                        "AND [TIMEDATE] >= " + secToDayStart.Seconds.ToString() + " " +
                                        "AND TYPE = 1 " +
                                        "GROUP BY KEYNUM " +
                                        "HAVING COUNT(KEYNUM) > 2) " +
                                "OR EXISTS  (SELECT T1.[TIMEDATE], COUNT(T2.[TIMEDATE]) " +
                                        "FROM " + strFileName + " AS T1 " +
                                        "INNER JOIN " + strFileName + " AS T2 " +
                                        "ON T1.KEYNUM = T2.KEYNUM " +
                                        "WHERE T1.KEYNUM = T.KEYNUM " +
                                        "AND T1.[TIMEDATE] >= " + (secDiff.Seconds - 3600).ToString() + " " +
                                        "AND T2.[TIMEDATE] > T1.[TIMEDATE]-3600 " +
                                        "AND T2.[TIMEDATE] <= T1.[TIMEDATE] " +
                                        "GROUP BY T1.[TIMEDATE] " +
                                        "HAVING COUNT(T2.[TIMEDATE]) > 2 )) " +
                            "ORDER BY N.FNAME, N.LNAME, T.[TIMEDATE] DESC",
                            conn
                        );
                    OleDbDataAdapter da = new OleDbDataAdapter(cmd);
                    DataTable dt = new DataTable();
                    da.Fill(dt);
                    
                    foreach(DataRow row in dt.Rows)
                    {
                        Console.WriteLine(row["FNAME"].ToString());
                    }
                    
                    conn.Close();
                }
                catch(Exception e)
                {
                    Console.WriteLine("An error occurred: {0}", e);
                }
                finally
                {
                    File.Delete(strPath + strFileName);
                    File.Delete(strPath + strFileName.Replace(".DBF", ".MDX"));
                    File.Delete(strPath + "CARD.DBF");
                    File.Delete(strPath + "CARD.DBT");
                    File.Delete(strPath + "CARD.MDX");
                    File.Delete(strPath + "MSGS.DBF");
                    File.Delete(strPath + "MSGS.MDX");
                }
                Console.WriteLine("Done");
                Console.ReadKey();
            }
    
            public static DateTime FirstSunday()
            {
                DateTime testDate = new DateTime(DateTime.Now.Year, 1, 1);
                while(true)
                {
                    if (testDate.DayOfWeek == DayOfWeek.Sunday)
                        return testDate;
                    testDate = testDate.AddDays(1);
                    if (testDate > DateTime.Now)
                        testDate = new DateTime(DateTime.Now.Year - 1, 1, 1);
                }
            }

    DBFView does not need the .MDX files or the .DBT file to access the data in the .DBF files, so I am hoping I can do the same. Is there a way?

    Edit: When I hit Ignore a bunch of times on the assertion error, it gives me a System.IO.IOException that briefly flashes on the screen, but I cannot get much of what it says.

    Thursday, February 9, 2017 11:08 PM

Answers

  • Can you use the File Class and get it into a FileStream instead so you can write it back out to the new file? There are plenty of options and one may work for your scenario. File.Copy is somewhat limited in this respect.

    Paul ~~~~ Microsoft MVP (Visual Basic)

    Friday, February 10, 2017 7:17 PM

All replies

  • Hi SlipEternalRobert,

    >>DBFView does not need the .MDX files or the .DBT file to access the data in the .DBF files, so I am hoping I can do the same. Is there a way?

    As far as I know, ado.net could access the data in the .DBF files only. please only copy the DBF files to temp folder and check if it works.

    If the issue still exist, could you please share related files (dbf etc) via OneDrive and related detailed error message.

    Best regards,

    Cole Wu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Friday, February 10, 2017 6:31 AM
    Moderator
  • When I do not include CARD.DBT, I get this error message:

    An error occurred: System.Data.OleDb.OleDbException (0x80004005): Cannot locate
    the requested Xbase memo file.
       at System.Data.OleDb.OleDbCommand.ExecuteCommandTextErrorHandling(OleDbHResul
    t hr)
       at System.Data.OleDb.OleDbCommand.ExecuteCommandTextForSingleResult(tagDBPARA
    MS dbParams, Object& executeResult)
       at System.Data.OleDb.OleDbCommand.ExecuteCommandText(Object& executeResult)
       at System.Data.OleDb.OleDbCommand.ExecuteCommand(CommandBehavior behavior, Ob
    ject& executeResult)
       at System.Data.OleDb.OleDbCommand.ExecuteReaderInternal(CommandBehavior behav
    ior, String method)
       at System.Data.OleDb.OleDbCommand.ExecuteReader(CommandBehavior behavior)
       at System.Data.OleDb.OleDbCommand.System.Data.IDbCommand.ExecuteReader(Comman
    dBehavior behavior)
       at System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[]
     datatables, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand co
    mmand, CommandBehavior behavior)
       at System.Data.Common.DbDataAdapter.Fill(DataTable[] dataTables, Int32 startR
    ecord, Int32 maxRecords, IDbCommand command, CommandBehavior behavior)
       at System.Data.Common.DbDataAdapter.Fill(DataTable dataTable)
       at SwipeTracker.SwipeTracker.Main(String[] args)

    When I do include the .DBT file (removing the code to copy it manually and delete it afterwards), the error goes away. So, is there a way to remove the need for the .DBT file? And is there a way to allow the code to copy the files, then wait for the files to become available?

    Friday, February 10, 2017 2:22 PM
  • Have you tried using the Visual FoxPro OLEDB Provider? My understanding was that the .DBT file actually contains memo or binary data that was required by the dBase ISAM driver, but you may be able to workaround this issue with the VFP provider.

    https://www.microsoft.com/en-us/download/details.aspx?id=14839

    https://www.connectionstrings.com/vfp-ole-db-provider/connect-to-a-single-dbf-file/


    Paul ~~~~ Microsoft MVP (Visual Basic)

    Friday, February 10, 2017 3:50 PM
  • Thanks, but I have a 64-bit operating system, and that driver is apparently incompatible with a 64-bit operating system.

    https://social.msdn.microsoft.com/Forums/en-US/ef0f1f24-4f86-4a0a-86dc-5d2f9178753b/vfpoledb-on-64-bit-operating-systems?forum=visualfoxprogeneral

    Friday, February 10, 2017 4:05 PM
  • Thanks, but I have a 64-bit operating system, and that driver is apparently incompatible with a 64-bit operating system.

    https://social.msdn.microsoft.com/Forums/en-US/ef0f1f24-4f86-4a0a-86dc-5d2f9178753b/vfpoledb-on-64-bit-operating-systems?forum=visualfoxprogeneral


    You can compile your app as 32-bit (Platform of x86) but otherwise I'm not aware another option. You are working with a legacy DBMS in dBase and your options will be limited.

    Paul ~~~~ Microsoft MVP (Visual Basic)

    Friday, February 10, 2017 5:27 PM
  • Here is the situation:

    We have an old system managing our building's security. We are not upgrading our security system, so we are stuck with the legacy DBMS. The system is set up to flag if someone is going into an area they are not supposed to be, but it is not set up to flag things like the number of times someone comes into the building. We want to track this, as it indicates people sleeping in their car while they are supposed to be working.

    Since I have no access to the controllers directly, I wanted to grab the data from the dBASE files that the legacy security system maintains. I cannot use them directly from the server, as the security system has locked access to them. So, I need to make a copy every time I try to run this report. The report will find anyone who enters the building more than once in an hour or more than twice in a day and send that information to security who can check cameras to see if they find the agent sleeping in their car while on the clock.

    How do I make sure that the File.Copy command completes (releases its lock on the file) so that I can use it? Because I got it to work fine when the file is manually copied. But, I will need to copy the files fairly frequently (once an hour, say) to grab any updates.

    Friday, February 10, 2017 6:49 PM
  • Can you use the File Class and get it into a FileStream instead so you can write it back out to the new file? There are plenty of options and one may work for your scenario. File.Copy is somewhat limited in this respect.

    Paul ~~~~ Microsoft MVP (Visual Basic)

    Friday, February 10, 2017 7:17 PM
  • Thank you! I had not used a FileStream before, but that solved the problem completely! I just used the following code:

    using (FileStream inStream = File.Open(strDoorsPath + "CARD.DBF", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                {
                    using (FileStream outStream = File.Create(strPath + "CARD.DBF"))
                    {
                        inStream.CopyTo(outStream);
                    }
                }
                using (FileStream inStream = File.Open(strDoorsPath + "CARD.DBT", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                {
                    using (FileStream outStream = File.Create(strPath + "CARD.DBT"))
                    {
                        inStream.CopyTo(outStream);
                    }
                }
                using (FileStream inStream = File.Open(strDoorsPath + "MSGS.DBF", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                {
                    using (FileStream outStream = File.Create(strPath + "MSGS.DBF"))
                    {
                        inStream.CopyTo(outStream);
                    }
                }
                using (FileStream inStream = File.Open(strDoorsPath + strFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                {
                    using (FileStream outStream = File.Create(strPath + strFileName))
                    {
                        inStream.CopyTo(outStream);
                    }
                }

    Thank you!

    Friday, February 10, 2017 9:20 PM