Can i use clickOnce to deploy MS Access database? - c#

i have developed an application in a .mdb access file with tables linked to sql server
i try toput the mdb file in folder shared to all user but simultaneus access break the file very often.
so iam trying to deploy the .mdb file to every client machine and keep it update. i have created a winform app that check mdb file version and copy it to a local folder and next opens the local copy
but even in this way i have problem if too many user uses the winform launcher appat same time
so iam thinking if there is a bettere and simpler way:
can i use clickonce to deploy directly the access file and create a silly webform to launch it?
i have created the webform but how can i add the mdb file to deploy process? i have to add it to resources? and in that case embedded or not?
and in that case how clickonce detect that the access is a modified one?

If I understand correctly, your .mdb file is the front end to a SQL Server back end. In that case, yes, each user should have their own copy of that FE. If you do a web search, there are many solutions for distributing an Access FE, without having to re-invent the wheel. A favorite is Tony's Auto FE Updater http://autofeupdater.com/.

Found the solution finally:
i add the db to Resources, setting build action to "Content", then my program.cs is this:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
string nomeFile = #"\EW.accde";
string DestinationPath;
string codeBase = Assembly.GetExecutingAssembly().CodeBase;
UriBuilder uri = new UriBuilder(codeBase);
string path = Uri.UnescapeDataString(uri.Path);
DestinationPath = System.IO.Path.GetDirectoryName(path) + #"\Resources";
Process.Start(DestinationPath + nomeFile);
}
in this way i simply copy the new db in project and then deply app with clickonce
once installed app simply launch the database file

Related

ERROR: System.Environment.SpecialFolder' does not contain a definition for 'CommonApplicationData'

I have the code to save a file in a folder in directory
string timestamp = DateTime.Now.ToString("MM-dd-yyyy.HH-mm-ss");
var file = File.Create("Owe-Data.txt" + timestamp);
var com = System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase + timestamp + #"\Data" + file;
MessageBox.Show(com);
if (!Directory.Exists(com))
{
Directory.CreateDirectory(com);
}
using (var sw = new StreamWriter(com))
{
sw.WriteLine(InputData);
}
}
i Displayed COM it gives path bt i cant see the Data folder or Owe-Data file at that path
Anybody can tell why this happening, or should i save the Data folder in current directory where this prgram running? bt i dnt know how to reach that path. Any solutions ??
Working on windows phone 5, visual studio 2008 .NET framwork 2.0
As per the Exceptions section of documentation,the above exception is thrown when
ArgumentException ------- folder is not a member of System.Environment.SpecialFolder.
It means the OS where you are running this command does not have Environment.SpecialFolder.CommonApplicationData as one of the special folder.
For knowledge,
Environment.SpecialFolder.ApplicationData is the most common one. This folder holds per-user, non-temporary application-specific data, other than user documents. A common example would be a settings or configuration file.
Environment.SpecialFolder.CommonApplicationData is similar, but shared across users. You could use this to store document templates, for instance.
Environment.SpecialFolder.LocalApplicationData is a non-roaming alternative for ApplicationData. As such, you'd never store important data there. However, because it's non-roaming it is a good location for temporary files, caches, etcetera. It's typically on a local disk.
I think the problem may be that Environment.SpecialFolder.CommonApplicationData is common and shared between different users and the user with which you have logged in is not having rights to access the folder or the Visual Studio has not been started in Admin mode.
EDIT Look at link and try to add a manual registry Common AppData defined in the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\
Given you are asking about a .NET Windows Phone application as per the tags
I think your problem is that a .NET Windows Phone application does not have direct access to the file system; it can only access IsolatedStorage this is by design.
I would quote a Microsoft source for this but I can't seem to find one!
EDIT
See this article from MSDN

asp.net MVC3 create folder where application can write in

I need to create a folder to use for storing files within it, in a .Net MVC3 application, but I think the problem is common to all ASP.Net platform.
Problem is I can create the folder, but cannot write the files, because System.UnauthorizedAccessException occurred.
I also tryed givin extra permission to the user currently running the web app, but nothing changes.
This is my code so far:
if (!System.IO.Directory.Exists(fullPath))
{
System.IO.Directory.CreateDirectory(fullPath);
var user = System.Security.Principal.WindowsIdentity.GetCurrent().User;
var userName = user.Translate(typeof(System.Security.Principal.NTAccount));
var dirInfo = new System.IO.DirectoryInfo(fullPath);
var sec = dirInfo.GetAccessControl();
sec.AddAccessRule(new System.Security.AccessControl.FileSystemAccessRule(userName,
System.Security.AccessControl.FileSystemRights.Modify,
System.Security.AccessControl.AccessControlType.Allow)
);
dirInfo.SetAccessControl(sec);
System.IO.Directory.CreateDirectory(fullPath);
}
string fullPathFileName = System.IO.Path.Combine(fullPath, fileName);
System.IO.File.WriteAllBytes(fullPath, viaggio.Depliant.RawFile);
Too bad, last line of code always throw System.UnauthorizedAccessException.
I'm not impersonating user in my app, everything run under a predefined user.
What should I do to create a folder and assure that the application can also create files within it?
Edited:
I also tryed to save the files in the App_Data special folder, but I still got the System.UnauthorizedAccessException error. Somebody can tell me why is that happening?
I hate to answer my own question when the problem is that stupid...
I'm just trying to save a file without a proper filename: you can see I'm using the fullPath variable both for creating the folder and for saving the file, instead of using the correctly created fullPathFileName.
Blame on me!
Use App_Data folder, quote from http://msdn.microsoft.com/en-us/library/06t2w7da%28v=vs.80%29.aspx :
To improve the security of the data used by your ASP.NET application, a new subfolder named App_Data has been added for ASP.NET applications. Files stored in the App_Data folder are not returned in response to direct HTTP requests, which makes the App_Data folder the recommended location for data stored with your application, including .mdf (SQL Server Express Edition), .mdb (Microsoft Access), or XML files. Note that when using the App_Data folder to store your application data, the identity of your application has read and write permissions to the App_Data folder.

Can't create a file in C:\inetpub\wwwroot programmatically

I have a function in the code behind of an ASP.NET webpage that creates a file and then opens it with a javascript command. This works in the IDE - it creates the file, asks me where I want to save the file, I can save it, etc. - but when I install the website and test it out, I get an UnauthorizedAccessException while just trying to create the directory for the file within C:\inetpub\wwwroot.
The frustrating part is that I have a similar function that runs in a service and that creates its directories and files just fine in C:\inetpub\wwwroot.
What would I have to do to get this to work for a webpage?
if(!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
StreamWriter SW = new StreamWriter(fullpath, false, Encoding.Unicode);
SW.WriteLine(/*stuff*/);
SW.Close();
You need to make sure the .NET user has write access by right-clicking on the directory, going to the security tab, and adding the appropriate user and checking the write checkbox.
Depending on your version of .NET/Windows/IIS this can be different, typically it is Network Service or IUSR. If you are running IIS7 make sure to check the Identity under advanced settings of the application pool, as that will be the user that needs the write access, again typically this is Network Service.
You need to grant the ASP.Net user write access to the directory.
just open your text editor( notepad or textpad or anything) using administrative previledges
right click on .exe file and click run as administrator you will be able to do it now

Where can I safely store data files for a ClickOnce deployment?

I have been using ApplicationDeployment.CurrentDeployment.DataDirectory to store content downloaded by the client at runtime which is expected to be there every time the app launches, however now I've found this changes seemingly randomly if the application is updated.
What is the best reliable method for storing user data for the application in click-once deployments?
Currently I've been using the following method
private const string LocalPath = "data";
public string GetStoragePath() {
string dir;
if (ApplicationDeployment.IsNetworkDeployed) {
ApplicationDeployment ad = ApplicationDeployment.CurrentDeployment;
dir = Path.Combine(ad.DataDirectory, LocalPath);
} else {
dir = LocalPath;
}
return CreateDirectory(dir);
}
I originally followed the article Accessing Local and Remote Data in ClickOnce Applications under the heading ClickOnce Data Directory which states this is recommended path.
NOTE: CreateDirectory(string) simply creates a directory if it doesn't already exist.
I have found the root cause of my problem is I'm creating many files and an index file, this index file contains absolute paths, click-once moves the content (or copies) on an upgrade, so the absolute paths no longer exist. I will investigate isolated storage as Damokles suggests to see if this has the same side affect for click-once deployments.
Another option is to make a directory for your application in the user's AppData folder and store it there. You can get a path to that with this:
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
You'll find a lot of applications use that (and it's local equivalent). It also doesn't move around between ClickOnce versions.
Check out IsolatedStorage this should help.
It even works in partial trust environments.
To keep you data you need to use the application scoped IsolatedStorage
using System.IO;
using System.IO.IsolatedStorage;
...
IsolatedStorageFile appScope = IsolatedStorageFile.GetUserStoreForApplication();
using(IsolatedStorageFileStream fs = new IsolatedStorageFileStream("data.dat", FileMode.OpenOrCreate, appScope))
{
...
code taken from this post
It depends on the data you are saving.
You are currently saving to the Data Directory which is fine. What you need to be aware of is that each version of the application has its own Data Directory. When you update ClickOnce copies all the data from the previous version to the new version when the application is started up. This gives you a hook to migrate any of the data from one version to the next. This is good for in memory databases like Sql Lite or SQL CE.
One thing that I cam across is that when you have a large amount of data (4 gig) if you store it in the Data Directory this data will be copied from the old version to the new version. This will slow down the start up time after an upgrade. If you have a large amount of data or you don't want to worry about migrating data you can either store the data in the users local folder providing you have full trust or you can use isolated storage if you have a partial trust.
Isolated Storage
Local User Application Data

Error opening connection to SQL CE file on test machine

I'm testing my application on a non-administrator windows 7 account. The application is installed into program files. This includes the .sdf file I need to read from. I've got the connection string marked as read only and set the temp path to my documents. This is the error that it spits out when I try to do connection.Open()
Internal error: Cannot open the shared
memory region
I've got the connection string defined in app.config, but I'm modifying it before I start using the connection. This part is in app.config Data Source=|DataDirectory|\DB.sdf;Password=password;
And then I modify it like so:
connection = new SqlCeConnection(connectionString +
";Mode=Read Only; Temp Path=" + Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments));
This works on my developer machine (obviously) since its running from outside of a read-only directory. But even when I manually mark the .sdf file as read-only it still works, and successfully creates the temporary db file in the correct folder. However, on the test machine everything is located in a read-only program files folder, and it doesn't work.
The main goal of this problem is trying to make sure my program doesn't have to be ran as an administrator, and I would like to keep from moving the main copy of the db file from outside of the installation directory.
Let me know if I need to explain anything else. Thanks
I'm using a sql ce database too and had the same problems. my solution was to create the database in a subfolder in Environment.SpecialFolder.CommonApplicationData. If only one user will use it you can create it in Environment.SpecialFolder.ApplicationData. But here you don't need admin rights.
Another point is your connection string in your app.config. If you'll modify it in your program like me, it must be located in such a 'non-admin-right-needed' folder too. I have a static app.config in my app-folder in program files, but a second one with the connection string in Environment.SpecialFolder.LocalApplicationData (this is 'username\AppData\Local' in Win7). And I protect my connectionstring with DataProtectionConfigurationProvider encryption, so no one can read the data base password.
This is how you can map your second app.config to your app:
string ConfigPathString = #"{0}\MyApp\MyApp.config";
string ConfigPath = String.Format( ConfigPathString, System.Environment.GetFolderPath( Environment.SpecialFolder.LocalApplicationData ) );
ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = ConfigPath;
Configuration Config = ConfigurationManager.OpenMappedExeConfiguration( fileMap, ConfigurationUserLevel.None );
string myConnectionString = ConnectionStrings.ConnectionStrings["MyConnectionStringKey"].ConnectionString;
Like Calgary already mentioned in his comments you can't really open the file directly in the programs folder due to the restrictions of Windows 7 to non-admins. But due to the fact that you don't want to write anything into it, why don't you simply copy at startup the file into Environment.SpecialFolder.ApplicationData?
When your program starts up simply copy the file out of the programs folder into a proper location, use it as you like and delete it on application exit. So you don't leave any fragments (except the application would crash).
Just to be sure for the last scenario, you could add an additional delete operation to the setup deinstallation routine. So if the application will be removed and it crashed at the last start the setup will remove the trash, leaving the machine as before the installation of the software.

Categories