I have setup my sqlite database path as
string AppPath = System.IO.Path.GetDirectoryName(Application.ExecutablePath);
dbName = AppPath + "\\data\\rbssystems.sqlite";
But when application is packed and installed using setup, my application uses
C:\Users\<username>\AppData\Local\VirtualStore\Program Files\RBS\data
it should be using
C:\Program Files\RBS\data
Can anyone tell whats going around and how to make it read database from
C:\Program Files\RBS\data
Thanks
Your app can't write to C:\Program Files unless it has administrative privileges. Windows automatically redirects you to C:\Users\<username>\AppData\Local\VirtualStore\Program Files instead. See this article for the explanation: http://blogs.windows.com/windows/archive/b/developers/archive/2009/08/04/user-account-control-data-redirection.aspx
Application data should always be in the AppData folder, never in Program Files.
Related
I created a WinForms application that includes code to find the user's desktop and perform 3 tasks:
1. Create a folder
2. Read a .csv file
3. Output some data to a .csv file on the desktop.
I'm using the code below to find the user's desktop
string desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
I used the ClickOnce deployment to install the program to our network drive. The program installs successfully, but Whenever I have someone attempt to run the program from their terminal, they get an error message that states "The directory name is invalid" and it references my desktop and not the user's.
How should I change my code or the deployment method so it references the user's desktop?
If directory invalid try creating it
Try with this code
string filePath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
string extension = ".log"; filePath += #"\Error Log\" + extension;
if (!Directory.Exists(filePath)) {
Directory.CreateDirectory(filePath);
}
I made the following change to my code and it worked as needed:
string desktop = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
I have C# wpf installation done with .net using click once installation. All works fine. Then I have the following code which is part of the installed program:
String destinationPath = System.Windows.Forms.Application.StartupPath + "\\" + fileName;
File.Copy(path, destinationPath, true);
this.DialogResult = true;
this.Close();
But I get this error:
System.UnauthorizedAccessException: Access to the path C:\user\pc\appdata\local\apps\2.0....... is denied.
at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)
at System.IO.File.Copy(String sourceFileName, String destFileName, Boolean overwrite)
Is it a permission error or do I need to tweak something in my code?
What puzzles me is why the user is able to install the program using click once into that directory without any issues, but uploading a file to it doesn't work?
When installing an application the installer usually asks for administrative privileges. If the user chooses "Yes" the program will run and have read and write access to a larger variety of paths than what a normal user has. If the case is such that the installer did not ask for administrative privileges, it might just be that ClickOnce automatically runs under some sort of elevated privileges.
I'd suggest you write to the local appdata folder instead, but if you feel you really want to write to the very same directory as your application you must first run your app with administrator privileges.
To make your application always ask for administrator privileges you can modify your app's manifest file and set the requestedExecutionLevel tag's level attribute to requireAdministrator:
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
You can read a bit more in How do I force my .NET application to run as administrator?
I was running a program that would generate file. The destination folder was read only. And it would crash with the error. Removing the read-only attribute using folder properties resolved the error.
First, if you need to write any data you should use the Environment.SpecialFolder enumeration.
Second, do not write to any folder where the application is deployed because it is usually read only for applications. You probably want to write to the ApplicationData or LocalApplicationData enumerations.
I think that access to %appdata% is restricted by default on windows 8 (or 7) onwards.
When the app installed via ClickOnce you are probably prompted to give it permission to alter this computer - is that right?
You can try running the app with admin permissions as a test (hold shift, right click the .exe, run as administrator) which will probably solve it, but it's not an ideal way to do it.
Instead try another folder, something like:
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
or
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments )
which should give you better luck.
As a side note - if you are building paths in code, rather than using
path + "\\" + path + "\\" + filename
which is prone to failure (path may already have a \ on the end) it is usually better to use Path.Combine(..)
String destinationPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), fileName);
In my case, the remote server was returning "." and ".." when I was trying to download (SFTP) files and write to our local/network folder. I'd to explicitly discard the "." and ".." file names.
I tried many ways to access a text file in my Visual Studio 2012 Solution from a folder named TextFiles
using (System.IO.StreamWriter file = new System.IO.StreamWriter(#"~/TextFiles/ActiveUsers.txt", true))
{
file.WriteLine(model.UserName.ToString());
}
But it kept on throwing the error
Could not find a part of the path 'C:\Program Files (x86)\IIS
Express\~\TextFiles\ActiveUsers.txt'.
Not sure where I made a mistake
You need to use HttpServerUtility.MapPath which will turn the ~/ portion of the path in to the real location it resildes on your hard drive.
So that would change your code to (assuming you are in one of the IIS classes that expose a Server property to it's methods)
var path = Server.MapPath(#"~/TextFiles/ActiveUsers.txt");
using (System.IO.StreamWriter file = new System.IO.StreamWriter(path, true))
{
file.WriteLine(model.UserName.ToString());
}
I ran into a similar issue and ended up using
string sFileName = HttpContext.Current.Server.MapPath(#"~/dirname/readme.txt");
This is an old question but I just ran into this problem myself and wanted to add what I've just discovered, in case it's helpful to anyone else.
If you have UAC turned off but are not running with elevated permissions, and try to write to restricted files (e.g. the "Program Files" folder) you'll get the "could not find a part of the path" error, instead of the (correct) access denied error.
To eliminate the problem, run with elevated permissions as in this solution: https://stackoverflow.com/a/1885543/3838199
~ is not the "user home" or anything else in Windows. You can still set the path as relative to the working directory (where the executable is) by just not specifying a full path.
For .netcore 3.x
You should make use of IWebHostEnvironment using dependency injection.
You can then use it in your code this way
string wwwRootPath = _hostEnvironment.WebRootPath;
string path = Path.Combine(wwwRootPath, $"TextFiles{Path.PathSeparator}ActiveUsers.txt");
Ensure to use PathSeparator otherwise you might face the same error due to the variance in your hosting environment.
I'm trying to deploy my Application that uses a Firebird v2.5 database to a client machine.
I am trying to use a minimum installation, without the need to run any other installers. From what I gather, all I need to do is copy the "FBClient.dll" to the target application folder (which includes firebird database file). I have tried this and it still reports an error about not being able to find the correct .net data provider.
eg
C:\Program Files (x86)\MyApp\myApp.exe
C:\Program Files (x86)\MyApp\fbDatabase.fdb
C:\Program Files (x86)\MyApp\fbclient.dll
The error produced is:
Failed to find or load the registered .Net Framework Data Provider.
Also have copied, renamed and included fbclient.dll as fbembed.dll
I have also tried to copy a bunch of other files to the app directory, as well as placing fbclient.dll into the c:\, c:\windows, c:\windows\system.
I also tried installing the client installation, with no joy too.
Is there a way, that I can use the firebird database, without manually editing the machine.config files or using the gac and going through the hell that I went through to install firebird on the dev machine? I want an application that a user can install, not requiring that it be installed by a developer.
Please note, the application that I am writing is for a single machine, single user environment, who knows how to double click the install button, with the attention span of a gnat, that if required to do more than double click install and then press GO, will simply get bored and press the cancel, forget it button.
I add the file "FirebirdSql.Data.FirebirdClient.dll" to the application folder and I no longer get the Data provider error, instead I get the following
"Unable to complete network request to host \"DevMachine\"."
at FirebirdSql.Data.Client.Managed.Version10.GdsConnection.Connect()
at FirebirdSql.Data.FirebirdClient.ClientFactory.CreateManagedDatabase(FbConnectionString options)
at FirebirdSql.Data.FirebirdClient.ClientFactory.CreateDatabase(FbConnectionString options)
at FirebirdSql.Data.FirebirdClient.FbConnectionInternal.Connect()
I am trying to connect with the following
string file = #"C:\Program Files (x86)\MyApp\Test.FDB;";
FbConnection con = new FbConnection("User=SYSDBA;" + "Password=masterkey;" + "Database=" + file + "DataSource=Dev-VS-W7VM;" + "Port3050;" + "Dialect=3;" + "Charset=ISO8859_1;");
try
{
con.Open();
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
I have included FirebirdSql.Data.FirebirdClient in my project and installation folder (..\MyApp)
Thank you in advance.
You have to grap a zip and copy FirebirdSql.Data.FirebirdClient.dll to bin folder.
I wonder how you wrote your application that it works without the file (probably installed .msi) :)
You needed to install .net provider
http://www.firebirdsql.org/en/net-provider/
The database file resides next to your application's exe module. So, you need in local server running or embedded server in order to work with data. For embedded server a minimal set of files is (specifed relatively to an application folder):
\UDF (folder with UDF needed if any)
\Intl (with contents from FB installation)
fbembed.dll
firebird.msg
ib_util.dll
icudt30.dll
icuin30.dll
icuuc30.dll
Microsoft.VC80.CRT.manifest
msvcp80.dll
msvcr80.dll
for a full scale server (i.e. not an embedded) a list of files would be:
\UDF (folder with UDF needed if any)
\Intl (with contents from FB installation)
fbserver.exe or fb_inet_server.exe
fbclient.dll
firebird.msg
ib_util.dll
icudt30.dll
icuin30.dll
icuuc30.dll
Microsoft.VC80.CRT.manifest
msvcp80.dll
msvcr80.dll
security2.fdb
firebird.conf (if non default parameters used)
But then you would need in setting up service record for FB
or start it as an application before your application start.
Installation of the Firebird as a service could be done with
instsvc.exe utility. Appropriate commands:
instsvc install -s -a
instsvc start
Also you should take care of two things:
FileName must be a local file, not in a shared folder from another server.
Appending the firebird server IP before the filename. If you are running your app always in the firebird server, or you are using embeded fbclient.dll, than it should be like
FbConnection con = new FbConnection("User=SYSDBA;" + "Password=masterkey;" + "Database=localhost:" + file + "DataSource=Dev-VS-W7VM;" + "Port3050;" + "Dialect=3;" + "Charset=ISO8859_1;");
Some fbclient.dll version will allow you not to add localhost and still connect on local files, or use \\servername\c:\filename format instead of localhost:c:\filename, but it is deprecated and not supposed to work anymore (and can work depending on windows version).
In Windows using C#, how can I get the installation path of a software (for example consider NUnit or any other software like MS word, etc.) from my project? Also how to set the path variables that we set in Environment variables so that we can run the application just by giving in command prompt.
Like if I install NUnit in "C:\Program Files" I can run it by giving 'NUnit' in cmd prompt but if I install in a different location I can't do the same.
I need to get the location or path of NUnit or any other software installed in my system (having Windows XP) from my project.
EDIT:
Like I can get the path of installed program from registry.
HKEY_CURRENT_USER->SOFTWARE
Use the system and application classes. This will give you all sorts of information.
EG: Application.ExecutablePath
It also provides methods to do what you want to.
Edit: Also see registry read/write instructions here:
http://www.c-sharpcorner.com/UploadFile/sushmita_kumari/RegistryKeys102082006061720AM/RegistryKeys1.aspx?ArticleID=0ce07333-c9ab-4a6a-bc5d-44ea2523e232
Application.ExecutablePath (includes filename)
Application.StartupPath (not includes filename)
This will give you the path where the application started. Hopefully it will be the installation path.
string appFileName = Environment.GetCommandLineArgs()[0];
will give you the full path of the executable and
string directory = Path.GetDirectoryName(appFileName);
extracts the directory.
string envPath = Environment.GetEnvironmentVariable("PATH");
Environment.SetEnvironmentVariable(envPath + ";" + yourPath);
edits the PATH environment variable for the current process.
Application.StartupPath is used to get installation location in c#.
Like if i install Nunit in "C:\Program
Files" i can run it by giving 'nunit'
in cmd prompt but if i install in a
different location i cant do the same.
May be you are using Windows Vista, which can search in Program Files, but won't look in other folders.
In windows using C#, how to get the
installation path of a software(for
example consider nunit).?
It depends, how you are installing the application. The installer knows the path, you may program the installer to write that path to somewhere, say registry.
Also how to set the path variables
that we set in Environment variables
so that we can run the application
just by giving in command prompt.
How do I get and set Environment variables in C#?
Steps to extract value from registry are shown in following code snippet.
You may already know that there are no standard rules for applications to place their installation info.
The steps shown below are for COM based applications where the appplication must provide Local executable path in a reasonably standard manner.
For non-com applications, check to see if some data can be extracted from installed applications cache.
I hate to admit that the solution is not as elegant as I want it to be. Each subkey has to opened in series and opening in single method does not work.
//string hiveName = #"CLSID"; // for 64 bit COM 7applications
string hiveName = #"WOW6432Node\CLSID"; // for 32 bit COM applications
using (RegistryKey key = Registry.ClassesRoot.OpenSubKey(hiveName))
{
if (key != null) {
using (RegistryKey key2 = key.OpenSubKey("{<YourAppGUID>}"))
{
if (key2 != null) {
using (RegistryKey key3 = key2.OpenSubKey("LocalServer32"))
{
if (key3 != null) {
return key3.GetValue("").ToString();
}
}