Why does this fail? Is my extern signature wrong?

H

Hasani

OK, I'm trying to programmatically create an Access database/mdb file but
CreateDb(string) always returns false. I don't know what I'm doing wrong, is
it my extern signature?

Thx in advance

my references:
http://msdn.microsoft.com/library/d...matically_configuring_an_odbc_data_source.asp

http://support.microsoft.com/defaul...port/kb/articles/q149/5/58.asp&NoWebContent=1
[DllImport("ODBCCP32.DLL")]
private static extern bool SQLConfigDataSource(
IntPtr hwndParent,
uint fRequest,
[MarshalAs(UnmanagedType.LPStr)] string lpszDriver,
[MarshalAs(UnmanagedType.LPStr)] string lpszAttributes
);

public static bool CreateDb(string dbName)
{
const string driver = @"Microsoft Access Driver (*.mdb)";
const int ODBC_ADD_DSN = 1;
string path = Environment.CurrentDirectory + "\\" + dbName + "
General";
return SQLConfigDataSource(IntPtr.Zero, ODBC_ADD_DSN, driver,
"CREATE_DB=" + path);
}
 
B

Brian W

Are you certain the directory path exists?

Keep in mind that using Environment.CurrentDirectory is usually not a good
idea in these situations since it will not necessarly return the directory
where your app is located, and here's why:

Assume you have a command prompt open and you are at C:\
Now, assume your app is located in C:\program files\MyDBApp.
Now, in the command prompt you type C:\program files\mydbapp\mydbapp.exe to
start your app, Environment.CurrentDirectory will return C:\ This is
obviously not what you wanted.

The same holds true when starting from a shortcut on the start menu. Unless
the Start In Directory property is set to the directory your app is located
the same thing will happen. Even if you install the app and create the
shortcut. you cannot guarantee the user won't change the shortcut somehow.

Instead if using Environment.CurrentDirectory consider using
Application.StartupPath


HTH
Brian W



Hasani said:
OK, I'm trying to programmatically create an Access database/mdb file but
CreateDb(string) always returns false. I don't know what I'm doing wrong, is
it my extern signature?

Thx in advance

my references:
http://msdn.microsoft.com/library/d...port/kb/articles/q149/5/58.asp&NoWebContent=1
[DllImport("ODBCCP32.DLL")]
private static extern bool SQLConfigDataSource(
IntPtr hwndParent,
uint fRequest,
[MarshalAs(UnmanagedType.LPStr)] string lpszDriver,
[MarshalAs(UnmanagedType.LPStr)] string lpszAttributes
);

public static bool CreateDb(string dbName)
{
const string driver = @"Microsoft Access Driver (*.mdb)";
const int ODBC_ADD_DSN = 1;
string path = Environment.CurrentDirectory + "\\" + dbName + "
General";
return SQLConfigDataSource(IntPtr.Zero, ODBC_ADD_DSN, driver,
"CREATE_DB=" + path);
}
 
H

Hasani

Thx for that, but regardless of what path I specify, the function always
fails.
Brian W said:
Are you certain the directory path exists?

Keep in mind that using Environment.CurrentDirectory is usually not a good
idea in these situations since it will not necessarly return the directory
where your app is located, and here's why:

Assume you have a command prompt open and you are at C:\
Now, assume your app is located in C:\program files\MyDBApp.
Now, in the command prompt you type C:\program files\mydbapp\mydbapp.exe to
start your app, Environment.CurrentDirectory will return C:\ This is
obviously not what you wanted.

The same holds true when starting from a shortcut on the start menu. Unless
the Start In Directory property is set to the directory your app is located
the same thing will happen. Even if you install the app and create the
shortcut. you cannot guarantee the user won't change the shortcut somehow.

Instead if using Environment.CurrentDirectory consider using
Application.StartupPath


HTH
Brian W



Hasani said:
OK, I'm trying to programmatically create an Access database/mdb file but
CreateDb(string) always returns false. I don't know what I'm doing
wrong,
is
it my extern signature?

Thx in advance

my references:
http://msdn.microsoft.com/library/d...port/kb/articles/q149/5/58.asp&NoWebContent=1
[DllImport("ODBCCP32.DLL")]
private static extern bool SQLConfigDataSource(
IntPtr hwndParent,
uint fRequest,
[MarshalAs(UnmanagedType.LPStr)] string lpszDriver,
[MarshalAs(UnmanagedType.LPStr)] string lpszAttributes
);

public static bool CreateDb(string dbName)
{
const string driver = @"Microsoft Access Driver (*.mdb)";
const int ODBC_ADD_DSN = 1;
string path = Environment.CurrentDirectory + "\\" + dbName + "
General";
return SQLConfigDataSource(IntPtr.Zero, ODBC_ADD_DSN, driver,
"CREATE_DB=" + path);
}
 
B

Brian W

BTW, if you pass a valid HWND the function should open a dialog so that you
can provide additional parameters, if that is the problem. This is useful
for debugging this sort of thing.

Also, check value of Marshal.GetLastWin32Error() after the function call.

Finally, for your applicaiton, is it abbsolutly necessary you have a DSN for
the MDB?


HTH2
Brian W






Hasani said:
OK, I'm trying to programmatically create an Access database/mdb file but
CreateDb(string) always returns false. I don't know what I'm doing wrong, is
it my extern signature?

Thx in advance

my references:
http://msdn.microsoft.com/library/d...port/kb/articles/q149/5/58.asp&NoWebContent=1
[DllImport("ODBCCP32.DLL")]
private static extern bool SQLConfigDataSource(
IntPtr hwndParent,
uint fRequest,
[MarshalAs(UnmanagedType.LPStr)] string lpszDriver,
[MarshalAs(UnmanagedType.LPStr)] string lpszAttributes
);

public static bool CreateDb(string dbName)
{
const string driver = @"Microsoft Access Driver (*.mdb)";
const int ODBC_ADD_DSN = 1;
string path = Environment.CurrentDirectory + "\\" + dbName + "
General";
return SQLConfigDataSource(IntPtr.Zero, ODBC_ADD_DSN, driver,
"CREATE_DB=" + path);
}
 
H

Hasani

man, I already changed the code so that an empty mdb is embeded in the exe
=/
Thx for the input though
Brian W said:
BTW, if you pass a valid HWND the function should open a dialog so that you
can provide additional parameters, if that is the problem. This is useful
for debugging this sort of thing.

Also, check value of Marshal.GetLastWin32Error() after the function call.

Finally, for your applicaiton, is it abbsolutly necessary you have a DSN for
the MDB?


HTH2
Brian W






Hasani said:
OK, I'm trying to programmatically create an Access database/mdb file but
CreateDb(string) always returns false. I don't know what I'm doing
wrong,
is
it my extern signature?

Thx in advance

my references:
http://msdn.microsoft.com/library/d...port/kb/articles/q149/5/58.asp&NoWebContent=1
[DllImport("ODBCCP32.DLL")]
private static extern bool SQLConfigDataSource(
IntPtr hwndParent,
uint fRequest,
[MarshalAs(UnmanagedType.LPStr)] string lpszDriver,
[MarshalAs(UnmanagedType.LPStr)] string lpszAttributes
);

public static bool CreateDb(string dbName)
{
const string driver = @"Microsoft Access Driver (*.mdb)";
const int ODBC_ADD_DSN = 1;
string path = Environment.CurrentDirectory + "\\" + dbName + "
General";
return SQLConfigDataSource(IntPtr.Zero, ODBC_ADD_DSN, driver,
"CREATE_DB=" + path);
}
 
A

Andrew S \(Infragistics\)

You're using an absolute path - you need to use a relative path.
e.g.
string path = ".\\" + dbName + " General";

Hasani said:
Thx for that, but regardless of what path I specify, the function always
fails.
Brian W said:
Are you certain the directory path exists?

Keep in mind that using Environment.CurrentDirectory is usually not a good
idea in these situations since it will not necessarly return the directory
where your app is located, and here's why:

Assume you have a command prompt open and you are at C:\
Now, assume your app is located in C:\program files\MyDBApp.
Now, in the command prompt you type C:\program files\mydbapp\mydbapp.exe to
start your app, Environment.CurrentDirectory will return C:\ This is
obviously not what you wanted.

The same holds true when starting from a shortcut on the start menu. Unless
the Start In Directory property is set to the directory your app is located
the same thing will happen. Even if you install the app and create the
shortcut. you cannot guarantee the user won't change the shortcut somehow.

Instead if using Environment.CurrentDirectory consider using
Application.StartupPath


HTH
Brian W



wrong,
http://msdn.microsoft.com/library/d...port/kb/articles/q149/5/58.asp&NoWebContent=1
[DllImport("ODBCCP32.DLL")]
private static extern bool SQLConfigDataSource(
IntPtr hwndParent,
uint fRequest,
[MarshalAs(UnmanagedType.LPStr)] string lpszDriver,
[MarshalAs(UnmanagedType.LPStr)] string lpszAttributes
);

public static bool CreateDb(string dbName)
{
const string driver = @"Microsoft Access Driver (*.mdb)";
const int ODBC_ADD_DSN = 1;
string path = Environment.CurrentDirectory + "\\" + dbName + "
General";
return SQLConfigDataSource(IntPtr.Zero, ODBC_ADD_DSN, driver,
"CREATE_DB=" + path);
}
 
B

Brian W

I'm sorry, I don't understand your statement.

What does that have to do with :

1) Passing and HWND so the ODBC manager can show you a dialog indicating
you missed some parameters.
Doing so, will allow you to fill in the necessary parameters to make the
connection work. After filling in the connections, you can inspect the
connection string to see what it is you need to add to your code to make it
work without the window.

2) Checking GetLastWin32Error() after you make the call
This may tell you *why* it failed.

3) The question, Is it absolutly necessary to use a DSN?
It is possible, and prefered (IMO) to connect to an MDB with out a DSN.


Regards
Brian W

Hasani said:
man, I already changed the code so that an empty mdb is embeded in the exe
=/
Thx for the input though
Brian W said:
BTW, if you pass a valid HWND the function should open a dialog so that you
can provide additional parameters, if that is the problem. This is useful
for debugging this sort of thing.

Also, check value of Marshal.GetLastWin32Error() after the function call.

Finally, for your applicaiton, is it abbsolutly necessary you have a DSN for
the MDB?


HTH2
Brian W






wrong,
http://msdn.microsoft.com/library/d...port/kb/articles/q149/5/58.asp&NoWebContent=1
[DllImport("ODBCCP32.DLL")]
private static extern bool SQLConfigDataSource(
IntPtr hwndParent,
uint fRequest,
[MarshalAs(UnmanagedType.LPStr)] string lpszDriver,
[MarshalAs(UnmanagedType.LPStr)] string lpszAttributes
);

public static bool CreateDb(string dbName)
{
const string driver = @"Microsoft Access Driver (*.mdb)";
const int ODBC_ADD_DSN = 1;
string path = Environment.CurrentDirectory + "\\" + dbName + "
General";
return SQLConfigDataSource(IntPtr.Zero, ODBC_ADD_DSN, driver,
"CREATE_DB=" + path);
}
 
H

Hasani

1) I don't want end user input.
2) Can no longer do because code has been deleted.
3) No, it is not necessary. I needed to create an access database, not
connect to one.

Well, When I posted my last reply, I had already modified the code using a
different approach to solve a problem I was having.
The problem is, I have an application that needs to read and write to a
database to store stuff. When the application is first run, it will check
for the existence of this database (a mdb file) in the path of where it was
executed from. If the database does not exist, it is to create a database.
The database creation process is to be transparent and there can be no user
input.
So I googled how to programmatically create a db and I came across the kb
article. I tried to implement this, and I think I did it properly but I was
never able to create a new access database using the SQLConfigDataSource
method. I then posted my problem. Almost an hour later you mentioned the get
last error (Which I thank you for), but between the time of my original post
and your 'get last error' post, I decided to just include an empty access
database file to the output as an embedded resource and when the application
is run, it will extract this database if no other access database exist. And
it works too, and if it aint broke, don't try 2 fix it!

Cheers

Brian W said:
I'm sorry, I don't understand your statement.

What does that have to do with :

1) Passing and HWND so the ODBC manager can show you a dialog indicating
you missed some parameters.
Doing so, will allow you to fill in the necessary parameters to make the
connection work. After filling in the connections, you can inspect the
connection string to see what it is you need to add to your code to make it
work without the window.

2) Checking GetLastWin32Error() after you make the call
This may tell you *why* it failed.

3) The question, Is it absolutly necessary to use a DSN?
It is possible, and prefered (IMO) to connect to an MDB with out a DSN.


Regards
Brian W

Hasani said:
man, I already changed the code so that an empty mdb is embeded in the exe
=/
Thx for the input though
that
you DSN
for file
but
http://msdn.microsoft.com/library/d...port/kb/articles/q149/5/58.asp&NoWebContent=1
[DllImport("ODBCCP32.DLL")]
private static extern bool SQLConfigDataSource(
IntPtr hwndParent,
uint fRequest,
[MarshalAs(UnmanagedType.LPStr)] string lpszDriver,
[MarshalAs(UnmanagedType.LPStr)] string lpszAttributes
);

public static bool CreateDb(string dbName)
{
const string driver = @"Microsoft Access Driver (*.mdb)";
const int ODBC_ADD_DSN = 1;
string path = Environment.CurrentDirectory + "\\" + dbName + "
General";
return SQLConfigDataSource(IntPtr.Zero, ODBC_ADD_DSN, driver,
"CREATE_DB=" + path);
}
 
B

Brian W

Oh OK, I see your point.

FWIW, I understand not wanting to have user input, I only suggested it as a
way to debug your problem only.

Best of luck
Brian W


Hasani said:
1) I don't want end user input.
2) Can no longer do because code has been deleted.
3) No, it is not necessary. I needed to create an access database, not
connect to one.

Well, When I posted my last reply, I had already modified the code using a
different approach to solve a problem I was having.
The problem is, I have an application that needs to read and write to a
database to store stuff. When the application is first run, it will check
for the existence of this database (a mdb file) in the path of where it was
executed from. If the database does not exist, it is to create a database.
The database creation process is to be transparent and there can be no user
input.
So I googled how to programmatically create a db and I came across the kb
article. I tried to implement this, and I think I did it properly but I was
never able to create a new access database using the SQLConfigDataSource
method. I then posted my problem. Almost an hour later you mentioned the get
last error (Which I thank you for), but between the time of my original post
and your 'get last error' post, I decided to just include an empty access
database file to the output as an embedded resource and when the application
is run, it will extract this database if no other access database exist. And
it works too, and if it aint broke, don't try 2 fix it!

Cheers

Brian W said:
I'm sorry, I don't understand your statement.

What does that have to do with :

1) Passing and HWND so the ODBC manager can show you a dialog indicating
you missed some parameters.
Doing so, will allow you to fill in the necessary parameters to make the
connection work. After filling in the connections, you can inspect the
connection string to see what it is you need to add to your code to make it
work without the window.

2) Checking GetLastWin32Error() after you make the call
This may tell you *why* it failed.

3) The question, Is it absolutly necessary to use a DSN?
It is possible, and prefered (IMO) to connect to an MDB with out a DSN.


Regards
Brian W
http://msdn.microsoft.com/library/d...mmatically_configuring_an_odbc_data_source.as
phttp://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:80/support/kb/articles/q149/5/58.asp&NoWebContent=1
[DllImport("ODBCCP32.DLL")]
private static extern bool SQLConfigDataSource(
IntPtr hwndParent,
uint fRequest,
[MarshalAs(UnmanagedType.LPStr)] string lpszDriver,
[MarshalAs(UnmanagedType.LPStr)] string lpszAttributes
);

public static bool CreateDb(string dbName)
{
const string driver = @"Microsoft Access Driver (*.mdb)";
const int ODBC_ADD_DSN = 1;
string path = Environment.CurrentDirectory + "\\" + dbName
+
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top