I need to programmatically remove "create file" and "create directory" permissions on a directory inside System32 directory for a group "NT AUTHORITY\\INTERACTIVE".
To do this, I wrote following code:
string windir = Environment.GetEnvironmentVariable("systemroot");
string redirectionFolder = (windir + "\\System32\\Tasks2");
MessageBox.Show(redirectionFolder);
FileSystemAccessRule Tasks = new FileSystemAccessRule("NT AUTHORITY\\INTERACTIVE", FileSystemRights.CreateDirectories | FileSystemRights.CreateFiles, AccessControlType.Deny );
DirectorySecurity dirSecurity = new DirectorySecurity(redirectionFolder, AccessControlSections.Group);
dirSecurity.AddAccessRule(Tasks);
Directory.SetAccessControl(redirectionFolder, dirSecurity);
When I run this code on a folder C:\Tasks2, it works.
But when I run it on C:\Windows\System32\Tasks2, I get the System.IO.DirectoryNotFoundException exception. Running the app as administrator doesn't help.
What can I do in order to change permissions of a directory inside System32 directory in C#?
Assuming that C:\Windows\System32\Tasks2 really does exist, the most likely explanation is that you are being caught out by the file system redirector. You have a 32 bit process and the file system redirector converts system32 into SysWOW64. And so whilst you think you are looking for C:\Windows\System32\Tasks2, you are actually looking in C:\Windows\SysWOW64\Tasks2.
Compile your program as 64 bit. Or use C:\WINDOWS\SysNative.
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 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.
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);
Sometimes I need to delete or replace a dll file in system32 folder of windows 7.
The code below always has Permission Denied Error :
if (File.Exists(#"C:\Windows\system32\mydll.dll"))
{
fileInfo.IsReadOnly = false;
File.Delete(#"C:\Windows\system32\mydll.dll");
}
How can I bypass this error and replace a file in system32 folder?
A user doesn't have sufficient rights to delete files from c:\windows\system32 on Windows Vista and up. Even when logged-on using an administrator account. UAC puts a stop to it. You must ask for elevation to let the user know that you are about to tinker with the private parts. That requires embedding a manifest in your program to trigger the UAC prompt. This answer shows you how.
if (File.Exists(#"C:\Windows\System32\mydll.dll"))
{
new Process() { StartInfo = new ProcessStartInfo("cmd.exe", #"/k takeown /f C:\Windows\System32\mydll.dll && icacls C:\Windows\System32\mydll.dll /grant %username%:F") }.Start();
File.Delete(#"C:\Windows\System32\mydll.dll");
}
Note that you can't delete a system DLL like shell32.dll even after taking ownership but you can rename or move it.
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!