SQLite invalid URI after updating System.Data.SQLite.dll - c#

I first had this SQLite version: 1.0.77.0 (sqlite-netFx40-static-binary-bundle-Win32-2010-1.0.77.0)
and everything was working fine.
After updating my System.Data.SQLite.dll to version 1.0.82.0 (sqlite-netFx40-static-binary-bundle-Win32-2010-1.0.82.0) I now receive this:
Unable to open database. Connection string: 'datetimeformat=ISO8601;synchronous=Off;uri="file://C:/Users/username/Documents/data/test.db";version=3;journal mode=Truncate;default isolationlevel=ReadCommitted;pooling=True'; Error: 'System.InvalidOperationException: Invalid connection string: invalid URI
I've also tried file:/// instead of file:// without any luck.
Could anybody tell me what is wrong with my URI, why it doesn't work anymore in v1.0.82.0 but worked in v1.0.77.0?
http://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki
(1.0.82.0 == 3.7.14)

The best way to get correct connection string is to always use the SQLiteConnectionStringBuilder class to generate them.
SQLiteConnectionStringBuilder conn_builder = new SQLiteConnectionStringBuilder
{
DateTimeFormat = SQLiteDateFormats.ISO8601,
SyncMode = SynchronizationModes.Off,
Version = 3,
JournalMode = SQLiteJournalModeEnum.Truncate,
DefaultIsolationLevel = System.Data.IsolationLevel.ReadCommitted,
Pooling = true,
Uri = new Uri(#"c:\tmp\db.sqlite").AbsoluteUri
};
string conn_str = conn_builder.ConnectionString;
if Uri is not working, try setting DataSource instead (if you are using a local file).
A quick check shows that DataSource is evaluated before Uri in SQLiteConnection.cs and takes precedence over it, so if there is a bug in the Uri handling, using DataSource may help bypassing it.

According to the docs starting from the version 1.0.82.0 it was changed:
Add support for URI file names via the new FullUri connection string
property.
Example:
var connection = new SQLiteConnection("FullUri=file:mydb.sqlite?cache=shared");

following works for me, for following example you can't not use Data Source
FullUri=file::memory:?cache=shared

See these URI filename examples, but your URI (with three slashes) looks correct.

I think you should try to strip down your connection string to the basics and then add the options.
Take a look at this site for example SQLite connection string options.
http://www.connectionstrings.com/sqlite
The 3 /// is only valid when you are trying to escape out the spaces in the uri, I would also say that you should try moving the db out of the users folder to the root on c:\ in case the access permissions are not valid for it to access the DB and it also means a simpler connection string for you to try.
Good luck

Related

How to get ExpandEnvironmentVariables to return custom variables?

I have added a custom environment variable and I'm unable to get it to return in the ExpandEnvironmentVariables.
These 2 calls work fine:
string s = Environment.GetEnvironmentVariable("TEST", EnvironmentVariableTarget.Machine);
// s = "D:\Temp2"
string path = Environment.ExpandEnvironmentVariables(#"%windir%\Temp1");
// path = "C:\Windows\Temp1"
However, this call returns the same input string:
var path = Environment.ExpandEnvironmentVariables(#"%TEST%\Temp1");
// path = "%TEST%\\Temp1"
I expect to get D:\Temp2\Temp1
What am I missing to correctly get the custom EnvironmentVariable in this last call?
Hans and Evk were correct in their comments. Since no one wanted to add an answer I'll close this question out.
For whatever reason ExpandEnvironmentVariables will not get any keys which were added after an application started. I also tested this with a running Windows Service. It was only after I restarted the service that new keys were found and populated.
This behavior is not documented in the Microsoft Documentation.

C# Open Registry Key when only a prefix portion of the name is known

I am working with these two registry keys.
64 bit Firefox version:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Mozilla Firefox (????)
32 bit Firefox version:
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Mozilla Firefox xx.xx.xx (x86 en-US)
What I want is to read the key called InstallLocation inside that path. The issue is in the path. The path has Firefox version which has version number in it.
I can hard code the path, but when Firefox is updated, the the path is also updated, so it won't work after the update.
Is there a way to dynamically just read the part of the path and parse out the version to reach to the key?
In other words, is there a way to read the path up to Mozilla Fireox and ignore the rest, because I just want see if it this path exist, if it does, go inside the path to get the key-value.
Update
Thanks to konkked
var has32bit =
Registry.LocalMachine
.OpenSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall")
.GetSubKeyNames()
.Any(a=>a.StartsWith("Mozilla Firefox"));
var has64bit =
Registry.LocalMachine
.OpenSubKey("SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall")
.GetSubKeyNames()
.Any(a=>a.StartsWith("Mozilla FireFox"));
How can I get a key-value inside the Mozilla Firefox folder?? Because the above code only returning true of false.
Try using below and it will have the install path
var path = Registry.GetValue(#"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\firefox.exe", "", null);
You could get all of the subkeys of an entry using RegistryKey.GetSubKeyNames Method () and then do a where to see if any are FireFox
var has32bit =
Registry.LocalMachine
.OpenSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall")
.GetSubKeyNames()
.Any(a=>a.StartsWith("Mozilla Firefox"));
var has64bit =
Registry.LocalMachine
.OpenSubKey("SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall")
.GetSubKeyNames()
.Any(a=>a.StartsWith("Mozilla FireFox"));
Also notice in a comment you said
There should be a better way to do this rather than collecting alllll (sic)
of the keys inside uninstall, as it can grow pretty big. #MarcB thank
you tho.
I don't think there is a better way to partially match against a subkey
And to answer comment :
Thank you! it's working. Is there a away (sic) to get values inside that
full path afte (sic) like InstallLocation
You can get the actual subkey when you decide which version you want, but I am not sure how you are going to decide that, but here is an example of how to access the values:
var subkey32BitBase =
Registry.LocalMachine
.OpenSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall");
var fireFoxKeys = subkey32BitBase.GetSubKeyNames(subkey32base);
foreach(var fireFoxSubKey in fireFoxSubKeys)
{
Console.WriteLine(
subkey32BitBase
.GetSubKey(fireFoxSubKey)
.GetValue("InstallLocation")
);
}
If Firefox is installed it will register itself to the "Open With..." list of HTML files.
The application names to open html files with are stored under the file type's registry key, under the OpenWithList subkey. The path to applications themselves are stored under HKCR\Applications.

localhost: network name not found

I'm doing database unit testing and I'm trying to write data to files via localhost, but I'm getting the error Exception occurred: The network name cannot be found. I have a byte array that I want to put in a text file like so:
File.WriteAllBytes(outputFilePath, res);
Where res is the byte array and outputFilePath is a string assigned as "\\localhost\InterfaceFiles\Requirements.txt".
All the documentation I can find on the data types and operators indicate this should work. Anyone have an idea why it isn't? The file Requirements.txt doesn't exist yet, but WriteAllBytes should create it in that case.
edit: unchecked "trustworthy" in the Visual Studio database settings.
Try replacing localhost with your actual PC name; the computer host name which you get by running hostname command under command prompt.
"\\PC_NAME\InterfaceFiles\Requirements.txt"
Check the string assignment, I mean the string literal. If it contains single backslashes, then it should preceded by #. If no # then all backslashes should be doubled like:
#"\\host\path\filename.any"
// or
"\\\\host\\path\\filename.any"

Class Library Connection String Confusion

I have managed to confuse myself... not difficult, I know, and am looking for some guidance...
I have written a dll which I am now starting to use in my Winforms UI.
This is a follow on question to this:
Class Libray Connection String - How to change?
As told in that post, I have added the identical connection string settings from the app.config in the dll to my App.config in my UI.
In my UI, I have a text box where the user can enter the connection string and hit "Save", which runs the following code:
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
config.ConnectionStrings.ConnectionStrings["TPAPI.Properties.Settings.TruePotentialConnectionString"].ConnectionString = txtConnectionString.Text;
config.Save(ConfigurationSaveMode.Modified, true);
ConfigurationManager.RefreshSection("connectionStrings");
Which seems to update the string in the file correctly.
But, and this is where the previous posting confuses me...
That setting only gets read when the software starts. Somehow I need to change the setting which Belogix has explained I should do like this:
var connectionString = "Data Source=MegaServer;Initial Catalog=MyDb; .. etc ..";
using (var db = new MyDataContext(connectionString))
{
// This will connect to MegaServer...
}
But, I am calling functions in my dll like this:
List<Page> pages = Database.getlistOfPagesToScan();
How do I tell that call to start using the newly saved connection string from the UI's App.config?
Can anyone shed any light?
Thanks
You should get the connection string from the settings in the dll. Your answer is actually in the question you post.
Use this:
var connectionString = config.ConnectionStrings.ConnectionStrings["TPAPI.Properties.Settings.TruePotentialConnectionString"].ConnectionString;
You can also use this:
string s = Properties.Settings.Default.ConnectionStr;
Console.WriteLine("Connection string from main app: " + s);
//
// When setting access modifier on Class library to `public`
//
s = ClassLibrary1.Properties.Settings.Default.ConnectionStr;
Console.WriteLine("Connection string from dll: " + s);
Assuming you are using ConfigurationManager to retrieve the application connection strings, try:
ConfigurationManager.RefreshSection("connectionStrings");

C# Modify Connection String that exists inside a library

I have a Class Library, which inside just has a DataSet (MySQL connector) and a Connector class.
I use this class in multiple projects to connect to the database, and I always had the password embedded in the connection string but now I need to be able to modify this string(for security purposes) so I can have the user connect using their own account.
How can I modify this connection string.
I have tried the following
Properties.Settings.Default.DataBaseConnectionString = "String";
But it seems that the connection string is readonly becase it doesn't appear to have a setter value.
I also tried the following with no luck
Properties.Settings.Default.DatabaseConnectionString.Insert(
Properties.Settings.Default.DatabaseConnectionConnectionString.Length - 1,
"Password=dbpassword;");
You can modify them like this:
Properties.Settings.Default["MyConnectionString"] = newCnnStr;
For a full solution that also saves the new value to the file, you need to do something like this:
private static void ModifyConnectionStrings()
{
// Change the value in the config file first
var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
const string newCnnStr = "server=(local);database=MyDb;user id=user;password=secret";
config.ConnectionStrings.ConnectionStrings["MyProject.Properties.Settings.MyConnectionString"].ConnectionString = newCnnStr;
config.Save(ConfigurationSaveMode.Modified, true);
// Now edit the in-memory values to match
Properties.Settings.Default["MyConnectionString"] = newCnnStr;
}
If your dataset is in another assembly, you can still do this providing you make the settings for that assembly public. To do this:
Right-click the project in the solution explorer and click Properties
Click the Settings tab.
Change the Access Modifier dropdown to "Public", save, and close.
Then you can do this (assuming the other project is called "MyProject.DataLayer"):
private static void ModifyConnectionStrings()
{
// Change the value in the config file first
var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
const string newCnnStr = "server=(local);database=MyDb;user id=user;password=secret";
config.ConnectionStrings.ConnectionStrings["MyProject.Properties.Settings.MyConnectionString"].ConnectionString = newCnnStr;
config.ConnectionStrings.ConnectionStrings["MyProject.DataLayer.Properties.Settings.MyConnectionString"].ConnectionString = newCnnStr;
config.Save(ConfigurationSaveMode.Modified, true);
// Now edit the in-memory values to match
Properties.Settings.Default["MyConnectionString"] = newCnnStr;
MyProject.DataLayer.Properties.Settings.Default["MyConnectionString"] = newCnnStr;
}
Don't you have the source code of that class?
Also, but a little more complicated method, would be to patch the assembly using Reflector with the Reflexil AddIn.
I think you're asking how you can change connectionstring properties at runtime depending on who is using the application. Hope this helps.
In the past I have done this by making my connection string contain parameters that I can provide using string.Format.
<connectionStrings>
<add name="SomeDB" connectionString="("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Jet OLEDB:Database Password={1}"" />
</connectionStrings>
string connectionString = string.Format(ConfigurationManager.ConnectionStrings["SomeDB"].ConnectionString, location, password);
It looks like you are loading the connection string from the config file, you should be able to change it from there. Once built it will be a file named the same as your compiled form plus .config. (For example application.exe.config)

Categories

Resources