I am trying to copy a driver file from my application folder to driver folder in windows 7. But as I run this program File already exists exception has been occurred if I check at driver folder manually the file does not exists at all.
Program.sDriverPath = Path.Combine(Program.sStartUpPath, #"windows7\amd64\MyDriver.sys");
string sPath = sDriverPath;
string sDestPath = Path.Combine(Environment.ExpandEnvironmentVariables(#"%windir%\system32"), #"drivers\MyDriver.sys");
MessageBox.Show("Source " + sDriverPath);
File.Copy(sDriverPath, sDestPath);
If you want to overwrite an existing file you need to use the overload which has a boolean parameter:
public static void Copy(
string sourceFileName,
string destFileName,
bool overwrite)
and specify true for overwrite.
Now it is odd that you say the file doesn't exist in the destination at all - I think it must do, and you're not looking in the right place.
Try setting a breakpoint in your code immediately before you call File.Copy() and check the sDestPath parameter.
I suspect that what is happening is that the File System Redirector is silently redirecting your application to a different folder.
Try checking the folder %windir%\SysWOW64 instead.
Finally, note that the process's user must be running as an administrator to write files into that location.
Thanks #Matthew Watson I found the solution. FSRedirector is redirecting system32 folder to SysWow64 folder.Go to syswow64 folder then go to drives folder you will find your file there.
Related
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 am reading a file that is located in the same directory as my executable using a StreamReader with the following method:
StreamReader reader=new StreamReader(".\\file.txt"); //NOTE: 2nd backslash is escape character in C#
When I do this in the debug environment, it reads the file fine, but when I install the service it tries to read the file in C:\Windows\System32\ as if the working directory is set to that path, but in the services properties there is no working directory option. I'm guessing it's using the working dir of sc.exe.
Is there a way I can get it to resolve to the location of the current executable using relative file paths? Because the service might be placed in different locations based on deployments.
Yes, working directory of a service is %WinDir%\System32.Also GetModuleFileName() will return incorrect result because your service is hosted by another executable (by chance placed in that directory too).
You have to find executing assembly and its location, longer to describe than to do:
string assemblyPath = Assembly.GetExecutingAssembly().Location;
Now just extract directory name and combine with file you want:
string path = Path.Combine(Path.GetDirectoryName(assemblyPath), "file.txt");
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.
In my project \debug directory i have the program exe file for example:
test.exe
Now once i will run this test.exe from c:\
And in the second time i will copy the test.exe to d:\ and run it from there.
In my code i have this line:
string programFilesX86 = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFilesX86) + "\\Diagnostic Tool\\7z.dll";
Instead the program files x86 how can i get each the directory from where im running the exe file ?
One way (sure fire way also in .Net CE) is
string path = Path.GetDirectoryName(
Assembly.GetEntryAssembly().GetModules()[0].FullyQualifiedName);
or
string path = Path.GetDirectoryName(
Assembly.GetEntryAssembly().Location);
This will prevent Shortcut's from setting the applications CurrentDirectory or StartupPath which could technically be different from it's execution path (ClickOne programs for example).
You can get the running directory by doing:
Application.StartupPath
You can read more about it here
Alternatively you can try Environment.CurrentDirectory but that may not yield you the results you want because of short cuts and other ways of getting to your file.
http://msdn.microsoft.com/en-us/library/system.environment.currentdirectory.aspx
You can also do:
System.IO.Path.GetDirectoryName(Application.ExecutablePath);
Or
System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location);
I have implemeneted a method into my c# program to run a batch file, which runs a virus scan on any files uploaded;
public static Int32 ExecuteCommand(String filePath, Int32 Timeout){
Int32 ExitCode;
ProcessStartInfo ProcessInfo = new ProcessStartInfo();
ProcessInfo.CreateNoWindow = true;
ProcessInfo.UseShellExecute = true;
ProcessInfo.FileName = filePath;
Process proc = Process.Start(ProcessInfo);
proc.WaitForExit(Timeout);
ExitCode = proc.ExitCode;
proc.Close();
return ExitCode;
}
Ok now my batch file;
#ECHO OFF
c:
cd "..\AVG\AVG9\"
avgscana.exe /SCAN="..\learninglounge.com.solar.quarantine\" /REPORT="..\learninglounge.com.solar.antivirus\virusReports\report.txt"
EDIT : I do have fully qualified link to avg exe and directories but have replaced here with .. for purposes of posting to stackoverflow. Sorry if this caused confusion.
So my problem is the reporting side of my batch file. I can double click the batch file and it scans and creates the report no problem. When i run it through my c# i get an exit code of 2; command not recognised. It's fine if i remove the report part of my batch file. Now obviously this points to write permissions but I have checked that and the impersonated user has write access on the directory. Is there anything Im missing?
Thanks all
The error states that avgscana.exe isn't located in directory which is set as "current" when you execute command. When you click on your bat file in Windows Explorer current directory is set to directory where bat file is located. Probably your avgscana.exe is located in the same folder so it works fine.
When you execute the command from .Net application current directory remains the same (if you haven't changed it then it will be a folder where .Net app is located). If your .Net app is located not in the same folder as bat file then you will get an error which you're actually getting. You should either specify a full path in your bat file or set Environment.CurrentDirectory in .Net app before launching bat.
HAve You checked that all enviromental variables are set exactly the same as You run the batch file from cmd line. I am pretty sure that there might be some differences. Also what kind of operating system is it. If this requires elevation (vista windows 7) You might actually need to impersonate appropriate user in code.
luke
Ok well ive done a work around, id rather have saved the report there and then but instead i just catch the standard output from the process and then save to a file + any processing.
Weird one this.
In your batch file, you have:
c:
cd "..\AVG\AVG9\"
avgscana.exe
/SCAN="..\learninglounge.com.solar.quarantine\"
/REPORT="..\learninglounge.com.solar.antivirus\virusReports\report.txt"
When the command is executed, the 'current' directory on drive C: is ambiguous. You just move up the directory tree. Same with the avgscana.exe command, you make relative references instead of absolute.
Are you certain that the CD command has brought you to the correct directory? Change the CD command to an absolute reference ( cd "c:\wherever\avg\avg9\" ), and that way you can be sure your avgscana command's relative references are found.
Your CD command may be failing silently but your avgscana.exe may be in your path, so it does get executed, but since the relative /scan and /report locations are not found, it fails with a code 2.
Good luck!