ProcessStartInfo.WorkingDirectory can't find the location on server - c#

I have a really strange situation.
In our company we develop big web application which consist of several modules. Each module is divided in separate folders on server. There is one module which launches application mapped on users L:\app.exe disk.
My goal is update the invoking method which first will start the switcher.exe file INSIDE the module and after will start L:\app.exe as it was before.
The problem is that when i build this module on my local it works perfectly fine but when i downloading the content from my bin\Debugg on server-including swither.exe (say on Dev environment) the application fails to find "switcher.exe" in folder on server. It throws an exception which says {"The system cannot find the file specified"}.
The code behind is pretty simple:
private void LaunchSwitherExe()
{
string executionPath = System.IO.Path.GetDirectoryName(
System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
MessageBox.Show(executionPath);
Process themeSwitchProc = new Process();
themeSwitchProc.StartInfo.FileName = "Switcher.exe";
themeSwitchProc.StartInfo.WorkingDirectory = executionPath;
themeSwitchProc.Start();
}
The messagebox shows(for test purposes) the path to swither.exe. And this path is absolutely correct. It has swither.exe inside.
Do you have any ideas?
---UPDATE---
The problem way in the string to the path. This:
string executionPath = System.IO.Path.GetDirectoryName(
System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
Chould be changed to:
string exeDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
Directory.SetCurrentDirectory(exeDir);
Thanks to all folks who answered and especially to "Rick S."

Have you considered it might be permissions issue? What process Id is the code running under and does it have access to that folder?
I also found this:
When the UseShellExecute property is false, gets or sets the working directory for the
process to be started. When UseShellExecute is true, gets or sets the directory that
contains the process to be started.
And maybe try this:
Defining a working directory for executing a program (C#)

Related

Error when start application through \Local Settings\Application Data\ in Windows 7

Simple code:
ProcessStartInfo psi = new ProcessStartInfo(path);
psi.UseShellExecute = false;
Process.Start(psi);
if path = C:\Users\Marat\AppData\Local\MyCompany\Program.exe, it's OK!
but if path = C:\Users\Marat\Local Settings\Application Data\MyCompany\Program.exe
getting Exception:
System.ComponentModel.Win32Exception(0x80004005): An invalid name request was made. The name requested cannot be
retrieved at this time
Actually, everything worked fine, but at some moment it began to give this error.
As far as i can remember the Local Settings folder in Windows 7 it's a link to the AppData folder, mainly used for compatibility with old pre-Windows Vista applications, actually you can't access it directly unless you change the owner of that link (It's System), so that's probably why you're getting this error.
Another cause, could be the white spaces in the name, as you don't show how you construct path or its contents when you start the process.

Copying files to a mapped drive while user is not logged in (scheduled task)

I have a job that needs to connect to two fileshares and copy some files for a data feed.
The source server is on our domain's network, and that works fine. The remote server, however, chokes on me and throws a "Could not find part of the path" error. I should add the destination server lives in a different domain than my source server.
The source and destination paths are read out of my app.config file.
I thought persistently mapping a drive would work, but since this is a scheduled task, that doesn't seem to work. I thought about using NET USE, but that doesn't seem to like taking a username and password.
The really weird thing - if I double click on the job while I'm logged into the machine, it'll run successfully.
Sample code:
DirectoryInfo di = new DirectoryInfo(srcPath);
try
{
FileInfo[] files = di.GetFiles();
foreach (FileInfo fi in files)
{
if(!(fi.Name.Contains("_desc")))
{
Console.WriteLine(fi.Name + System.Environment.NewLine);
File.Copy(fi.FullName, destPath + fi.Name, true);
fi.Delete();
}
}
}
Apparently this isn't as simple as copying the files over. Any suggestions on mapping a drive with credentials in C# 4.0?
EDIT
I'm trying to use a batch file called from the console application that maps the drive while the program is running. I'll know for sure whether that works in the morning.
I'd suggest looking into a proper file transfer protocol, like FTP.
Assuming that's out of the question, try using a UNC path like \\servername\path\file.txt. You will still need credentials, but assuming that the account running the application has those permissions you should be fine. Given that you mention a web.config file, I am guessing that would be an ASP.NET application, and therefore I mean the account that runs the Application Pool in IIS. See http://learn.iis.net/page.aspx/624/application-pool-identities/
What I finally wound up doing was mapping the drive in a batch file called by my program. I just launch a NET USE command and pause for a few seconds for the mapping to complete.
It looks like while the user is logged out, there's no context around mapped drives.

File not found when executable launched from another application

In my application, after the user logs in I set a few picturebox/button/etc images and do some scaling on them and whatnot. I use relative paths for example:
#".\Images\SomeImage.png"
It works fine when the application is launched directly, but if you try to run it via another application:
Process process = new Process();
process.StartInfo.FileName = networkPath;
process.Start();
It dies and comes up with a file not found error, because it cannot locate the images. It also does this if I try to launch it via the command prompt. The executable is stored on a network drive. Why won't the relative path work in this situation? I can just go ahead and hard code the full path but that makes me feel dirty... Any thoughts?
This is because the working directory is different - by default when starting a new process the working directory for the new process is set to the working directory of the existing process (which will in turn probably be the directory that existing application is contained within).
Normally your application will be run with the working directory as the directory that the executable is contained in - this is the default when creating a new shortcut for example (you can see this in the shortcut properties under the "Start in" field.
When your application is run from the command prompt or from another application however the working directory is changed and the relative paths are resolved to a completely different directory.
You can either change the calling application to se the WorkingDirectory property of the new process to the value it expects, however the proper way of fixing this it to modify your application so that it uses absolute paths based on the path to the executable. Assembly.GetExecutingAssembly().Location can be used to get the path to the executable being run and so the following code should do the trick:
static string GetAbsolutePathFromRelative(string RelativePath)
{
string directory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string absolutePath = Path.Combine(directory, RelativePath);
// This final call is to stop paths like "C:\Dir\..\OtherDir\file.txt" being returned
return Path.GetFullPath(absolutePath);
}
You need to set the Process.WorkingDirectory property to the correct path.
The path you posted:
#".\Images\SomeImage.png"
Is not a network path (it is not UNC or using a mapped drive).

Where will the file without path get created in client system

I have the following code in an Winform Application
String[] lines = { "LAST MESSAGE", "101" };
File.WriteAllLines("MPP_Config.txt", lines);
On my Development system, the file gets created under Bin\Debug...
Where will the file be created in the client once it is installed in the client system ?
I deploy to a website using Click once Deployment...
I believe it will be created in current working directory of the application. The application might not have access to this directory, especially on systems with UAC, Vista and windows 7. You should probably think about using the application data directory instead.
String[] lines = { "LAST MESSAGE", "101" };
String fileName = Path.combine(System.Deployment.Application.ApplicationDeployment.CurrentDeployment.DataDirectory,"MPP_Config.txt");
File.WriteAllLines(fileName, lines);
I'm guessing it gets created in the debug folder becuse you have been running it in debug mode. If you ran it in release mode then it will be saved in the bin/release folder.
In other words it will be created in the directory in which the application resides. Why not try it? I.e. copy your exe across...
In the current directory. This means that it might be hard to predict with 100% certainty. If you want to control it, you can use Environment.CurrentDirectory but (as Sam points out in the comments) this may not be a good idea since other code may also depend on the current directory for other purposes.
For instance, the following program will create two different files called "somefile.txt" (given that the exe is not run from the c:\temp directory):
static void Main(string[] args)
{
File.WriteAllText("somefile.txt", "some text");
Environment.CurrentDirectory = #"c:\temp";
File.WriteAllText("somefile.txt", "some text");
}

Win32Exception: The directory name is invalid

I'm trying to run a process as a different user that has Administrator privilege in 2 different computers running Vista and their UAC enabled but in one of them I get a Win32Exception that says "The directory name is invalid"
Can anyone tell me what is wrong with my code?
var myFile = "D:\\SomeFolder\\MyExecutable.exe";
var workingFolder = "D:\\SomeFolder";
var pInfo = new System.Diagnostics.ProcessStartInfo();
pInfo.FileName = myFile;
pInfo.WorkingDirectory = workingFolder;
pInfo.Arguments = myArgs;
pInfo.LoadUserProfile = true;
pInfo.UseShellExecute = false;
pInfo.UserName = {UserAccount};
pInfo.Password = {SecureStringPassword};
pInfo.Domain = ".";
System.Diagnostics.Process.Start(pInfo);
UPDATE
The application that executes the above code has requireAdministrator execution level.
I even set the working folder to "Path.GetDirectoryName(myFile)" and "New System.IO.FileInfo(myFile).DirectoryName"
You need to specify the WorkingDirectory property of ProcessStartInfo`. From Win32Exception error code 267 "The directory name is invalid":
I'm currently working on an "Automated Run As" tool. Its goal is
helping admins which, like me, have to give users a means to execute
one or two programs as Administrator and would like to do so without
having to surrender an admin's password.
So, I'm developing on Vista and I just whipped up a small proof of
concept prototype, that'd run calc.exe as a different user, using
ProcessStartInfo and Process. This worked fine when I executed it as
myself (a rather pointless exercise, I must admit), but when I created
a new user and tried to run it as him, I stumbled upon a
Win32Exception complaining that the directory name is invalid, native
error code 267. I was instsantly baffled, as I knew of no supplied
directory name that could be invalid. I then tested the code on an XP
machine and it worked!
I started googling on it to no avail, many reports of that error but
no conclusive solution, or on different contexts. Finally, after a
while it dawned on me, I wasn't specifying the WorkingDirectory
property of the ProcessStartInfo class, as soon as I added the lines
FileInfo fileInfo = new FileInfo(path); startInfo.WorkingDirectory =
fileInfo.DirectoryName;
To my code, it was allowed to run code as different than logged in
user. ...
It is because the path length of the file exceeds 255 characters.
Try to replace
pInfo.WorkingDirectory = New System.IO.FileInfo(myFile).DirectoryName;
with
pInfo.WorkingDirectory = Path.GetDirectoryName(myFile);
The FileInfo makes an access to the filesystem, and I would assume only the admin user has access to that directory. If it doesn't solve your problem, at least it will make your code a tiny bit faster...
Is the directory the logged-on user's mapped home folder or below that? Than this knowledge base article might help:
"The directory name is invalid" error message when you start Cmd.exe or Notepad.exe by using the Run as feature in Windows
Update: Please note that being member of the Local Administrators group and having administrative privileges are not the same on Vista.
I suppose that everything works fine when you run your C# application as administrator. Right-click the executable, then choose Run as Administrator, or start the application from an elevated command prompt (the fastest way to get one is by pressing Start, enter 'cmd' followed by Ctrl+Shift+Return).
Or, as an alternative, disable UAC for the account running that process.
It is due to space in the folder name. Once I removed the space it started working file when I hit this issue.
I had a similar experience and it turned out to be an issue with our development environment. We map our source code directory to a virtual drive using the subst command. So the FileName and WorkingDirectory properties were being set to "W:\SomeFolder\FileName.exe"
When I hard-coded the FileName & WorkingDirectory to access the files via my actual disk (C:), I stopped receiving the "Invalid Directory" exception.

Categories