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
Related
I have an application that should be able to run explicit tasks in another users context, so that within the application, a less privileged user is able to do some tasks, he is not allowed to.
I used for this an impersonation and it works fine with the acutal code, but I can not make it work with a Folderbrowser Dialog. I think the browser is executed within the context of the correct user, but uses other windows functions which override the user context.
My code that does not work is:
private void tb_customRoot_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
ImpersonationHelper.Impersonate("STARK", VSSFileExplorer.Properties.Settings.Default.FS_User, BASE64.Base64Decode(VSSFileExplorer.Properties.Settings.Default.FS_Password), delegate
{
VistaFolderBrowserDialog myFancyFolderDialog = new VistaFolderBrowserDialog();
DirectoryInfo rootDir = new DirectoryInfo(#"C:\");
try
{
rootDir = new DirectoryInfo(VSSFileExplorer.Properties.Settings.Default.CustomRoot);
}
catch
{ throw; }
myFancyFolderDialog.SelectedPath = rootDir.ToString();
myFancyFolderDialog.ShowDialog();
tb_customRoot.Text = myFancyFolderDialog.SelectedPath;
});
}
The problem is, that after opening the browser dialog, windows opens a "Enter network credentials" login prompt. The user should not know this credentials.
Is there a way to run a Folderbrowserdialog with another users rights?
I also build a function which will generate the correct path from some Tools in the GUI, but I am really interested if this is possible.
Thanks in advance.
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.
I have an ASP.NET application which requires write access on the App_Data subfolder. The MSI used to deploy the application tries to set the permissions correctly, but in spite of this, it seems the permissions are sometimes wrong. Most of the application works fine without this permission. I would prefer that the application fails to start if the permissions are wrong.
What is the best practice for ensuring that the necessary permissions are correct for the IIS user context? Ideally I want to display some simple instructions for fixing whatever is wrong. And I want the message to appear in as many incorrect configurations as possible.
The following describes what I've tried so far, until I realised there's a probably a better or standard way.
I tried putting this in Application_Start()
protected void Application_Start(Object sender, EventArgs e)
{
// Assert permissions on writeable folders are correct
var permissionsChecker = new AppDataPermissionsChecker();
permissionsChecker.AssertFolderIsWriteable(
HttpContext.Current.Server.MapPath("~/App_Data"));
// remainder of Application_Start()...
}
where AppDataPermissionsChecker is defined as follows:
public class AppDataPermissionsChecker
{
private bool CanWriteAccessToFolder(string folderPath)
{
try
{
// Attempt to get a list of security permissions from the folder.
// This will raise an exception if the path is read only or do not have access to view the permissions.
DirectorySecurity directorySecurity = Directory.GetAccessControl(folderPath);
return true;
}
catch (UnauthorizedAccessException)
{
return false;
}
}
public void AssertFolderIsWriteable(string folderPath)
{
if (!Directory.Exists(folderPath))
throw new Exception(String.Format("The {0} folder does not exist.", folderPath));
if (!CanWriteAccessToFolder(folderPath))
throw new Exception(String.Format("The ASPNET user does not have "
+ "access to the {0} folder. Please ensure the ASPNET user has "
+ "read/write/delete access on the folder. See 'The App_Data folder' "
+ "here: http://msdn.microsoft.com/en-us/library/06t2w7da.aspx'",
folderPath));
}
}
I thought this would throw an ugly exception if the rights are incorrect (which is better than nothing), but in some situations I just get an HTTP Error 503.
I found this implementation of a diagnostics page which does exactly what I was looking for (and more besides).
Why wont the files in the test folder delete?? How can i get admin access??
namespace Delete
{
using System;
using System.Windows.Forms;
using System.IO;
public class Delete
{
public Delete()
{
if (Directory.Exists(#"C:\Program Files (x86)\test\"))
{
string[] filePaths = Directory.GetFiles(#"C:\Program Files (x86)\test\");
foreach (string file in filePaths) { File.Delete(file); }
}
}
}
}
You need to rethink your strategy.
If you are adding/removing files programatically from within your application, they should be stored in a separate location (that won't need admin privs to elevate for writing/deleting, etc.):
like the user's data directory/your company/your application, or
the user's documents/your company/your application
The Program Files directory is for application specific files (DLL's, etc) that are installed with the program but don't change once installed/updated.
Here's an example of the User's Data directory by application:
public static DirectoryInfo ApplicationVersionDirectory()
{
return new DirectoryInfo(System.Windows.Forms.Application.UserAppDataPath);
}
This is due to the UAC. So either run your executable as admin by right clicking -> "Run as Administrator" or if you want to do it programatically refer to other posts like Windows 7 and Vista UAC - Programmatically requesting elevation in C#
In order to delete files from "Program Files" folder you need to start application as an administrator. Otherwise you will not be able to get an access to %PROGRAMFILES%.
Here is the sample code to restart current app and run it as admin:
ProcessStartInfo proc = new ProcessStartInfo();
proc.UseShellExecute = true;
proc.FileName = Application.ExecutablePath;
proc.Verb = "runas";
try
{
Process.Start(proc);
}
catch
{
// The user refused the elevation.
// Do nothing and return directly ...
return;
}
Application.Exit(); // Quit itself
I am creating a Windows Service which I want to use NLog with. I want the logs to be written to the install location of the service say something like:
PathToInstalledService\Logs\MyLog.txt
This is of course going to require administrator priveledges. So my question is, when creating the install for the Service, what account should I use on the ServiceProcessInstaller. I have been currently using LocalService, but this account does not have the required elevation.
Thanks.
During installation you should change the permissions of the 'Logs' directory to allow your service account to write files. Use the account with the least privileges needed to perform your services function, generally the NETWORK SERVICE account.
You can do this from an install class on the service:
void Installer1_AfterInstall(object sender, InstallEventArgs e)
{
string myAssembly = Path.GetFullPath(this.Context.Parameters["assemblypath"]);
string logPath = Path.Combine(Path.GetDirectoryName(myAssembly), "Logs");
Directory.CreateDirectory(logPath);
ReplacePermissions(logPath, WellKnownSidType.NetworkServiceSid, FileSystemRights.FullControl);
}
static void ReplacePermissions(string filepath, WellKnownSidType sidType, FileSystemRights allow)
{
FileSecurity sec = File.GetAccessControl(filepath);
SecurityIdentifier sid = new SecurityIdentifier(sidType, null);
sec.PurgeAccessRules(sid); //remove existing
sec.AddAccessRule(new FileSystemAccessRule(sid, allow, AccessControlType.Allow));
File.SetAccessControl(filepath, sec);
}