how to compress & fix database access 2007 by C# code? - winforms

my C# winforms program work's on database access 2007
this database became swollen.
is there any way for compress and fix this database by C# code ?
if i do it manual (through access) it became less swollen
thank's in advance

You could use the /compact command line argument for msaccess.exe or you can use interop and do something like this Compact And Repair that I found on code project.
C# sample using MS Access Command Line...
var mdbFileName = Path.GetFullPath("youraccessdb.mdb");
if (!File.Exists(mdbFileName))
throw new FileNotFoundException(
"Could not find Access Database",
mdbFileName);
var programFiles = Environment.GetEnvironmentVariable("ProgramFiles");
var accessPath = Path.Combine(
programFiles,
#"Microsoft Office\Office12\MSACCESS.EXE");
if (!File.Exists(accessPath))
throw new FileNotFoundException(
"Could not find MSACCESS.EXE",
accessPath);
var commandArgs = string.Format("/compact \"{0}\"", mdbFileName);
var process = Process.Start(accessPath, commandArgs);
process.WaitForExit();
if (process.ExitCode != 0)
throw new ApplicationException(string.Format(
"Access Exited with Error Code [{0}]",
process.ExitCode));

Related

Windows Forms save to dataset but not table [duplicate]

I have following C# code in a console application.
Whenever I debug the application and run the query1 (which inserts a new value into the database) and then run query2 (which displays all the entries in the database), I can see the new entry I inserted clearly. However, when I close the application and check the table in the database (in Visual Studio), it is gone. I have no idea why it is not saving.
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.SqlServerCe;
using System.Data;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
try
{
string fileName = "FlowerShop.sdf";
string fileLocation = "|DataDirectory|\\";
DatabaseAccess dbAccess = new DatabaseAccess();
dbAccess.Connect(fileName, fileLocation);
Console.WriteLine("Connected to the following database:\n"+fileLocation + fileName+"\n");
string query = "Insert into Products(Name, UnitPrice, UnitsInStock) values('NewItem', 500, 90)";
string res = dbAccess.ExecuteQuery(query);
Console.WriteLine(res);
string query2 = "Select * from Products";
string res2 = dbAccess.QueryData(query2);
Console.WriteLine(res2);
Console.ReadLine();
}
catch (Exception e)
{
Console.WriteLine(e);
Console.ReadLine();
}
}
}
class DatabaseAccess
{
private SqlCeConnection _connection;
public void Connect(string fileName, string fileLocation)
{
Connect(#"Data Source=" + fileLocation + fileName);
}
public void Connect(string connectionString)
{
_connection = new SqlCeConnection(connectionString);
}
public string QueryData(string query)
{
_connection.Open();
using (SqlCeDataAdapter da = new SqlCeDataAdapter(query, _connection))
using (DataSet ds = new DataSet("Data Set"))
{
da.Fill(ds);
_connection.Close();
return ds.Tables[0].ToReadableString(); // a extension method I created
}
}
public string ExecuteQuery(string query)
{
_connection.Open();
using (SqlCeCommand c = new SqlCeCommand(query, _connection))
{
int r = c.ExecuteNonQuery();
_connection.Close();
return r.ToString();
}
}
}
EDIT: Forgot to mention that I am using SQL Server Compact Edition 4 and VS2012 Express.
It is a quite common problem. You use the |DataDirectory| substitution string. This means that, while debugging your app in the Visual Studio environment, the database used by your application is located in the subfolder BIN\DEBUG folder (or x86 variant) of your project. And this works well as you don't have any kind of error connecting to the database and making update operations.
But then, you exit the debug session and you look at your database through the Visual Studio Server Explorer (or any other suitable tool). This window has a different connection string (probably pointing to the copy of your database in the project folder). You search your tables and you don't see the changes.
Then the problem get worse. You restart VS to go hunting for the bug in your app, but you have your database file listed between your project files and the property Copy to Output directory is set to Copy Always. At this point Visual Studio obliges and copies the original database file from the project folder to the output folder (BIN\DEBUG) and thus your previous changes are lost.
Now, your application inserts/updates again the target table, you again can't find any error in your code and restart the loop again until you decide to post or search on StackOverflow.
You could stop this problem by clicking on the database file listed in your Solution Explorer and changing the property Copy To Output Directory to Copy If Newer or Never Copy. Also you could update your connectionstring in the Server Explorer to look at the working copy of your database or create a second connection. The first one still points to the database in the project folder while the second one points to the database in the BIN\DEBUG folder. In this way you could keep the original database ready for deployment purposes and schema changes, while, with the second connection you could look at the effective results of your coding efforts.
EDIT Special warning for MS-Access database users. The simple act of looking at your table changes the modified date of your database ALSO if you don't write or change anything. So the flag Copy if Newer kicks in and the database file is copied to the output directory. With Access better use Copy Never.
Committing changes / saving changes across debug sessions is a familiar topic in SQL CE forums. It is something that trips up quite a few people. I'll post links to source articles below, but I wanted to paste the answer that seems to get the best results to the most people:
You have several options to change this behavior. If your sdf file is part of the content of your project, this will affect how data is persisted. Remember that when you debug, all output of your project (including the sdf) if in the bin/debug folder.
You can decide not to include the sdf file as part of your project and manage the file location runtime.
If you are using "copy if newer", and project changes you make to the database will overwrite any runtime/debug changes.
If you are using "Do not copy", you will have to specify the location in code (as two levels above where your program is running).
If you have "Copy always", any changes made during runtime will always be overwritten
Answer Source
Here is a link to some further discussion and how to documentation.

Windows phone 8 Sqlite setup

I started setting up the windows phone 8 sqlite and everything worked out great. I installed the SQL for Windows phone extension. Then i proceeded on adding the solution (Sqlite.vcxproj). After that i added the files Sqlite.cs and SqliteAsync.cs. Then i referenced the sqlite for windows phone in add reference and everything seemed fine. Finally I added the USE_WP8_NATIVE_SQLITE to the build properties. (I followed -> THIS guide)
First i had problems with SQLite3 missing namespace but then I fixed it after manually adding Community.CsharpSqlite.SQLiteClient.WP.dll, Community.CsharpSqlite.WinPhone.dll, System.Data.Ersatz.WinPhone.dll.
Problem is, when I insert this code:
private async void CreateDatabase()
{
SQLiteAsyncConnection conn = new SQLiteAsyncConnection(Path.Combine(ApplicationData.Current.LocalFolder.Path, "people.db"), true);
await conn.CreateTableAsync<Person>();
}
i keep getting namespace name SQLiteAsyncConnection could not be found (are you missing a directive or an assembly reference?) errors.
is this happening because i cannot add the sqlite3 dll manualy ?( i get the pesky "a reference to a higher version or incompatible assembly cannot be added to the project" error). the SQLite for windows phone is added to the reference tho.
SQLiteAsyncConnection conn = new SQLiteAsyncConnection(Path.Combine(ApplicationData.Current.LocalFolder.Path, "people.db"), true);
Next open connection
await conn.OpenAsync();
string empPersionallInfo = "create table if not exists EmpInfo" + "(no int," + "name varchar(20))";
await conn.ExecuteStatementAsync(empPersionallInfo);

How to delete server entries in SQL Server Management Studio's "Connect to Server" Screen? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to remove “Server name” items from history of SQL Server Management Studio
In the "Connect to Server" screen, SQL Server Management Studio stores all entries you have ever entered for Server Name, login and password. This is very helpful, but from time to time things change, servers addresses change, databases are no longer available.
How can I delete server entries from this screen? Also, when you select a server, past logins are available in the list. Once again, these change. How can I delete user entries?
Looks like this file is a binary serialized version of the Microsoft.SqlServer.Management.UserSettings.SqlStudio class defined in the Microsoft.SqlServer.Management.UserSettings, Version=10.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91 assembly (located at c:\Program Files\Microsoft SQL Server\100\Tools\Binn\VSShell\Common7\IDE\Microsoft.SqlServer.Management.UserSettings.dll).
With a bit of development skill (Visual Studio or even Powershell) you can deserialize this file into the original class, find the entries you want to remove and re-serialize the file back out.
This should give you the idea (working on a copy of the .bin file)...
var binaryFormatter = new BinaryFormatter();
var inStream = new MemoryStream(File.ReadAllBytes(#"c:\temp\SqlStudio.bin"));
var settings = (SqlStudio) binaryFormatter.Deserialize(inStream);
foreach (var pair in settings.SSMS.ConnectionOptions.ServerTypes)
{
ServerTypeItem serverTypeItem = pair.Value;
List<ServerConnectionItem> toRemove = new List<ServerConnectionItem>();
foreach (ServerConnectionItem server in serverTypeItem.Servers)
{
if (server.Instance != "the server you want to remove")
{
continue;
}
toRemove.Add(server);
}
foreach (ServerConnectionItem serverConnectionItem in toRemove)
{
serverTypeItem.Servers.RemoveItem(serverConnectionItem);
}
}
MemoryStream outStream = new MemoryStream();
binaryFormatter.Serialize(outStream, settings);
byte[] outBytes = new byte[outStream.Length];
outStream.Position = 0;
outStream.Read(outBytes, 0, outBytes.Length);
File.WriteAllBytes(#"c:\temp\SqlStudio.bin", outBytes);
After Adrian's question, I tried this again on a Win7 x64 box using Visual Studio 2010. I found the same error so, after digging a bit I found it took a number of steps to resolve.
Set the Platform target to 'x86' in the project properties
add a reference to Microsoft.SqlServer.Management.SDK.SqlStudio (on my box this was at c:\Program Files\Microsoft SQL Server\100\Tools\Binn\VSShell\Common7\IDE\Microsoft.SqlServer.Management.Sdk.SqlStudio.dll)
add a reference to Microsoft.SqlServer.Management.UserSettings (in the same directory at the previous one)
perform custom assembly resolution
The custom assembly resolution took a bit of doing since it wasn't obvious (to me, at least) why the CLR wouldn't just resolve the assembly correctly and why Visual Studio wouldn't allow me to add the reference manually. I'm talking about the SqlWorkbench.Interfaces.dll.
The updated code looks like this:
internal class Program
{
static void Main(string[] args)
{
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
var binaryFormatter = new BinaryFormatter();
var inStream = new MemoryStream(File.ReadAllBytes(#"c:\temp\SqlStudio.bin"));
var settings = (SqlStudio) binaryFormatter.Deserialize(inStream);
foreach (var pair in settings.SSMS.ConnectionOptions.ServerTypes)
{
ServerTypeItem serverTypeItem = pair.Value;
List<ServerConnectionItem> toRemove = new List<ServerConnectionItem>();
foreach (ServerConnectionItem server in serverTypeItem.Servers)
{
if (server.Instance != "the server you want to remove")
{
continue;
}
toRemove.Add(server);
}
foreach (ServerConnectionItem serverConnectionItem in toRemove)
{
serverTypeItem.Servers.RemoveItem(serverConnectionItem);
}
}
MemoryStream outStream = new MemoryStream();
binaryFormatter.Serialize(outStream, settings);
byte[] outBytes = new byte[outStream.Length];
outStream.Position = 0;
outStream.Read(outBytes, 0, outBytes.Length);
File.WriteAllBytes(#"c:\temp\SqlStudio.bin", outBytes);
}
private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
Debug.WriteLine(args.Name);
if (args.Name.StartsWith("SqlWorkbench.Interfaces"))
{
return Assembly.LoadFrom(#"C:\Program Files (x86)\Microsoft SQL Server\100\Tools\Binn\VSShell\Common7\IDE\SqlWorkbench.Interfaces.dll");
}
return Assembly.Load(args.Name);
}
}
Unfortunately, it does not appear to be possible (or at least practical) to only remove certain items.
However, if you want, you can reset the configuration and start from scratch.
Make sure Management Studio is closed, then delete or rename this file:
%APPDATA%\Microsoft\Microsoft SQL Server\100\Tools\Shell\SqlStudio.bin
Note that that file contains other user preference settings, so if you've customized your Management Studio configuration, you'll have some work to do restoring them.
Reference: http://social.msdn.microsoft.com/Forums/en-US/sqltools/thread/94e5c3ca-c76d-48d0-ad96-8348883e8db8/
Good luck!

Attempt to access the method failed: System.IO.StreamWriter..ctor(System.String, Boolean)

I need to write string to an xml file in Silverlight. When I used the following code, the above mentioned exception "Attempt to access the method failed: System.IO.StreamWriter..ctor(System.String, Boolean)" has occurred.
using (StreamWriter sw = new StreamWriter("C:\Test.xml", false))
{
sw.Write(root.ToString());
}
Can anyone help me out in doing writing to xml file in Silverlight?
Silverlight is in a sandboxed mode where it has restricted access. You can write to "Isolated Storage", but you cannot create files on their hard drive.
http://msdn.microsoft.com/en-us/library/system.io.isolatedstorage.isolatedstoragefile(VS.95).aspx
http://forums.silverlight.net/forums/p/22011/77243.aspx

Com Interop problem Silverlight 4 and MS Access 2010

I am trying to launch an existing MS Access database (Access 2010) from a Silverlight 4 OOB with elevated authorisation set. I keep getting an error. I can create a new Access application using the CreateObject keyword, but when I try to launch an existing one I get an error: "No object was found registered for specified ProgID."
Any help is appreciated. Here is the code I use:
string sMSAccess = "C:\\Users\\storltx\\Documents\\SL4Demo.accdb";
dynamic MSAccess = ComAutomationFactory.GetObject(sMSAccess);
MSAccess.Visible = true;
I think you should pass "Access.Application" string to GetObject call. like this:
dynamic MSAccess = ComAutomationFactory.GetObject("Access.Application");
Try your code like this:-
string sMSAccess = "C:\\Users\\storltx\\Documents\\SL4Demo.accdb";
dynamic app = ComAutomationFactory.CreateObject("Access.Application");
app .Visible = true;
app.OpenCurrentDatabase(sMSAccess);

Resources