2

Dear Stackoverflow community,

I am a little bit confused using the VFPOleDb Library (9.0Sp2) in Visual Studio 2010 with .NET 4.0 Client Profile. What do I want to do? Edit existing and create new FoxPro Database files using C#.

Trying to compile my own example and based upon the examples seen in "How to create a dbf file from scratch in C#" (1), "How do I read a FoxPro 8.0 database from C#" (2) and "Programming databasing with Visual FoxPro" (3) I receive a compilation error: "Feature not available". Stacktracing the Exception Message shows me that the OleDbConnection Factory doesn't recognize the connection string? I already added the 'Interop.VFPOLEDBLib' as a Reference but I wasn't able to add the 'vfpoledb.dll' because of a missing manifest file?

Code-Example

using System;
using System.IO;
using System.Data;
using System.Data.Odbc;
using System.Data.OleDb;
using System.Data.Common;


    namespace VFPExample
    {

        class VFPExample
        {
            /*
            https://stackoverflow.com/questions/754436/odbc-dbf-files-in-c-sharp/

            http://www.devnewsgroups.net/group/microsoft.public.dotnet.framework/topic62548.aspx
            */

            static void Main(String[] args)
            {

                {
                    string strTestDirectory = @"Provider=VFPOLEDB.1; DataSource=D:\TEMP\";

                    using (OleDbConnection vfpro_con_insert =
                    new OleDbConnection(strTestDirectory) )
                    {
                    vfpro_con_insert.Open(); // FIXME: Ex.Message: "Feature not available"; 

                    OleDbCommand createTable = new OleDbCommand(@"Create Table TestDBF (Field1 I, Field2 C(10))", vfpro_con_insert);
                    OleDbCommand insertTable1 = new OleDbCommand(@"Insert Into TestDBF Values (1, 'Hello')", vfpro_con_insert);
                    OleDbCommand insertTable2 = new OleDbCommand(@"Insert Into TestDBF Values (2, 'World')", vfpro_con_insert);

                    createTable.ExecuteNonQuery();
                    insertTable1.ExecuteNonQuery();
                    insertTable2.ExecuteNonQuery();

                    Console.WriteLine("Wrote in " + vfpro_con_insert.DataSource);
                    }

                    Console.ReadLine();

                    /*
                --------------------------------------------------------------------------------
                    */

                    using (OleDbConnection vfpro_con_read = new OleDbConnection(strTestDirectory))
                    {
                        vfpro_con_read.Open();

                        OleDbCommand readTable = new OleDbCommand("Select * From TestDBF (Field1 I, Field2 C(10))", vfpro_con_read);

                        OleDbDataAdapter da = new OleDbDataAdapter(readTable);

                        DataSet ds = new DataSet();
                        //  DataRow dr = new DataRow();

                        da.Fill(ds);

                        foreach (DataRow dr in ds.Tables[0].Rows)
                        {
                            Console.WriteLine(dr.ItemArray[1].ToString());
                        }

                    }

                    Console.ReadLine();

                }
                catch (Exception e)
                {
                    Console.WriteLine("\n\n Exception:\n\n{0}", e.Message); // Set Breakpoint here for detailed StackTrace
                }
            }

        }
    }

StackTrace

> e {"Feature is not available."}   System.Exception {System.Data.OleDb.OleDbException}
>       [System.Data.OleDb.OleDbException]
>       {"Feature is not available."}
>       System.Data.OleDb.OleDbException
> Data  {System.Collections.ListDictionaryInternal}
>        System.Collections.IDictionary {System.Collections.ListDictionaryInternal}
> HelpLink  null    string
> InnerException    null    System.Exception
> Message   "Feature is not available." string
> Source    "Microsoft OLE DB Provider for Visual FoxPro"   string
> StackTrace    "
>    at System.Data.OleDb.OleDbConnectionInternal..ctor(OleDbConnectionString constr, OleDbConnection connection)
>    at System.Data.OleDb.OleDbConnectionFactory.CreateConnection(DbConnectionOptions options, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningObject)
>    at System.Data.ProviderBase.DbConnectionFactory.CreateNonPooledConnection(DbConnection owningConnection, DbConnectionPoolGroup poolGroup)
>    at System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)
>    at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
>    at System.Data.OleDb.OleDbConnection.Open()
>    at bestsellerList.VFPExample.Main(String[] args)
>    in  D:\Visual Studio 2010\Projects\VFPExample\VFPExample.cs:Line 37."  string
> TargetSite    {Void .ctor(System.Data.OleDb.OleDbConnectionString, System.Data.OleDb.OleDbConnection)}    System.Reflection.MethodBase {System.Reflection.RuntimeConstructorInfo}
>    Static Member      
>    No(t) public Member        
> e.Message "Feature is not available." string

(Tried to fix localization)

So I need some clarifications regarding VFPOleDb/ Visual FoxPro in Visual Studio:

  • Is the Visual FoxPro Library only supported with .NET Client Profile 2.0 and/or Visual Studio 2003/5 (and earlier)? Besides I can clearly see that VSFoxPro (5) reached its End of Product Lifecycle (4) -- at least for Mainstream Support. Extended Support is still granted until 2015. Are there any other (semi)official Documents or Blog entries from Microsoft regarding migration of FoxPro Databases? Already seen "Migrating from Visual FoxPro" (6).

  • Are there any successful compilations reported with .NET 3.x (Client Profile) and above?

  • What am I missing in my code example and/or Reference in Visual Studio?


So, I took the example-code, modified it to my needs -- to read one table with six columns and many, many rows which is exported as a csv file; works fine on my local machine (as usual, as we all know) -- and copied the executable to a Windows 2008 Server R2 with installed .NET 3.5.x and tried to start the application. Did you already do a well educated guess?

Once again I receive the same Exception as the first time but this time it looks like that

            DataSet ds = new DataSet();
            da.Fill(ds); // throws Exception

da.Fill(ds) is the troublemaker but this makes really no sense for me, because I also copied the compiled example-application based on the corrected code to the server and it just does what it is supposed to do...

Thanks for any hints.

Exception

System.Data.OleDb.OleDbException: Feature is not available.
   at System.Data.OleDb.OleDbCommand.ExecuteCommandTextErrorHandling(OleDbHResult hr)
   at System.Data.OleDb.OleDbCommand.ExecuteCommandTextForSingleResult(tagDBPARAMS dbParams, Object& executeResult)
   at System.Data.OleDb.OleDbCommand.ExecuteCommandText(Object& executeResult)
   at System.Data.OleDb.OleDbCommand.ExecuteCommand(CommandBehavior behavior, Object& executeResult)
   at System.Data.OleDb.OleDbCommand.ExecuteReaderInternal(CommandBehavior behavior, String method)
   at System.Data.OleDb.OleDbCommand.ExecuteReader(CommandBehavior behavior)
   at System.Data.OleDb.OleDbCommand.System.Data.IDbCommand.ExecuteReader(CommandBehavior behavior)
   at System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
   at System.Data.Common.DbDataAdapter.Fill(DataSet dataSet, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
   at System.Data.Common.DbDataAdapter.Fill(DataSet dataSet)
   at Program.Main(String[] args)


System.Collections.ListDictionaryInternal

   at System.Data.OleDb.OleDbCommand.ExecuteCommandTextErrorHandling(OleDbHResult hr)
   at System.Data.OleDb.OleDbCommand.ExecuteCommandTextForSingleResult(tagDBPARAMS dbParams, Object& executeResult)
   at System.Data.OleDb.OleDbCommand.ExecuteCommandText(Object& executeResult)
   at System.Data.OleDb.OleDbCommand.ExecuteCommand(CommandBehavior behavior, Object& executeResult)
   at System.Data.OleDb.OleDbCommand.ExecuteReaderInternal(CommandBehavior behavior, String method)
   at System.Data.OleDb.OleDbCommand.ExecuteReader(CommandBehavior behavior)
   at System.Data.OleDb.OleDbCommand.System.Data.IDbCommand.ExecuteReader(CommandBehavior behavior)
   at System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
   at System.Data.Common.DbDataAdapter.Fill(DataSet dataSet, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
   at System.Data.Common.DbDataAdapter.Fill(DataSet dataSet)
   at Program.Main(String[] args)
Community
  • 1
  • 1
hal
  • 153
  • 1
  • 6

3 Answers3

3

I fixed the code as proposed, cleaned it up and improved some minor parts. It works.

using System;
using System.IO;
using System.Data;
using System.Data.Odbc;
using System.Data.OleDb;
using System.Data.Common;

namespace VFPExample
{
    class VFPExample
    {
        /*
         * http://stackoverflow.com/questions/754436/odbc-dbf-files-in-c-sharp/
         * http://www.devnewsgroups.net/group/microsoft.public.dotnet.framework/topic62548.aspx
         */
        static void Main(String[] args)
        {
            try
            {
                string strTestDirectory = @"Provider=VFPOLEDB.1; Data Source=D:\TEMP\";

                using (OleDbConnection vfpro_con_insert = new OleDbConnection(strTestDirectory) )
                {
                    vfpro_con_insert.Open(); 

                    OleDbCommand createTable = new OleDbCommand(@"Create Table TestDBF (Field1 N(2,0), Field2 C(10))", vfpro_con_insert);
                    OleDbCommand insertTable1 = new OleDbCommand(@"Insert Into TestDBF (Field1, Field2) Values (1, 'Hello')", vfpro_con_insert);
                    OleDbCommand insertTable2 = new OleDbCommand(@"Insert Into TestDBF (Field1, Field2) Values (2, 'World')", vfpro_con_insert);

                    createTable.ExecuteNonQuery();
                    insertTable1.ExecuteNonQuery();
                    insertTable2.ExecuteNonQuery();

                    Console.WriteLine("Wrote in " + vfpro_con_insert.DataSource);
                }

                Console.ReadLine();

                using (OleDbConnection vfpro_con_read = new OleDbConnection(strTestDirectory))
                {
                    Console.WriteLine("Read from " + vfpro_con_read.DataSource);

                    vfpro_con_read.Open();

                    OleDbCommand readTable = new OleDbCommand(@"Select * From TestDBF", vfpro_con_read);

                    OleDbDataAdapter da = new OleDbDataAdapter(readTable);

                    DataSet ds = new DataSet();

                    da.Fill(ds);

                    foreach (DataRow dr in ds.Tables[0].Rows)
                    {
                        Console.WriteLine(dr.ItemArray[1].ToString());
                    }
                }
                Console.ReadLine();
            }
            catch (Exception e)
            {
                Console.WriteLine("\n\n Exception:\n\n{0}", e.Message); // Set Breakpoint here for detailed StackTrace
            }
        }
    }
}
John Watts
  • 8,717
  • 1
  • 31
  • 35
hal
  • 153
  • 1
  • 6
  • Wow! Perfect! Exactly what I needed and I've been searching high and low. I had the connection string, I had the query, I just didn't know how I can pull data out of these FoxPro databases. Thak you! +1 – Lukas Nov 20 '13 at 20:10
2

The “Feature is not available” exception is due to an incorrect connection string. Use “Data Source” instead of “DataSource.”

Tom Brothers
  • 5,929
  • 1
  • 20
  • 17
  • You are right. I missed the blank in `Data Source` and this caused the Exception. – hal Jun 01 '12 at 20:35
0

I've used VFPOleDb using VS2010 building WPF app with no problem... I'm running on a 32-bit development machine though. VFP does NOT support 64-bit -- PERIOD, and don't know if that MIGHT be what you are encountering.

Also... does the path "D:\TEMP" exist? It won't automatically try to create a path, but that would appear to me as throwing a different error.

You can also remove System.Data.ODBC and System.Data.Common, I don't think those are needed in the sample you are working.

I also do not have any explicit add reference of 'Interop.VFPOLEDBLib'. From what I've encountered, just having the System.Data and what you DO have of

using System.Data;
using System.Data.OleDb;

should be good to go. The OleDB provider will actually look into what is 'registered' when it tries to load the "Provider=VFPOLEDB.1;" portion.

That said, I would start by making it even more simple... just try to OPEN the connection and then close it

static void Main(String[] args)
{
   string strTestDirectory = @"Provider=VFPOLEDB.1; DataSource=D:\TEMP\";

   OleDbConnection VFPConn = new OleDbConnection(strTestDirectory);
   VFPConn.Open();
   if( VFPConn.State == System.Data.ConnectionState.Open )
      VFPConn.Close();
}

see if THIS crashes... if so, you know it has nothing else to do with any other preparation of create, insert, select, but explicitly the connection.

DRapp
  • 47,638
  • 12
  • 72
  • 142
  • Sorry - I'm unclear as to what you mean by "VFP does NOT support 64-bit -- PERIOD" Both the IDE and applications produced with it run perfectly well and are supported on 64-bit Windows. Or did you mean something else? – Alan B Jun 01 '12 at 08:24
  • @AlanB, it may be backward supported for a 64-bit to call/run the 32-bit, but VFP won't be able to take advantage of 64-bit.. ie: max numeric value, 32-bit, records per table still limited to 2-gig per single file, etc. – DRapp Jun 01 '12 at 10:59
  • Yes that's true, but it's also true of a large percentage of everything that runs on 64-bit Windows at the current time that doesn't have a native 64-bit executable. The 2GB limit was there well before 64-bit and is a function of the legacy file locking mechanism used. 32-bit numerics, yes, how often is that ever a problem with any development product? Bottom line: It's as supported (until 2014) as any other 32-bit application on 64-bit Windows. – Alan B Jun 01 '12 at 11:16
  • @DRapp Well, it is 64-bit system but in this case, the example compiles fine as long the project preferences are set for 32-bit compatibilty mode and the drivers are properly installed. – hal Jun 01 '12 at 20:41