Programmatically get the full path of a shared folder on another computer? - c#

I know that you can get the path to a mapped drive (e.g. Find UNC path of a network drive?), but what if the only thing I have is just the path to the shared folder?
For example, let's say I have a friend who is sharing the folder C:\MyDocs\PublicDoc over the network. I can access it under the path \\danas-pc\PublicDoc. Is there any way that I could, being on another computer, determine that \\danas-pc\PublicDoc actually maps to \\danas-pc\c$\MyDocs\PublicDoc?
I ask because I am given a path to a log file that has the path (e.g. \danas-pc\c$\MyDocs\PublicDoc\mylog.log )and I need to check if it matches the same path that is set in another location. The other location has the "short path" (e.g. \\danas-pc\PublicDoc\mylog.log ), and thus, even though the log paths lead to the same location, the program determines that they are different. I wanted to see if there's a way to figure out that they are pointing to the same location.

I can't imagine why you might need this since for the remote instance's full path is \danas-pc\PublicDoc but if you let your imagination thrive I'd suggest something like this:
(1) on the remote computer inside the share folder you can drop a small script that if executed return the full path. You have to search for appropriate coding for windows or linux environment also you need to have execution privilege or rights on it. for example on windows you can have a vbscrit or cscript and a .sh script in linux.
Also please note that seeing it from the remote host, in terms of the remote host the full path is \NAME-OR-IP\Path\to\Folder\or\File etc. For you on the remote connection that is the full path ;)
UPDATE:
as per the comment below, this is a full script that does the following
creates a vbscript with code in it to retrieve the current full path
copies the files into the network desired path
executes the vbscript and reads the result back
deletes the vbscript
Assuming: you have the read/write access on the network folder
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Mime;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace GetNetworkFullPath
{
class Program
{
static void Main(string[] args)
{
var networkFolder = "\\\\REMOTE-PC-NAME\\SharedFolder";
var nameOfVBScript = "capturepath.vbs";
var vbsOutput = "";
//Get the name of the current directory
var currentDirectory = Directory.GetCurrentDirectory();
Console.WriteLine("Current Dir: " + currentDirectory);
//1. CREATE A VBSCRIPT TO OUTPUT THE PATH WHERE IT IS PRESENT
//Ref. https://stackoverflow.com/questions/2129327/how-to-get-the-fully-qualified-path-for-a-file-in-vbscript
var vbscriptToExecute = "Dim folderName \n" +
"folderName = \"\" \n" +
"Dim fso \n" +
"Set fso = CreateObject(\"Scripting.FileSystemObject\") \n" +
"Dim fullpath \n" +
"fullpath = fso.GetAbsolutePathName(folderName) \n" +
"WScript.Echo fullpath \n";
//Write that script into a file into the current directory
System.IO.File.WriteAllText(#""+ nameOfVBScript + "", vbscriptToExecute);
//2. COPY THE CREATED SCRIPT INTO THE NETWORK PATH
//Ref. https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/file-system/how-to-copy-delete-and-move-files-and-folders
string sourceFile = System.IO.Path.Combine(currentDirectory, nameOfVBScript);
string destFile = System.IO.Path.Combine(networkFolder, nameOfVBScript);
System.IO.File.Copy(sourceFile, destFile, true);
//3. EXECUTE THAT SCRIPT AND READ THE OUTPUT
//Ref. https://stackoverflow.com/questions/27050195/how-do-i-get-the-output-from-my-vbscript-console-using-c
Process scriptProc = new Process();
ProcessStartInfo info = new ProcessStartInfo();
info.WorkingDirectory = #"" + networkFolder + "";
info.FileName = "Cscript.exe";
info.Arguments = nameOfVBScript;
info.RedirectStandardError = true;
info.RedirectStandardInput = true;
info.RedirectStandardOutput = true;
info.UseShellExecute = false;
info.WindowStyle = ProcessWindowStyle.Hidden;
scriptProc.StartInfo = info;
scriptProc.Start();
scriptProc.WaitForExit();
bool exit = false;
while (!scriptProc.StandardOutput.EndOfStream)
{
vbsOutput = scriptProc.StandardOutput.ReadLine();
}
Console.WriteLine("vbscript says: " + vbsOutput);
//4. DELETE THE FILE YOU JUST COPIED THERE
System.IO.File.Delete(#"" + networkFolder + "\\" + nameOfVBScript);
}
}
}
Unfortunately when executed remotely the script replies with the Network Path :( so disappointed...really sorry! As long as execution is happening from a user outside the remote system it will reply with the absolute path related to that instance. I think an internal process/user should execute the file and reply back with the answer to the application.
I'll try to think something more tomorrow and maybe reply back if I'm lucky.

Related

Failed to convert xml to csv using perl script through c#

I have the following code for converting xml to csv by using perl script. When I run the perl script through c# but there is no files are created and string output become empty.
What is the problem?
I have the perl script with .txt extention, Is this ok or not?
string filePath = Path.GetDirectoryName(Path.GetDirectoryName(Directory.GetCurrentDirectory())) + "/Files/SAVVIS_CDR_1806012231.XML";
if (Path.GetExtension(filePath) != "csv")
{
ProcessStartInfo perlStartInfo = new ProcessStartInfo(#"C:\Strawberry\perl\bin\perl.exe");
string perlScriptFilePath = Path.GetDirectoryName(Path.GetDirectoryName(Directory.GetCurrentDirectory())) + "/PerlScript/formatter_savvis.pl.txt";
string csvFilePath = Path.GetDirectoryName(Path.GetDirectoryName(Directory.GetCurrentDirectory())) + "/PerlScript/";
perlStartInfo.Arguments = perlScriptFilePath + " " + filePath + " " + csvFilePath;
perlStartInfo.UseShellExecute = false;
perlStartInfo.RedirectStandardOutput = true;
perlStartInfo.RedirectStandardError = true;
perlStartInfo.CreateNoWindow = false;
Process perl = new Process();
perl.StartInfo = perlStartInfo;
perl.Start();
perl.WaitForExit();
string output = perl.StandardOutput.ReadToEnd();
}
Could you please anyone help me to solve this problem?
Thanks in advance.
First, to find out what went wrong:
string error = perl.StandardError.ReadToEnd();
Also, make sure you have necessary permissions to create files in the output directory. You may try to run your process with Admin privileges to find out if it's a permission issue:
perlStartInfo.Verb = "runas";
You may want to run your entire host process with elevated permissions for this.
(This is only to figure out if it's a permission issue! If it's the case, grant the output directory the necessary permissions, and if possible don't automatically run scripts with admin privileges in production environment)
There also may be errors in the perl script itself.

WPF: unable to map network drive for all users

I'm trying to create a function for an application to automatically copy over specific files during the final stage of a job. The only issue here is that the copy location is a protected share drive and uses a separate login instead of being validated by the active directory so I've got to do a bit of a workaround to get File.Copy() working. My workaround has been to call the built in net.exe utility and passing a command line argument that points to the share drive to open up a connection to the drive then using File.Copy() to get the file where it needs to go then deleting the connection. The issue at hand is that this works great on my computer but when anyone else on the team runs the same program a "Logon failure: unknown user name or bad password" is thrown. I'm at a bit of loss as to why this would happen since the username and password are static and not being changed and everyone on the team has the same network permissions I do. Here is the WPF/C# code I'm using to do this:
try
{
string mrdfDropPath = #"dropPathHere";
string MRDFPath = #"storePath\test.xml";
string command = #"use " + mrdfDropPath + #" /user:CORP\Username Password";
Process.Start("net.exe", command);
File.Copy(MRDFPath, mrdfDropPath + "test.xml");
string command2 = #"use " + mrdfDropPath + #" /delete";
Process.Start("net.exe", command2);
StreamWriter writer = new StreamWriter(#"logPath\log.txt", true);
writer.WriteLine(mrdfDropPath + "test.xml" + "," + File.GetLastWriteTime(MRDFPath).ToString());
writer.Close();
}
catch (Exception e)
{
StreamWriter writer = new StreamWriter(#"logPath\log.txt", true);
writer.WriteLine(e.Message);
writer.Close();
}
Like I said this works as expected during debug and when I run the application, but for anyone else it is throwing the error.

'No such file or directory' if process is run programmatically (from C#)

I have an application that dumps a lot of files to a directory. I want to copy these files to a Hadoop cluster using the hadoop command. I use the following code to run the command.
System.Diagnostics.ProcessStartInfo export = new System.Diagnostics.ProcessStartInfo();
export.RedirectStandardOutput = false;
export.RedirectStandardError = false;
export.UseShellExecute = false;
export.WorkingDirectory = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
export.FileName = "hadoop";
export.Arguments = "fs -copyFromLocal " + Path.Combine(dumpDirectory, "*.txt") + " " + hadoopPath));
Console.WriteLine("Copying data: hadoop " + export.Arguments);
System.Diagnostics.Process proc = System.Diagnostics.Process.Start(export);
proc.WaitForExit();
if (proc.ExitCode == 0)
{
IEnumerable<string> files = Directory.EnumerateFiles(dumpDirectory);
foreach (string file in files)
File.Delete(file);
}
else
Console.WriteLine("Error copying to Hadoop: " + proc.ExitCode);
The program writes the following message:
Copying data: hadoop fs -copyFromLocal local/directory/*.txt /user/remote/directory/
copyFromLocal: `local/directory/*.txt': No such file or directory
Error copying to Hadoop: 1
Interestingly, when I run the command manually, the files copy without error.
Also, if the program runs the command without using *.txt and instead calls the command for each file individually, the command succeeds.
Can anyone shed some light on this?
I partially resolved the problem by creating a bash script containing the given command. I ran the bash script programmatically and it worked.
However, I still do not know why the original did not work.

Starting a Jar file using System.Diagnostics.Process

I have a jar file which I want to run from within C#.
Here's what I have so far:
clientProcess.StartInfo.FileName = #"java -jar C:\Users\Owner\Desktop\myJarFile.jar";
clientProcess.StartInfo.Arguments = "[Something]";
clientProcess.Start();
clientProcess.WaitForExit();
int exitCode = clientProcess.ExitCode;
Unfortunatly I get "System could not find specified file", which makes sense since its not a file its a command.
I've seen code online which tells you to use:
System.Diagnostics.Process.Start("java -jar myprog.jar");
However I need the return codes AND I need to wait for it to exit.
Thanks.
Finally solved it. The filename has to be java and the arguments has to contain the location of the jar file (and anything arguments you want to pass that)
System.Diagnostics.Process clientProcess = new Process();
clientProcess.StartInfo.FileName = "java";
clientProcess.StartInfo.Arguments = #"-jar "+ jarPath +" " + argumentsFortheJarFile;
clientProcess.Start();
clientProcess.WaitForExit();
int code = clientProcess.ExitCode;
You need to set environment variable Path of java.exe executable or specify the full path of java.exe.
ProcessStartInfo ps = new ProcessStartInfo(#"c:\Program Files\java\jdk1.7.0\bin\java.exe",#"-jar C:\Users\Owner\Desktop\myJarFile.jar");
Process.Start(ps);

How to share remote folders?

I'm working on a .NET class that will be used in tools to manage our Active Directory accounts. Each of our accounts gets a network home directory, which can be located on a couple different servers, depending on what type of account we're working with.
I can create and delete the folders just fine, but I'm running into trouble sharing the folders. I found some code here that seems to be what I want, but it isn't working properly for me. The return value I get is 2, but I'm not sure what that indicates.
This shouldn't be a file permission issue, since I'm running my test application as myself, and I have full control of the folder that I'm trying to share (and each of its parent folders).
Here's my (modified) version of the code:
char[] delim = { '\\' };
// folderPath is a string (UNC path)
string[] drivePath = folderPath.Split(delim);
// Create a ManagementClass object
ManagementClass managementClass = new ManagementClass("Win32_Share");
// Create ManagementBaseObjects for in and out parameters
ManagementBaseObject inParams =
managementClass.GetMethodParameters("Create");
ManagementBaseObject outParams;
// Set the input parameters
inParams["Description"] = "";
inParams["Name"] = drivePath[3];
inParams["Path"] = folderPath;
inParams["Type"] = 0x0; // Disk Drive
// Invoke the method on the ManagementClass object
outParams = managementClass.InvokeMethod("Create", inParams, null);
I've tried outputting the other outParams, but it looks like ReturnValue is all I get.
Is there a different way to share a remote folder that would work better?
I'll answer myself, in case someone else finds this later.
I ended up going with the extremely unsexy answer of using PSExec and NET SHARE:
// Retrieve drive path from AD
char[] delim = { '\\' };
string[] drivePath = userAD.HomeDirectory.Split(delim);
// Configure startup properties of process
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = true;
startInfo.FileName = "C:\\Windows\\System32\\psexec.exe";
// Build arguments for folder on alpha or student
startInfo.Arguments = "\\\\" + serverName + " -s net share " + shareName + "=" folderPath + "$ /GRANT:\"authenticated users\",full";
Process process = new Process();
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
Note that in our environment the program will already be running under a user who has Full Control permissions on the folder being shared. To allow similar for a non-privileged user, you have to specify a name and password in startInfo.Arguments.

Categories

Resources