C# Windows Services File Move to different directory - c#

Apparently changing codes blows my head.
Here's what i am facing at the moment.
I've developed a service that will extract data from an SQL which converts the data into a CSV file and then upload the file via WinSCP. Once upload finishes , the file is then moved to another directory.
However we had an upgrade and i no longer able to extract the Data from SQL as user have to manually download the file and put into my folder.
I then changed my code to remove the SQL part , and kept sequence starting from the Upload file via WinSCP.
However , now my file move no longer works with error :
File Name couldnt be changed because : Could not find file 'Q:\FrontOffice\Nights\Qualtrics\UNPROCESSED\import-contacts.csv'.
Is there any reason why it cannot find that file when the file and path exist?
Note 1 : The Windows Services is installed in a Server environment. The Server has access to the network drive with admin credentials.
Note 2 : User only need to place the file into Unprocessed folder while the service will process the file and move it to Processed folder.
Here is my previous file move code :
string attachFileLoc = AppDomain.CurrentDomain.BaseDirectory + "\\Logs\\import-contacts-"+ DateTime.Today.AddDays(-1).ToString("yyyyMMdd") + ".csv";
var filename = Path.GetFileName(attachFileLoc);
try
{
System.IO.File.Move(#"C:\Users\Administrator\Documents\Automation\csvfiles\import-contacts.csv", attachFileLoc);
WriteToFile("New File name is : " + filename);
}
catch (System.Exception ex)
{
WriteToFile("File Name couldnt be changed because : " + ex.Message);
}
I then modified my code to reflect to our NAS network folder.
string attachFileLoc = #"Q:\FrontOffice\Nights\Qualtrics\PROCESSED\import-contacts-" + DateTime.Today.AddDays(-1).ToString("yyyyMMdd") + ".CSV";
try
{
System.IO.File.Move(#"Q:\FrontOffice\Nights\Qualtrics\UNPROCESSED\import-contacts.csv", attachFileLoc);
WriteToFile("New File name is : " + filename);
}
catch (System.Exception ex)
{
WriteToFile("File Name couldnt be changed because : " + ex.Message);
}
I then tried to use other methods to obtain file location and name
string[] qfile = Directory.GetFiles(#"Q:\FrontOffice\Nights\Qualtrics\UNPROCESSED\", "*.CSV").FirstOrDefault();
try
{
System.IO.File.Move(qfile[0], attachFileLoc);
WriteToFile("New File name is : " + filename);
}
catch (System.Exception ex)
{
WriteToFile("File Name couldnt be changed because : " + ex.Message);
}
but this one didnt even manage to obtain file name and location.
Edit 1 requested by mjwills :
Edit 2 requested by Caius Jard :

[Solution]
I ran debug and tried to use trycatch method to see what is going on.
Apparently I did not have enough privilege level as per conversation before with others in this thread.
I added the server into Domain as my NAS is also in a domain.
I also added the Windows Services to Log On as a Domain user.
I then proceeded to try removing the mapped drive from the Server. This does not work.
It does work when i have mapped drive or if i do mapping in my code , both while the installed services is in a Server that is in a Domain.
Conclusion :
Windows Services does use mapped drive but windows services authentication is not the same as the User Logged in or the same as the user that has the services installed with.
Solution :
Add LogOn Option to the windows services matching the network drive authentication
i.e : If Network Drive is a NAS in Domain , LogOn option should add Domain ID that has access to the required folder.
i.e2 : If Network Drive is a Shared Folder from PC21 , LogOn option should be an ID that has authentication to the required folder in PC21.

Related

Save files to external(other domain server) server in asp.net

Is it possible to save file to other domain path from file control. I have 2 website www.domain1.com & www.domain2.com. Now I have file control in www.domain1.com & here I want to upload a file which will be store in some directory of www.domain2.com. I don't know is it possible or not. I am trying below basic code but it's not working
if (mainImageUploader.FileName != "")
{
System.IO.FileInfo file = new System.IO.FileInfo(mainImageUploader.PostedFile.FileName);
string newname = file.Name.Remove((file.Name.Length - file.Extension.Length));
newname = (newname + System.DateTime.Now.ToString("_ddMMyyhhmmss")) + file.Extension;
mainImageUploader.SaveAs(Server.MapPath("http://www.domain2.com/images/client-store/" + path + newname));
}
No, not possible if your other server is configured anywhere near correctly.
You need to enable endpoint on your other server to provide file upload. And probably need to secure it somehow - i.e. with username/password.
It's not possible. The better way is creating a WebApi to save file on its server on your second website and save file via calling it from your first website.
Each web server only let to each website to access to its root and subfolders or files.

Creating a folder on the desktop

I want to create a folder on my current user's desktop folder, however; I keep getting an access denied message. I have full write permissions under my profile in IIS.
string activeDir = #"C:\Users\dmm\Desktop\";
string newPath = System.IO.Path.Combine(activeDir, "mySubDir");
System.IO.Directory.CreateDirectory(newPath);
Any help would be appreciated.
Try using the built in objects to get the desktop path, and let .NET also handle the path building for the new folder. You will also want to check if the directory exists first.
string newFolder = "abcd1234";
string path = System.IO.Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.Desktop),
newFolder
);
if(!System.IO.Directory.Exists(path)) {
try {
System.IO.Directory.CreateDirectory(path);
} catch (IOException ie) {
Console.WriteLine("IO Error: " + ie.Message);
} catch (Exception e) {
Console.WriteLine("General Error: " + e.Message);
}
}
When you deploy an application on IIS by default it is executed with ApplicationPoolIdentity. Which is virtual user created and named as IIS AppPool\YourPoolName If this virtual user does not have write access to your desktop. You get that exception.
You have two options.
Give ApplicationPoolIdentity user write access to Desktop directory.
goto Desktop folder and add user IIS AppPool\YourPoolName with write access :
Change pool Identity to user which has write access to directory.
Go
IIS->Application Pools -> Your AppPool ->Advanced Settings -> Identity
->
Select Custom Account and click set button. and there you enter your windows user credentials.
I would recommend first option.
There are many to consider here, first of them being that your application is an ASP.NET application, and every current user will be different. If your application — just assume — runs correctly on your machine, it will never run on hosting environment because they do not grant write permissions to special folders and user accounts.
That said, you need to work in physical paths in order to create your directories.
var path = "C:\\Users\\afzaa\\Desktop\\";
var folder = Path.Combine(path, "folder");
Directory.CreateDirectory(folder);
The result of the above code is,
As you can see, the code properly works and has no issue at all in execution.
There are few things to note:
Your application has read/write permissions. Check IIS for that.
Your code can actually lookup the path you are trying to access. That applies to any folder inside Desktop too, a sub folder may have special permissions applied.
Do not do this, write the content online in your hosting domain. Users have different accounts and structures for folders and thus this will not work — Desktop path is different.
If you want to users to download the file, simply stream the file down and let them save it where they want to.
https://forums.asp.net/t/1807775.aspx?Create+e+New+Folder+Access+Denied+
https://answers.microsoft.com/en-us/windows/forum/windows_xp-files/unable-to-create-the-folder-new-folder-access-is/ac318218-a7b2-4ee2-b301-2ad91856050b
.NET MVC Access denied when trying to create Directory
If you ran your logic from an IIS application, you should use Server.MapPath:
System.IO.Directory.CreateDirectory(Server.MapPath(newPath));

How to create the folder in a remote place using C#

How can I create a folder and programmatically access it on a server using C#?
I have used this code:
string path = #"\\MyIP\C$\NEWFOLDER";
try
{
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
Using above code, I can create a folder on my local machine only!
When I try to create a folder on the server machine, I get this exception:
The user name or password is incorrect
It should work as long as you can access the folder from source (where your program is running). To check it, open file explorer in source machine and type \\targetMachineIp\C$\, if you can reach there and can create a folder that means only problem is in user permissions under which your program is running, try to run it under your user account.
You need do some configurations on your server. This is because local pc -> server need permission. You need to allow IIS have the permission to create a folder on your server.
You receive a "logon failure: unknown user name or bad" error message while accessing remote security-enhanced resources from an ASP.NET application
Homegroup Problem - Logon failure; unknown user name or bad password

Copy file fo mapped network drive using FileInfo.CopyTo

I try to copy a file to a mapped network drive, but I always get the message "Could not find a part of the path ...". I tried different mapped network drives, so I could exclude credential problems (it neither works with a drive connexcted with different credentials nor with my normal user)
try
{
fi.CopyTo(SystemReg.TargetPath + fi.Name);
}
catch (Exception e)
{
SystemReg.Log.AppendLine("Copy failed! " + Environment.NewLine + e.Message);
}
SystemReg.TargetPath is read from an XML file. If I use a local path like D:\temp\ it works perfectly, but e.g. X:\temp\ with X as a mapped drive it fails.
I also tried to run my program in a batch file with "net use..." before calling my program, it also fails.
You shoud use computer address instead of drive name.
For example, if your computer's address is 192.168.0.200 which keeps shared folder temp\ then your full path is \\192.168.0.200\temp\

Moving files on the server side using webservice

I am working on a requirement that has the following logic. code is in C# and .NET CF 3.5
Upload some files from a mobile device to a web server.
when the upload is successful, the file is moved to an archived folder on the mobile device.
Download some files from the server to the mobile device.
When the download is successful, the file has to be moved to an archived folder on the server side in order so as not to download the same file again.
Wrote a web service (asmx) to handle this operation. The uploading and downloading works fine.
The webservice uses the function FileInfo.MoveTo() to move the file from the downloaded folder to the archives on the web server.
This works locally fine (when the webservice and the client calling the webservice are hosted on the same machine) but when deployed to a server, I get this message "the process cannot access the file because it is being used by another process".
I have given the necessary permissions to the IIS account on the server side. I would like to know if that can be achieved at all from the mobile device or is there any other way to invoke that call on the mobile device. I need to execute this method immediately after the file is downloaded.
Sample code is attached.
fileEntriesD = SomeWebService.FilesList();
string[] extractedFiles = fileEntriesD.Split(',');
foreach (string fileName in extractedFiles)
{
//dothe file downloading
//code comes here.......
}
//move the file on the server once all the files are downloaded
foreach (string DumpfileName in extractedFiles)
{
//after the download is complete move the file to the archived folder
string MoveFileOnServerStatus;
MoveFileOnServerStatus = SomeWebService.MoveFileToArchive(DumpfileName);
MessageBox.Show(MoveFileOnServerStatus);
}
code for the WebMethod for MoveFileToArchive(DumpfileName)
[WebMethod(Description="move the file to the archive location")]
public string MoveFileToArchive(string fileArchiveName)
{
try
{
string SerPathD = GetLocationOfFiles + "\\" + "ArchivedDispatchedFiles";
FileInfo MFTA = new FileInfo(SerPathD + "\\" + fileArchiveName);
MFTA.MoveTo(SerPathD + "\\" + fileArchiveName);
}
catch(IOException ex)
{
//if there is any error then return the error message.
return ex.Message.ToString();
}
//if the moving was successful then return 1 to the client.
return "1";
}

Categories