Best approach to reading and writing values from DLL at runtime - c#

I’m creating a class library DLL which will be used by others. I have no knowledge of what that project will be, what the project name will be and etc. When it’s all said and done, all I will be doing is handing them the DLL for any project to reference.
The problem now is that I need a way for my DLL to be able to read and load key/values from the project at runtime. The project will pass the key/values to my DLL and said DLL will do the reading and writing of these key/values. I’ve found out that there are multiple ways to do that:
1) User settings from Settings/Appconfig
2) Create a new XML file to read and write from
However both ways are not automated. Correct me if I’m wrong:
For 1) The project side will have to manually create a Settings file with the key/values my DLL needs.
For 2) The project side will have to manually create an XML file with the key/values my DLL needs. Plus my DLL will need to know where that XML is being saved by the project referencing it (so that I can read and write from it from the DLL)
This is where I need help. Is there a way I can achieve reading and writing values from my DLL at runtime without the project having to do any manual work? And if not, what would be the best approach to go about this? Hand over a Settings file to the people who will be referencing my DLL?
Thanks!

Well, the client (the project using your dll) will have to do something in order to use you dll, right.
Your choice is to either define a way of configuration or to change your interface, so that the caller can provide the key-value pairs directly. You can still use app-settings from the consuming application's configuration-file. Your DLL can access them by using System.Configuration.ConfigurationManagerwithout having to know anything about where the application is running.
The only thing the other project would have to do is to provide the settings you need in the config.
But maybe you could elaborate a little more on what you are actually trying to do, "reading values" is not very specific.

Related

Is there any way for converting reference dll to non-reference dll in visual studio

I have a DLL file (cf.dll) in my project.
It has some methods for encrypting and decrypting a string To/From a file.
My "cf.dll" have some methods for:
write "mystring" ---to-->> new encrypted dll
and
read encrypted dll ---to--->> "mystring"
Now i want publish my project, but if end user use my dll in his/her visual studio (by reference to dll), he/she can decrypt my encrypted files.
Another hand i need this dll in my published project because my project use theirs methods some times.
Now my question is:
How can i change this published dll (cf.dll) to a none-reference dll, for prevent any hack by it.
Edit (more details):
What i want to do:
I want encrypt some connection strings (as a DataTable) to a file and read this file agin.
I have a dll file for doing this work. it is cf.dll. it has some methods for encrypting and decrypting.
Encryption workflow>
DatatTable ------to------>> Xml as String ------by cf.dll methods to------>> enc.dll
Decryption workflow
enc.dll ------by cf.dll methods to------>> Xml as String ------to------>> DataTable
Everything is working properly and encrypted file (enc.dll) is created.
But if the end user use my magic DLL (cf.dll) in a new project in the visual studio (by reference to it), he/she can decrypt my encrypted file (enc.dll) and hack my program.
So, i want to prevent this hack by changing my DLL (cf.dll) to a none-reference DLL OR use another safe solution.
Edit:
My Table Columns for keeping connection string data:
Server DbName DbUser DbPass FileName
But may i ask save another DataTable by this encryption mechanism. so please help me by a solution for saving any string, not only a ConnectionString.
I want a very secure encrypted file from any data. in my solution i conver each object to a string then use my dll methods for save it as a encrypted file (i can do it nice, my problem described above).
You cannot make your dll "non-reference dll", but you can hide all your classes/methods with "internal" keyword (instead of public). This means that this classes/methods can be used only inside of current dll or in DLL/EXE which were specified with InternalVisibleTo attribute. So nobody can use them directly, but you should know that this is managed code, so anybody can take a look inside of your DLL and extract your keys for decryption and write the same code as you have in your dll.
Surprisingly you can not archieve your goal by using a .NET Assembly.
You could even obfuscate your code and it would still be decompilable and reusable.
There's nothing which can prevent that. You can rise the bar, but someone - if she want's - will be able to get the information you are trying to hide.
(Have you seen copy-protection mechanisms that really work besides doing something crucial online?)
Always think of the following:
If you want to hide information from a user DO NOT DELIVER that information. Everything else is just protection through obfuscation, wich can be cracked with more or less effort.
That's a really nice question RAM.
Some solutions to your problem:
1) Don't make a separate assembly (DLL), but put the code of your DLL in your EXE and make the encryption/decryption function of your DLL "internal" (so that no-one can use it from outside the EXE). Then use a free tool like Eazfuscator to obfuscate your EXE (because, if you don't, your code will be easy to decompile and read).
2) You could put the DLL in your EXE's resources (perhaps encrypted too). Then perhaps you can find a way to get it from there and load it into memory for your app to use. But this is quite complex thing to do if you are a beginner and I'm not 100% sure if it's doable in .NET (I haven't done it myself). However, I think it's doable.
3) The fact is that, if your code executes on the client's machine, there's not much you can do to prevent people from analysing it. The best you can do is to make it a little (or much) difficult for them to do it. E.g. you can add a lock mechanism in your DLL that requires the caller to respond to a random question. If he responds correctly, you execute the decryption. If not, throw an exception, return null or, even better, return a wrong output. The random question could be an integer that your DLL will generate on initialization and the EXE should process this integer to generate a new integer based on some "secret" algorithm. Then the EXE will "feed" this into the DLL somehow and it's functionality would be "unlocked".
4) Perhaps you could use reflection to analyse the caller assembly in order to find characteristics or even the author signature (if you put one in your EXE). That way, you could execute the decryption if the EXE is signed by your private key and the signature is valid. But that's a bit complex too.
5) I think there are tools called "EXE packers" that pack your EXE and DLLs into one EXE file and protect them at some degree. I haven't used one of those yet.
6) You can move the encryption/decryption process on a web site that will ask for authentication in a complex manner, similar to the one described in (3) for the DLL. This may keep your encryption algorithm safe, but the authentication process could still be analysed and hacked.
I would suggest the 3rd solution since it's the most easy to implement. The 4th (using signed code) is the most secure one but it takes a lot of knowledge to implement it (knowledge that even I don't have right now).
Have a nice coding! :)

Can language localisations be automatically reverse engineered from .resx files?

I'm working with an MVC 4 app that was originally created with the intention of possibly requiring language localisation so there's a heavy use of .resx files and corresponding embedding of references throughout the project. As it turns out, the app will only ever be used by English speaking audiences and indeed no other languages were ever loaded in. What we've got now is an overhead every time we need to put text on a page and increasing inconsistency as English language is hard-coded into places which can't directly access the resource files such as .js files and reference data in the DB.
Short of a lot of copying and pasting, is there any automated way to extract the English language values from the resource files and replace their references in the views? In a perfect world there'd be a tool to do this and certainly it's conceptually scriptable, does anything like this exist already?
You will have to script it. I have done similar stuff with the O2 Platform AST manipulation Mono.Cecil and mono Cecil APIs.
If you give me a small project with the use can you need (a resx file and an MVC view) I can show you a code snippet example
I haven't seen anything that would take care of this. My first thought is because of the localization issues that could be presented in most "out of the box" solution.
This maybe far fetched, but giving it a shot. Could you write a C# app that would load the assembly that holds the resource file, then loop through every file in the project and replace the resource keys with the values?
As you said, it is possible to be scripted, and this seems like the easiest yet crudest way to complete the task in my mind. Depending on the number of resources you're talking about, obviously it maybe easier and safer to copy/paste.
Satellite assemblies..If you have all app resources placed in a project then create the non-default language you want to implement. For example fr_ca.ErrorMsg | en_gb.ErrorMsg and en_Us.ErrorMsg. The default language can be specified in the main Thread.CultureInfo If en_us then fill you en_us file with all entries need and other resources will only be loaded if it does not exist in the default resource->en_us.

Reading from a file inside a VS solution

I have an xml file that I want to include along with my program as a template. I would prefer that it be bundled with the .exe when the project is completed.
Is this possible?
If so, how should I reference it in the code? I would assume that referencing "myXML.xml" won't work because, if it is included, the file no longer exists as a standalone object.
An alternative idea is to copy/paste the contents into string, but that seems like a bad idea in so many ways. (It's 900 lines.)
Ideas?
Thank you.
The real motivation behind this is I really prefer standalone executables rather than making the user go through the installation process. Additionally there's the extra benefit that they're less likely to f- it up.
This is quite simple to do, you can store files in any .NET assembly as "Embedded Resources", which can be then accessed at runtime.
See the Microsoft article here for a detailed rundown on how to do this.
Another way is resource files, http://msdn.microsoft.com/en-us/library/7k989cfy%28v=vs.80%29.aspx

How can I embed a SQLite Database in a .NET DLL and then use it from C#?

I'm currently working on some evaluation work for a project that I'm planning.
I recently looked at solutions for a data storage mechanism for my application and while researching stumbled upon SQLite. I currently use SQLite with the System.Data.SQLite wrapper.
I really like the way it works but I have one problem with it that I couldn't get fixed and I also found no help concerning my problem on the internet.
I would like my SQLite Database to be embedded into one of my applications DLLs (ie. Title.Storage.dll) to be used within this DLL. Is this possible?
How can I access the database then?
It would be great if I could use something like:
SQLiteConnection con = new SQLiteConnection();
con.ConnectionString="DataSource=Title.Storage.storage.db3";
con.Open();
Thanks in advance and best regards,
3Fox
An assembly isn't for file storage, it's for code storage. While you can store files in an assembly, they are read only.
This is not possible as such. What you could do is embed the db in your dll project and dump it to certain location on the file system (may be AppData?) and read and write from there. Having db sit directly inside the executable (or dlls) may not be a good idea in the sense it bloats the size of the application besides being technically infeasible.
Having a single executable to distribute is a matter of taste which I like. In your case but the problems are more. It's not just about embedding the db file alone, what about the dlls associated with it? Steps are 2:
1) Add the necessary dlls (System.Data.SQLite?) associated with your db to your project as Embedded Resource (not necessarily a Resource file) and let the system automatically resolve the assembly conflicts. Catch it here how to do it.
2) Now either add your db file to your Resources of your project (and extract it)
static void DumpDatabase()
{
var dbFullPath = Utility.GetDbFullPath(); //your path
if (File.Exists(dbFullPath))
return; //whatever your logic is
File.WriteAllBytes(dbFullPath, Properties.Resources.myDb);
}
or even better do not embed the db as such in your project but write the logic to create database in your application. What if tomorrow you need to change the version of SQLite, say from 3 to 4? With the first approach you need to create a database for yourself and re-embed it in the project. But if you are writing the logic to create the db in your application then updating SQLite version is just a matter of changing the ADO.NET dll (the code remains the same). May be like this:
static void DumpDatabase()
{
var dbFullPath = Utility.GetDbFullPath();
if (File.Exists(dbFullPath))
return; //whatever your logic is
CreateDb(dbFullPath);
}
static void Create(string dbFullPath)
{
SQLiteConnection.CreateFile(dbFullPath);
string query = #"
CREATE TABLE [haha] (.............)
CREATE TABLE ..............";
Execute(query);
}
And in the connection string add FailIfMissing=False;
If you're on NTFS, you can use an alternate data stream. On my project we hide the SQLite database inside another file using an alternate stream called :DB.
I don't think storing data in DLL is a good idea, but there is a dirty way to do it.
To load data from DLL:
Use System.Reflection.Assembly to load a string from DLL file. (The string is dump of DB)
Create empty SQLite DB in memory.
Use the loaded string as a query to DB to restore its content.
Now you can make any queries in memory.
To save data to DLL:
Dump DB content into a string.
Create temporary file containing SQL-dump wrapped in C# code.
Compile it using "csc" (or "gmcs" in Mono).
It's stupid, but it should work. Hope you will never code that way.
SQLite is packaged and distributed as a single C file with a few (3 I think) header files. This means that you can compile the entire 50000 line program with one compile command and get a .o file. From there, you can link it into your application DLL with the other files you link into that DLL.
Once you build sqlite3.o into your application DLL, the symbols in its SQLite's API become available to your programs in the same way that your other C/C++ DLLs become available to your C#/VB programs.
Check out www.sqlite.org/amalgamation.html for more info.

Letting several assemblies access the same text file

I've got many assemblies/projects in the same c#/.net solution. A setting needs to be saved by people using the web application gui, and then a console app and some test projects need to access the same file. Where should I put the file and how to access it?
I've tried using "AppDomain.CurrentDomain.BaseDirectory" but that ends up being different for my assemblies. Also the "System.Reflection.Assembly.Get*Assembly.Location" fail to give me what I need.
Maybe this isn't something I should but in a file, but rather the database? But it feels so complicated doing that for a few lines of configuration.
Put the file in
Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData),
"[Company Name]\[Application Suite]");
Personally, I would be leveraging the database because the alternative is either a configuration headache or is more trouble than it's worth.
You could configure each application to point to the same file, but that becomes problematic if you want to move the file. Or you could write a service to manage the file and expose that to clients, but at this point you may as well just use the DB.
Thought about storing it in the registry or in Isolated Storage? Not sure if multiple applications can share Isolated Storage or not, though.
projects can have build events -- why not add a post-build event to copy the file to all required locations?

Categories