I need to copy the images from C:/images folder to my web application folder which is running in the server.I used the following code which work well in local application but not work in server
string sourcePath = #"D:\images";
//string destinationPath = #"D:\a";
string destinationPath = Server.MapPath("SMSImages") + "\\";
if (System.IO.Directory.Exists(sourcePath))
{
string[] files = System.IO.Directory.GetFiles(sourcePath);
foreach (string s in files)
{
fileName = Path.GetFileName(s);
destFile = Path.Combine(destinationPath, fileName);
File.Copy(s, destFile, true);
}
how to copy
Servers often have a lot of security limitations for the IIS user.
Check if the user under which you are running your asp.net process has authorization to access this path.
You can log the exceptions that are occurring in this code to see if it is causing an access violation.
The following code can help you check if code if you have access
UserFileAccessRights rights = new UserFileAccessRights(sourcePath);
if (rights.canWrite() && rights.canRead()) {
lblLogMsg.Text = "R/W access";
} else {
if (rights.canWrite()) {
lblLogMsg.Text = "Only Write access";
} else if (rights.canRead()) {
lblLogMsg.Text = "Only Read access";
} else {
lblLogMsg.Text = rights.ToString();
}
}
It doesn't work because the program search a D:\ path in server not in local system.
Related
I use this code in my application to display some images stored on a network drive, for example with the path //MyCompanyServer/Folder
public ActionResult DocumentoLista(string area)
{
if (String.IsNullOrEmpty(area))
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var doc = db.Documentos.Where(x => x.area == area).FirstOrDefault();
if (doc == null)
{
return HttpNotFound();
}
string dirPath = Path.GetFullPath(doc.path);
List<string> dirs = new List<string>(Directory.EnumerateDirectories(dirPath));
List<string> files = new List<string>();
DirectoryInfo dirInfo = new DirectoryInfo(dirPath);
foreach (string fInfo in Directory.EnumerateFiles(dirPath, "*.*", SearchOption.TopDirectoryOnly)
.Where(s => s.EndsWith(".png")
|| s.EndsWith(".PNG")
|| s.EndsWith(".jpg")
|| s.EndsWith(".JPG")
).Select(Path.GetFileName)
)
{
files.Add(fInfo);
}
ViewBag.Area = area;
ViewBag.Dirs = dirs;
ViewBag.MyList = files;
return View(doc);
}
It works perfectly on my dev machine but when I tried it from my deployment server, it doesn´t work. I think that maybe it´s not working because in my dev computer I´m executing it with my LDAP user and in my production server (IIS) the user is different and it doesn´t have permision to access to this path.
¿Could be?
Witch user executes asp applications? to what user do I need to give permissions in order to make it work?
Thanks
Pretty sure that the user your application pool is running under doesn't have permissions for that path, you need to:
Locate your application pool in IIS
Check the user account it's running against (In Basic Settings)
Give that user access to the path that you're trying to access (using windows security).
Give IUSR access to the folder.
http://www.iis.net/learn/get-started/planning-for-security/understanding-built-in-user-and-group-accounts-in-iis
I am trying to create a file in my ASP.NET application (IIS 7.5). The file write is done in a separate thread and is giving access not available error.
What kind of permission does the directory need? I have tried giving full access to IIS_IUSRS and IUSR. But this did not work. Everything works okay in my local machine, but once deployed on the server, I get access error.
string filePath = MapPath("c:\FilePath\");
PrintFile printFile = new PrintFile();
Thread printFileThread = new Thread(delegate()
{
printFile.PrintFile(filePath);
});
printFileThread.Start();
public void PrintFile(string filePath)
{
if (Directory.Exists(filePath) == false)
{
Directory.CreateDirectory(filePath);
}
FileStream fs = new FileStream(filePath + "NewFile.pdf", FileMode.Create);
}
I uploaded nopcommerce solution to appharbor (using this method Can't build notcommerce project under appharbor) and solution succesfully builded, but I receiving 403 error - Forbidden: Access is denied when trying to open page(Allow write-access to file system is set to true).
Thanks and hope for your help
The problem is that the standard NopCommerce solution contains two Web Projects. AppHarbor only deploys one web project per application, and in this case, we happen to deploy Nop.Admin which is not what you want.
To resolve this, you should take advantage of the AppHarbor solution file convention and create an AppHarbor.sln solution file that only references the Nop.Web project.
We use a wrapper in our base controller to ensure that all of our code is oblivious to appharbor port changing.
First, fix in Webhelper.cs:75
public virtual string GetThisPageUrl(bool includeQueryString, bool useSsl)
{
string url = string.Empty;
if (_httpContext == null)
return url;
if (includeQueryString)
{
string storeHost = GetStoreHost(useSsl);
if (storeHost.EndsWith("/"))
storeHost = storeHost.Substring(0, storeHost.Length - 1);
url = storeHost + _httpContext.Request.RawUrl;
}
else
{
#if DEBUG
var uri = _httpContext.Request.Url;
#else
//Since appharbor changes port number due to multiple servers, we need to ensure port = 80 as in AppHarborRequesWrapper.cs
var uri = new UriBuilder
{
Scheme = _httpContext.Request.Url.Scheme,
Host = _httpContext.Request.Url.Host,
Port = 80,
Path = _httpContext.Request.Url.AbsolutePath,
Fragment = _httpContext.Request.Url.Fragment,
Query = _httpContext.Request.Url.Query.Replace("?", "")
}.Uri;
#endif
url = uri.GetLeftPart(UriPartial.Path);
}
url = url.ToLowerInvariant();
return url;
}
So what we did is simply add files from https://gist.github.com/1158264 into Nop.Core\AppHarbor
and modified base controllers:
nopcommerce\Presentation\Nop.Web\Controllers\BaseNopController.cs
public class BaseNopController : Controller
{
protected override void Initialize(RequestContext requestContext)
{
//Source: https://gist.github.com/1158264
base.Initialize(new RequestContext(new AppHarborHttpContextWrapper(System.Web.HttpContext.Current),
requestContext.RouteData));
}
//Same file from here downwards...
}
nopcommerce\Presentation\Nop.Web.Admin\Controllers\BaseNopController.cs
public class BaseNopController : Controller
{
protected override void Initialize(System.Web.Routing.RequestContext requestContext)
{
//set work context to admin mode
EngineContext.Current.Resolve<IWorkContext>().IsAdmin = true;
//Source: https://gist.github.com/1158264
base.Initialize(new RequestContext(new AppHarborHttpContextWrapper(System.Web.HttpContext.Current), requestContext.RouteData));
//base.Initialize(requestContext);
}
//Same file from here downwards...
}
Enable the Directory Browsing feature in IIS Express
Note This method is for the web developers who experience the issue when they use IIS Express.
To do this, follow these steps:
Open a command prompt, and then go to the IIS Express folder on your computer. For example, go to the following folder in a command prompt:
C:\Program Files\IIS Express
Type the following command, and then press Enter:
appcmd set config /section:directoryBrowse /enabled:true
refrence :https://support.microsoft.com/en-us/kb/942062
All works fine on my dev machine but if deployed to IIS the process doesn't get started. I am starting a powershell script by
private void RunScript()
{
Process process = null;
try
{
int timeout = 1800000;
var startInfo = new ProcessStartInfo
{
FileName = #"powershell.exe",
Arguments = string.Format("{0} {1}", "\path\toscript", "myParam"),
UseShellExecute = false,
CreateNoWindow = true
};
process = Process.Start(startInfo);
process.WaitForExit(timeout);
}
finally
{
if (!process.HasExited)
{
if (process.Responding)
process.CloseMainWindow();
else
process.Kill();
}
if (process != null)
{
process.Close();
process.Dispose();
}
}
}
Here's what's configured for the app pool this is running under.
Process Model
->Identity = domain user who is a Domain Admin.
->Load User Profile = True
Web App
Authentication is Windows
What else do I need to configure to so that I can run the Process?
As Start-Automating suggested I eventually ended up doing this:
using (Runspace runSpace = RunspaceFactory.CreateRunspace())
{
try
{
runSpace.Open();
RunspaceInvoke scriptInvoker = new RunspaceInvoke(runSpace);
scriptInvoker.Invoke("Set-ExecutionPolicy Unrestricted");
using (Pipeline pipeLine = runSpace.CreatePipeline())
{
var myCommand = new Command(scriptPath);
var myParam1 = new CommandParameter("-paramName", "someValue");
myCommand.Parameters.Add(myParam1);
pipeLine.Commands.Add(myCommand);
pipeLine.Commands.Add("Out-String");
Collection<PSObject> returnObjects = pipeLine.Invoke();
runSpace.Close();
return returnObjects;
}
}
finally
{
runSpace.Close();
}
}
On the IIS server I executed the following powershell command "Set-ExecutionPolicy RemoteSigned"
It's much better to embed the PowerShell APIs the call the .exe
Here's an old link that will get you a PowerShell runspace embedded in ASP.NET per user:
http://powershellpipeworks.com/
Check the permissions of the file system where powershell.exe lives.
Also, check the Security Log in the Event Viewer for authentication errors and access violations.
I have a ASP.NET SOAP web service whose web method creates a PDF file, writes it to the "Download" directory of the applicaton, and returns the URL to the user. Code:
//Create the map images (MapPrinter) and insert them on the PDF (PagePrinter).
MemoryStream mstream = null;
FileStream fs = null;
try
{
//Create the memorystream storing the pdf created.
mstream = pgPrinter.GenerateMapImage();
//Convert the memorystream to an array of bytes.
byte[] byteArray = mstream.ToArray();
//return byteArray;
//Save PDF file to site's Download folder with a unique name.
System.Text.StringBuilder sb = new System.Text.StringBuilder(Global.PhysicalDownloadPath);
sb.Append("\\");
string fileName = Guid.NewGuid().ToString() + ".pdf";
sb.Append(fileName);
string filePath = sb.ToString();
fs = new FileStream(filePath, FileMode.CreateNew);
fs.Write(byteArray, 0, byteArray.Length);
string requestURI = this.Context.Request.Url.AbsoluteUri;
string virtPath = requestURI.Remove(requestURI.IndexOf("Service.asmx")) + "Download/" + fileName;
return virtPath;
}
catch (Exception ex)
{
throw new Exception("An error has occurred creating the map pdf.", ex);
}
finally
{
if (mstream != null) mstream.Close();
if (fs != null) fs.Close();
//Clean up resources
if (pgPrinter != null) pgPrinter.Dispose();
}
Then in the Global.asax file of the web service, I set up a Timer in the Application_Start event listener. In the Timer's ElapsedEvent listener I look for any files in the Download directory that are older than the Timer interval (for testing = 1 min., for deployment ~20 min.) and delete them. Code:
//Interval to check for old files (milliseconds), also set to delete files older than now minus this interval.
private static double deleteTimeInterval;
private static System.Timers.Timer timer;
//Physical path to Download folder. Everything in this folder will be checked for deletion.
public static string PhysicalDownloadPath;
void Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup
deleteTimeInterval = Convert.ToDouble(System.Configuration.ConfigurationManager.AppSettings["FileDeleteInterval"]);
//Create timer with interval (milliseconds) whose elapse event will trigger the delete of old files
//in the Download directory.
timer = new System.Timers.Timer(deleteTimeInterval);
timer.Enabled = true;
timer.AutoReset = true;
timer.Elapsed += new System.Timers.ElapsedEventHandler(OnTimedEvent);
PhysicalDownloadPath = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath + "Download";
}
private static void OnTimedEvent(object source, System.Timers.ElapsedEventArgs e)
{
//Delete the files older than the time interval in the Download folder.
var folder = new System.IO.DirectoryInfo(PhysicalDownloadPath);
System.IO.FileInfo[] files = folder.GetFiles();
foreach (var file in files)
{
if (file.CreationTime < DateTime.Now.AddMilliseconds(-deleteTimeInterval))
{
string path = PhysicalDownloadPath + "\\" + file.Name;
System.IO.File.Delete(path);
}
}
}
This works perfectly, with one exception. When I publish the web service application to inetpub\wwwroot (Windows 7, IIS7) it does not delete the old files in the Download directory. The app works perfect when I publish to IIS from a physical directory not in wwwroot. Obviously, it seems IIS places some sort of lock on files in the web root. I have tested impersonating an admin user to run the app and it still does not work. Any tips on how to circumvent the lock programmatically when in wwwroot? The client will probably want the app published to the root directory.
Your problem may be related to the fact that IIS reloads the Web Service Application if the directory or files contained in the main folder changes.
Try creating / deleting files in a temporary folder which is outside the root folder of your application (be aware of permissions on the folder to allow IIS to read/write files).
Instead of writing directly to the file system, why not use isolated storage?
http://msdn.microsoft.com/en-us/library/system.io.isolatedstorage.isolatedstorage.aspx
This should solve any location or permission based issues that you are having
I forgot to come back and answer my question.
I had to give the IIS_IUSRS group Modify permissions to the directory where I was reading/writing files.
Thanks to all those who answered.