I know here is some questions about this error in DotNetZip, I've tried all solutions and failed. I'm developing code on my Win8.1 notebook and have no problems, problems begin after deploy to the remote Win2008R2 server...
Here is the problem method:
public bool CreateZIP(string ListStep)
{
Logger logger = LogManager.GetLogger("Task:CreateZIP" + this.TaskGuid);
using (ZipFile zip = new ZipFile())
{
zip.AlternateEncoding = System.Text.Encoding.GetEncoding("cp866");
zip.AlternateEncodingUsage = Ionic.Zip.ZipOption.Always;
...
zip.AddFile(...) loop
...
zip.MaxOutputSegmentSize = Properties.Settings.Default.ZIPSizeLimit * 1024 * 1024;
string zipFolder = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), #"zip-tmp");
string TaskZipFolder = Path.Combine(zipFolder, this.TaskGuid);
try
{
if (!Directory.Exists(zipFolder)) Directory.CreateDirectory(zipFolder);
if (!Directory.Exists(TaskZipFolder)) Directory.CreateDirectory(TaskZipFolder);
zip.TempFileFolder = Path.GetTempPath();
zip.Save(Path.Combine(TaskZipFolder, this.TaskGuid + #".zip"));
}
catch (Exception e)
{
logger.Fatal("Unable to save ZIP into ({0}): {1}", Path.Combine(TaskZipFolder, this.TaskGuid + #".zip"), e.ToString());
throw;
}
}
return true;
}
This code is running on remote server from domain user gfo-svc from C:\Courier\WD directory.
Each object instance has it's GUID, for example e1664582-1bbc-4a9f-a9fe-e7ce4a0a8a55
So the zipFolder variable value is C:\Courier\WD\zip-tmp and TaskZipFolder value is C:\Courier\WD\zip-tmp\e1664582-1bbc-4a9f-a9fe-e7ce4a0a8a55
When this code tries to run it fails with this stack trace:
Unable to save ZIP into (C:\Courier\WD\zip-tmp\e1664582-1bbc-4a9f-a9fe-e7ce4a0a8a55\e1664582-1bbc-4a9f-a9fe-e7ce4a0a8a55.zip): System.UnauthorizedAccessException: Access to the path is denied.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.__Error.WinIOError()
at System.IO.File.InternalMove(String sourceFileName, String destFileName, Boolean checkHost)
at Ionic.Zip.ZipSegmentedStream.TruncateBackward(UInt32 diskNumber, Int64 offset)
at Ionic.Zip.ZipEntry.Write(Stream s)
at Ionic.Zip.ZipFile.Save()
at Ionic.Zip.ZipFile.Save(String fileName)
at Worker.Task.CreateZIP(String ListStep) in Worker.cs:line 844
Line 844 contains this code: zip.Save(Path.Combine(TaskZipFolder, this.TaskGuid + #".zip"));
But in the C:\Courier\WD\zip-tmp\e1664582-1bbc-4a9f-a9fe-e7ce4a0a8a55 folder I can see file e1664582-1bbc-4a9f-a9fe-e7ce4a0a8a55.z01, so the first part of archive was saved before failure.
gfo-svc user has ownership on C:\Courier\WD directory and my code could create zip-tmp directory if it is not exists, and GUID-named directory in it. So the problem is not in Windows Security permissions.
UAC on this remote server is disabled.
What could I do wrong? What might be wrong with my environment? What could I do?
Ok, here is the reason:
This code runs twice on the same host: first time manually from cmd and second time from Windows Task Scheduler.
By default, Task Scheduler starts tasks from C:\windows\system32 and process could not write into it. But my code tried to write into relative to working directory path, so in fact it was trying to write into ...\system32\tmp-dir.
Related
I know this is a common problem with a lot of related topics on here. But none of them seem to work for me.
I have code that works on a production system that I've copied across to my local home computer:
private static void WriteToLog(string logText, string logPath)
{
try
{
using (StreamWriter outputFile = File.AppendText(logPath))
{
outputFile.WriteLine(DateTime.Now.ToString() + "|| " + Regex.Replace(logText, #"\t|\n|\r", ""));
}
}
catch (IOException ex)
{
//what do?
throw ex;
}
}
The line using (StreamWriter outputFile = File.AppendText(logPath)) throws the classic exception:
System.UnauthorizedAccessException: 'Access to the path
'C:\Users\Jaso\Documents\DataChecker_Logs\schema_a-academic_attainment.txt'
is denied.'
At runtime the path variable contains "C:\\Users\\Jaso\\Documents\\DataChecker_Logs\\schema_a-academic_attainment.txt"
The Security of the folder in question looks like this:
When I find the user the process is run under using WindowsIdentity.GetCurrent().Name;, the value returned is "DESKTOP-LMMBET3\\Jaso" which according to the folder's settings (above screenshot) is a principal with full control!!
Windows 10 machine.
GRRR!!!
Check the permission of the file itself not the folder
if you don't have the permission to access the file this error will be thrown
System.UnauthorizedAccessException
When I pass the value from the OpenFilePicker() method back to the button click method, I can utilize a debug string and ensure that the value is not null.
However, when I pass it to the GetCellValue() method, a 'FileNotFound' exception is thrown. Utilizing a debug statement here also shows that the value is not null and returns a valid file path of "C:\Test.xlsx".
Tried changing file permissions to RWX for all, attempted different folder locations. All permissions and folders seem to have the same issue.
public async void FileSelectButton_ClickAsync(object sender, RoutedEventArgs e)
{
string filePath = await openFilePicker();
//Debug.WriteLine("result:: " + filePath);
GetCellValue(filePath, "Sheet1", "A1");
}
public async Task<string> openFilePicker()
{
var archerReportPicker = new
Windows.Storage.Pickers.FileOpenPicker();
archerReportPicker.ViewMode =
Windows.Storage.Pickers.PickerViewMode.Thumbnail;
archerReportPicker.SuggestedStartLocation =
Windows.Storage.Pickers.PickerLocationId.Downloads;
archerReportPicker.FileTypeFilter.Add(".xlsx");
archerReportPicker.FileTypeFilter.Add(".xls"); // Default extensions
Windows.Storage.StorageFile archerReport = await archerReportPicker.PickSingleFileAsync(); //Get file
if (archerReport != null)
{
// Application now has read/write access to the picked file
this.fileTextBox.Text = archerReport.Name; // Load it up and throw the data in the textbox.
var filePath = archerReport.Path;
return filePath;
}
else
{
this.fileTextBox.Text = "";
return null;
}
}
public static string GetCellValue(string fileName, string sheetName, string addressName)
{
string value = null;
// Open the spreadsheet document for read-only access.
using (SpreadsheetDocument document = SpreadsheetDocument.Open(fileName, false)) //Line where exception is thrown
{...}
Throws System.IO.FileNotFound Exception as opposed to opening valid file path.
The issue also occurs when filePath or fileName is defined using const string '#c:\test.xlsx'
The short answer to this question is here:
https://blogs.msdn.microsoft.com/wsdevsol/2012/12/04/skip-the-path-stick-to-the-storagefile/
The gist of it is that in UWP, Storage Pickers return a non-filesystem bound Windows.Storage object. You can glean the filesystem path from the object, but because you are performing an operation on a secondary object, the fact that the user gave permissions for the first object does not apply to the second, resulting in an Access Denied condition when attempting to open the file - even if NTFS permissions allow 'Everyone' access.
This can be confirmed by monitoring the application using Process Monitor from SystemInternals.
If I discover a work-around to this issue, I will update this answer, but I will likely move away from UWP back towards a Windows Forms Application to avoid this issue entirely.
So, I have some logic that looks like the following:
private static void CopyToDestDirectory(string destDirectory, string srcDirectory)
{
if (!Directory.Exists(destDirectory))
{
Directory.CreateDirectory(destDirectory);
}
foreach (var file in Directory.GetFiles(srcDirectory))
{
var filename = Path.GetFileName(file);
var destPath = Path.Combine(destDirectory, filename);
File.Copy(file, destPath, true);
}
...
}
Usually this works, but every once in a while it does not. For the times it does not work, I have a log file which resembles the following:
2016-12-22 15:49:21,670 [11] ERROR:
System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\destPath\FileName.ext'.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)
at System.IO.File.Copy(String sourceFileName, String destFileName, Boolean overwrite)
at Namespace.Class.CopyToDestDirectory(String destDirectory, String srcDirectory)
at Namespace.Class.CallingMethod()
I have no idea why I'm getting an exception about the destination path. It doesn't make sense to me because I make sure to recreate the destination directory before I do my copying.
This is what the calling method looks like. It's notable in that it deletes the dest directory before calling CopyToDestDirectory I wouldn't expect this to be a problem because, and I just recreate the directory it again, and because both this and CopyToDestDirectory are synchronous, but I honestly am not familiar with all of the low-level details behind the System.IO functions, so I think it's worth mentioning.
public void CallingMethod()
{
try
{
...
if (Directory.Exists(destDirectory))
{
Directory.Delete(destDirectory, true);
}
string srcDirectory = GetSrcDirectory();
CopyToDestDirectory(destDirectory, srcDirectory);
...
}
catch (Exception ex)
{
_log.Error("", ex);
throw;
}
}
What might cause an error like this?
I had a similar case with powershell before create SymLinks/Junctions to renewed content of a directory.
as workaround: I´ve ended up in writing a loop, delete/create directory while it exists/or not. I wanted to write a log, for loop case, but since the changes it worked at the first time. strange, maybe the mistake was in the code around, but I hadn´t reproduce it. maybe it´s enough to call Directory.Exists() a second time.
I'm writing a backup program for our new server. I'm an administrator, and I'm learning a lot. The issue is that I can back up a file on the c:\ drive to the c:\ drive, but not for the drives on the SAN, like when I try to backup a file on the T drive (SAN) to the H drive (server). I tried using SetAttributes like
Why is access to the path denied?
but it basically gives the same error message to try setAttributes as I did when I tried to copy the file. This is a portion of my log:
12/30/2013 2:14:57 PM Successful backup of file C:\test\iceCreamCake_12_30_2013_1414P.docx
12/30/2013 2:14:57 PM exception during backupSystem.UnauthorizedAccessException: Access to the path 'T:\T Drive.vhd' is denied.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.File.SetAttributes(String path, FileAttributes fileAttributes)
at Bak.BackItUp(String fromDrive, String toDrive) in C:\Users\michele\BackupProj\ServerBackup\ServerBackup\Backup.cs:line 36
12/30/2013 2:14:57 PM exception during backupSystem.UnauthorizedAccessException: Access to the path 'S:\SQL Database.vhd' is denied.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.File.SetAttributes(String path, FileAttributes fileAttributes)
at Bak.BackItUp(String fromDrive, String toDrive) in C:\Users\michele\BackupProj\ServerBackup\ServerBackup\Backup.cs:line 36
Shouldn't I be able to run my program to do the backup if I'm logged on as Administrator?
Here's part of the code:
try
{
if (System.IO.File.Exists(fromDrive))
{
result = 4;
if (System.IO.Directory.Exists(toDrive))
{
string oldFileName = Path.GetFileName(fromDrive); //file name only
string sourcePath = Path.GetDirectoryName(fromDrive); //path only
string newFileName = AppendFileNameWithDate(oldFileName); //file name with date added
string destFile = System.IO.Path.Combine(toDrive, newFileName); //full path of final destination with new file name
result = 3;
System.IO.File.SetAttributes(fromDrive, FileAttributes.Normal);
System.IO.File.Copy(fromDrive, destFile, true); //copy backupFileName to toDrive, overwrite destination file if it already exists
if (File.Exists(destFile))
{
Logging.Logging.Instance.Debug("Successful backup of file " + destFile);
result = 2;
}
else
{
result = -2;
Logging.Logging.Instance.Debug("Backup *failure of file " + destFile);
}
}
else
{
Logging.Logging.Instance.Debug("to Drive does not exist: " + toDrive);
result = -1;
}
}
else
{
Logging.Logging.Instance.Debug("from Drive does not exist: " + fromDrive);
result = -1;
}
}
catch (Exception ex)
{
Logging.Logging.Instance.Debug("exception during backup" + ex.ToString());
}
The directory strings are like this:
string cDrive = #"C:\backup\2013\iceCreamCake.docx";
string tDrive = #"T:\T Drive.vhd";
string sDrive = #"S:\SQL Database.vhd";
string cDriveToLocation = #"C:\test";
string tDriveToLocation = #"H:\";
string sDriveToLocation = #"E:\";
string vDriveToLocation = #"G:\";
Thanks,
Michele
Thanks for all your help. I wound up specifically adding (security access to) each of my logins (usxxxxxx and M_CL) to the properties of the files/directories, then editing the privileges to get full control, and also removing all spaces in the file name for the t:\ drive file and the c:\ directories file (it was failing for my M_Cl login but not usxxxx), and it worked for c:\ and t:. We thought the general Users and Administrators file access priviledges would work, but it didn't. The other thing I added was instead of having the complete string for t drive defined with file, I did a path combine like
string sDrive = Path.Combine(#"S:\", #"SQL_Database.vhd");
We have an ascx custom control (not a web part) hosted in a special Sharepoint page. This page allows users to upload files to our server. Unfortunately permission issues are preventing Sharepoint from saving files to the network location.
The network account attributed to the application pool for the Sharepoint 2007 based site has "modify" and "read" access granted to the location.
We've logged in to a different machine using the credentials used by the application pool account and can create directories and files without any issue at the specified network location.
Is it possible Sharepoint is trying to use some other account to save these files rather than the one set on it's Application Pool in IIS7?
The error we're getting:
Message: Access to the path '\opal\gwl\pictures\L36' is denied.
Stack Trace: at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) at System.IO.Directory.InternalCreateDirectory(String fullPath, String path, DirectorySecurity dirSecurity) at System.IO.Directory.CreateDirectory(String path, DirectorySecurity directorySecurity) at ECan.SharePoint.Web.Applications.MyECan_WaterMeterFormDatalogger.SavePhotos()
Exception Type: System.UnauthorizedAccessException
User: System Account
The code for the SavePhotos function in the ascx code behind file:
protected void SavePhotos()
{
string wellNo = WellNo.Value;
string epoWaterMeterID = EPO_WaterMeterID.Value;
string dirRoot = ConfigurationManager.AppSettings["PhotoDir"];
string map = wellNo.Substring(0, wellNo.IndexOf('/'));
int photoSaveCount = 1;
foreach (string filePath in Request.Files)
{
HttpPostedFile file = (HttpPostedFile)Request.Files[filePath];
if (file.InputStream.Length > 0)
{
try
{
// Create dir if does not exist
string dir = dirRoot + map;
if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);
// Save file
file.SaveAs(dir + #"\" + wellNo.Replace('/', '_') + "-" + epoWaterMeterID.ToString() + "-" + photoSaveCount.ToString() + ".jpg");
photoSaveCount++;
}
catch (Exception ex)
{
Logger.Write(ex);
}
}
}
}
Anyone have any ideas what the issue might be?
I think you have to call the SavePhotos with elevated privildges.
Running the code with elevated priviledges will executes the specified method with Full Control rights even if the user does not otherwise have Full Control.
See link:
http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spsecurity.runwithelevatedprivileges(v=office.12).aspx
Please try the below code:
protected void Button1_Click(object sender, EventArgs e)
{
SPSecurity.CodeToRunElevated elevatedGetSitesAndGroups = new SPSecurity.CodeToRunElevated(SavePhotos);
SPSecurity.RunWithElevatedPrivileges(elevatedGetSitesAndGroups);
}
Have you tried to set the permission of the newly created directory or folder? You can do so by using the DirectorySecurity class within the System.Security.AccessControl Namespace, and specifically the SetAccessControl Method of that class.