System.UnauthorizedAccessException occurs under Admin privileges with full access to folder - c#

I'm all out of ideas on fixing an "Access Denied" issue on Windows 8.1...
I'm building a console app in Visual Studio under Administrative mode and my app is simply trying to do the following:
using System.IO;
namespace CommandCenterScriptLauncher
{
class Program
{
static void Main(string[] args)
{
try
{
Console.WriteLine("The argument passed was " + args[0] + ".");
Console.ReadLine();
File.WriteAllText(#"C:\Users\Matt\Music\target", "TEXT FILE BODY WITH ARG: " + args[0]);
}
catch
{
Console.WriteLine("No arguments were passed.");
Console.ReadLine();
File.WriteAllText("C:\\Users\\Matt\\Music\\target", "TEXT FILE BODY WITH NO ARGS");
}
}
}
}
Not only am I running in Admin mode which isn't helping, but the folder itself is NOT read only, and ALL USERS on the Security tab for the target folder have been granted FULL CONTROL.
What else am I missing here?!

You need to pass in a filename to File.WriteAllText. Right now, it looks like you are trying to write to a directory. That won't work.

Can you write in another location?. Windows for some reason prevent for writing on system folders. Try something like 'c:/Test/yourFile.txt'.
Check also UAC is disabled.

Related

File.AppendText attempting to write to wrong location

I have a C# console application that runs as a scheduled task within Windows Task Scheduler. This console app writes to a log file that when runs within debug mode creates and writes to the file within the application folder itself. However, when it runs in the task scheduler it throws an error saying that access is denied because it is trying to write to the same log file, but for some reason it is trying to write to it within the windows\system32 folder. Why would this be happening? And how would I correct this?
Here is the code snippet that assigns a StreamWriter to the log file:
static void Main(string[] args)
{
using (_swrtr = File.AppendText("gapi_gen_log.txt"))
{
_swrtr.Write("\r\n");
_swrtr.Write("\r\nGOOGLE CALENDAR:");
_swrtr.Write("\r\n\tDate Time - " + DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToLongTimeString());
start();
}
}
I also tried but this didn't work:
string dir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
using (_swrtr = File.AppendText(dir + "gapi_gen_log.txt"))
{
_swrtr.Write("\r\n");
_swrtr.Write("\r\nGOOGLE CALENDAR:");
_swrtr.Write("\r\n\tDate Time - " + DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToLongTimeString());
start();
}
This is happening because you are not specifying a directory for your log file, so it's assuming the directory where the parent executable resides which, while you're debugging, is your debug output folder and when you're running it from the task scheduler, is the "c:\windows\system32" folder.
You could provide a path to the directory like this:
File.AppendText(#"c:\MyLogFiles\gapi_gen_log.txt")

How to run a program in the same folder?

So I'm learning how to develop software and I'm running into a problem. When I create a form in Visual Studio and have it open a document or open something else when I click a button I have it pointing here:
C:\User\MyName\Documents\TestApp\test.txt
What I want to know is how do I get it to where the program just looks at TestApp folder vs going through the C: Drive? Say all the files are needed for the program to run are located in the TestApp folder.
If you know that your app is going to be run from the same place every time (like a folder) you can call the GetCurrentDirectory() method. This will return a string of the current directory that your app is running from.
String pwd = GetCurrentDirectory(); //Contains something like C:\Users\Daedric\TestApp\
String finalString = Path.Combine(pwd, "test.txt"); //As per Corak
You need start file from your app folder?
Application.StartupPath
for start file
Process.Start(Application.StartupPath + #"\test.txt");
Besides above answer, following example can help you understand how Path works:
class Program
{
static void Main()
{
string[] pages = new string[]
{
"cat.aspx",
"really-long-page.aspx",
"test.aspx",
"invalid-page",
"something-else.aspx",
"Content/Rat.aspx",
"http://dotnetperls.com/Cat/Mouse.aspx",
"C:\\Windows\\File.txt",
"C:\\Word-2007.docx"
};
foreach (string page in pages)
{
string name = Path.GetFileName(page);
string nameKey = Path.GetFileNameWithoutExtension(page);
string directory = Path.GetDirectoryName(page);
//
// Display the Path strings we extracted.
//
Console.WriteLine("{0}, {1}, {2}, {3}",
page, name, nameKey, directory);
}
}
}
Sample output would be like this:
Input C:\Windows\File.txt
GetFileName: File.txt
GetDirectoryName: C:\Windows
GetCurrentDirectory is not the correct method to use as the return value can change while you application is running. You can see this by simply running the following in a console app:
Console.WriteLine(Directory.GetCurrentDirectory());
Directory.SetCurrentDirectory(#"c:\temp\");
Console.WriteLine(Directory.GetCurrentDirectory());
You can use the following to give you the assembly location:
Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)

recognize if program was run from Desktop

Is there any way to recognize if the application has been run from a shortcut instead of executable file? I need to make my users to copy exe file to their desktops rather than create shortcuts to it due to personalization issues. Any ideas?
Edit: creating the installer is not an option.
I don't know if this helps, but if you want your exe file to be on the desktop, this could work:
string path = Directory.GetCurrentDirectory();
string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
if (!path.Equals(desktopPath))
{
Console.WriteLine("file is not at desktop");
}
If you do have an app in the windows shared folder you can configure it to prevent execution of the applications.
Or you can provide user just with link to .bat file instead of .exe and it would do something like this (using robocopy):
robocopy \\remote\server\exe %AppData%\your\folder app.exe /XO
start %AppData%\your\folder\app.exe
And on the C# side you can just check application path and do something like this:
public class Program
{
public int Main()
{
string original_path = System.IO.Path.GetFullPath(#"\\remote\app.exe");
string current_path = System.IO.Path.GetFullPath(
System.Reflection.Assembly.GetExecutingAssembly().Location);
if(original_path == current_path){
System.IO.File.Copy(original_path, #"C:\foo\bar\app.exe", true);
System.Diagnostics.Process.Start(#"C:\foo\bar\app.exe");
return 0;
}
// Run program normally here
}
}

Access to the path is Denied When create file by windows service

i cannot create file in my windows service
and this is error
error In onstart method Access to the path 'C:\Windows\system32\BridgeServiceLog.txt' is denied.
protected override void OnStart(string[] args)
{
try
{
Logger.InitLogFile("BridgeServiceLog.txt");
Trace.WriteLine(Logger.logSwitch.TraceInfo, "Trace Started");
Trace.WriteLineIf(Logger.logSwitch.TraceInfo, "OnStart Started");
_bridgeServiceEventLog.WriteEntry("new OnStart");
if (Vytru.Platform.Bridge.Configuration.LicenseValidetor.ValidCountAndTypeDevices())
{
SharedData.InitializeBridge();
// WsInitializeBridge();
}
else
{
this.Stop();
_bridgeServiceEventLog.WriteEntry("LicenseValidetor Error");
}
_bridgeServiceEventLog.WriteEntry("end Start");
}
catch (Exception e)
{
Trace.WriteLineIf(Logger.logSwitch.TraceError, e.Message);
_bridgeServiceEventLog.WriteEntry("error In onstart method " + e.Message);
}
Trace.WriteLineIf(Logger.logSwitch.TraceInfo, "OnStart Ended");
}
The service user account probably doesn't have access to write to C:\Windows\System32 (which is the working directory of a Windows service).
Anyway, you shouldn't write to that folder. It is for the operating system - not your service.
You can use Environment.GetFolderPath to get a suitable path for writing files like log files in a way that will work any computer, not just your own computer. Here is an example.
var companyPath = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData),
"MyCompany"
);
var productPath = Path.Combine(companyPath, "MyProduct");
var logFilePath = Path.Combine(productPath, "BridgeServiceLog.txt");
You should of course use suitable values for MyCompany and MyProduct.
When running a Windows Service the default working folder is <System drive>:\Windows\System32\.
Fortunately, not everyone can just access that folder.
There are two ways about this; write your file to another folder to which you do have rights, or run your service with administrator rights.
I would recommend the first option.
The easiest solution is to go the folder where you want to save a file, right click, properties, security, add a new user IIS_Users and give permission to write.
Use LocalSystem account on ProjectInstaller

Notepad Path in VS2008

In my application, I have defined the following:
public static readonly string NOTEPAD = "%windir%\\notepad.exe";
I can type in the text value of NOTEPAD into the Run command on my Win7 machine, and Notepad will open.
However, from within my Visual Studio C# project, the Write Line routine will fire every time:
if (!File.Exists(NOTEPAD)) {
Console.WriteLine("File Not Found: " + NOTEPAD);
}
Does Visual Studio not understand %windir%?
Instead of expanding the variable manually as suggested by the other answers so far, you can have the Environment class do this for you just like the Run command does:
if (!File.Exists(Environment.ExpandEnvironmentVariables(NOTEPAD))) {
Console.WriteLine("File Not Found: " + NOTEPAD);
}
See http://msdn.microsoft.com/en-us/library/system.environment.expandenvironmentvariables.aspx
When looking on my windows XP box, the location of notepad is:
%SystemRoot%\system32\notepad.exe
Not:
%windir%\notepad.exe
You also need to make sure that these environment variables are resolved correctly - use Environment.GetEnvironmentVariable and Path.Combine to build up the correct path:
string root = Environment.GetEnvironmentVariable("SystemRoot");
string path = Path.Combine(root, "system32", "notepad.exe");
Just have a closer Look at the Class Environment. The Environment Variable is SystemRoot, so you can use
Environment.GetEnvironmentVariable("windir") (or something like that)
http://msdn.microsoft.com/en-us/library/system.environment.getenvironmentvariable.aspx
The console "Resolves" the %windir% environment variable to the correct path. You need to use the above function to do the same within your application.
Use Environment.GetEnvironmentVariable("windir");
So you could declare it like this:
public static readonly string NOTEPAD = Environment.GetEnvironmentVariable("windir") + "\\notepad.exe";

Categories

Resources