Process cannot find file specified - c#

I have the following issue:
I have a C# app that runs as a 32-bit Application on my 64-Bit Machine. This application opens a process and starts wbadmin to make a backup of the C drive.
Now: when I call enter "wbadmin" in the command line wbadmin works and shows lists all its commands.
In my c# app when i do
ProcessStartInfo info = new ProcessStartInfo("wbadmin", $"start backup -backupTarget:{destinationDrive} -include:C: -quiet -vssCopy")
{
UseShellExecute = false
};
Process p = new Process()
{
StartInfo = info,
EnableRaisingEvents = true
};
p.Start();
it tells me that the file specified cannot be found.
I did some research and I think my app is looking for the wbadmin in the WOW64 folder, where it cant find it because it is inside the System32 Folder.
How do I tell my program to use the correct wbadmin.exe in the correct location?
Do I HAVE to run the app as a 64-bit application for it to work?
If so how would i support 32-bit architecture?
Thanks

Thanks to #PavelAnikhouski for providing me with the correct answer.
I had to specify the path to sysnative.

Related

Cannot launch PSEXEC

I have this very simple program
Process process = new Process();
process.StartInfo.FileName = #"psexec";
process.Start();
But when I run it the debug says "The system cannot find the file specified"
If I have the same program and change "psexec" by "Notepad", it works and opens notepad.
Process process = new Process();
process.StartInfo.FileName = #"notepad";
process.Start();
This is weird because I have my psexec in the System32 and if run "psexec" using Windows-Run, it works.
Thank you in advance for any help.
Update: I specify the full path #="C:\Windows\System32\PSexec.exe" and It doesnt work. But If I move Psexec to, as example #"D:\psexec.exe" it works!!
Why coud this happen?
Running programs from c:\windows\system32 is troublesome on a 64-bit operating system. The workaround is Project + Properties, Build tab, change Platform target to AnyCPU. Or to copy the file also to c:\windows\syswow64.
Or to just not put it in the Windows directory, it is not an operating system specific file that belongs there. The appropriate place is the same directory as your EXE.
You can learn more about the File System Redirector in this MSDN article.
try specify the full path of 'psexec'
there is any property 'WorkingDirectory', which might help.

SC.EXE - Calling from C# - Access Denied

I have a batch file I wrote (proof of concept) to install a sample service I also created. It contains the following command line:
sc create serviceTest binPath= C:\Sandbox\ServiceTest\ServiceTest.exe DisplayName= "Service Test"
When I right click and select 'Run as Administrator' everything runs as expected. Running the batch file without doing this gives 'Access Denied'. This is proof that the command works.
I have also tried running the sc command via Process.Start():
const string sc = #"sc";
const string arguments = #"create serviceTest binpath= {0} DisplayName= ""Service Test""";
FileInfo fi = new FileInfo(this.txtServiceLocation.Text);
if (fi.Exists)
{
ProcessStartInfo psi = new ProcessStartInfo()
{
FileName = sc,
Arguments = string.Format(arguments, fi.FullName),
UserName = "admin",
Password = "secret".ToSecureString(),
Domain = "MYDOMAIN",
WorkingDirectory = fi.DirectoryName,
CreateNoWindow = true,
UseShellExecute = false
};
Process.Start(psi);
}
else
MessageBox.Show("The service exe could not be found.");
I need to be able to do this programatically. What do I need to do to get this to work?
CLARIFICATION: I need to be able to do this without a user being prompted. This code will be running under a custom tfs build process.
In Windows 7 by default, runs most applications with least privilege access (non-admin) control. As your application is trying to modify the system, it needs to be elevated to Admin privilege in order to run successfully. If you want to make this app to run in admin privilege permanently, please follow the instructions as in the link
http://www.groovypost.com/howto/microsoft/automatically-run-any-application-as-admin-in-windows-7/
You need to add a UAC manifest file to your assembly in order to force UAC to run the process as an administrator. For a reference to other solutions, you can see UAC need for console application.
While I never got this to work I can still use impersonation via code and also ensure that the tfs build account has appropriate access. This is what I had to do.

Why does my IL generated Assembly, ilasm.exe called by C#, need UAC?

I'm trying to compile an IL Code to an Assembly. The ilasm.exe should get called by my C# Application. I'm invoking the ilasm.exe through an ProcessStartInfo Instance. The generation of the PE works fine and my Assembly is working.
My problem is that the files that were created by my application, afterwards need administrator privileges to be executed.
If I call ilasm.exe manually from command line, no admin rights are needed.
Used ilasm.exe command:
ilasm.exe /qui /output="c:\test\newFile.exe" <path to il file>
My Application calling the ilasm.exe:
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = false;
startInfo.UseShellExecute = false;
startInfo.FileName = #"C:\Windows\Microsoft.NET\Framework\v4.0.30319\ilasm.exe";
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.Arguments = ilFilePath + " /qui /output=" + outputPath + "testFile.exe";
try
{
using (Process exeProcess = Process.Start(startInfo))
{
exeProcess.WaitForExit();
}
}
catch
{
// Log error.
}
Am I doing anything wrong? Do I need to specify anything else when calling another Process from C#?
I'm running my Application and the commandline without admin rights.
It's requiring UAC because you're not supplying a path to a writable location in output, so it's trying to write to the same folder ilasm is in (or the current folder for your app).
A non-admin user doesn't have write access to anything under %WINDIR% (the Windows folder) or %ProgramFiles%, so it's asking for elevation to a user that does have write access to the folder.
What is patchFile?
This comment by #Chris is relevant to this puzzle, I don't see it in the question. You are probably dealing with a difficult problem that Microsoft needed to solve with UAC. Supporting old programs that need UAC privileges but don't ask for it because they were written before Vista. Like installers. And patch programs.
My crystal ball says that your actual program name is not newFile.exe like your question says but has a name like "update.exe" or "patch.exe". And furthermore, it isn't obvious either, that you don't include a manifest in the program you generated. A manifest that says that the program is Vista aware with the <requestedExecutionLevel> element. And furthermore, also not obvious, that when you run this from the command line by hand that you use another name for the .exe.
That's a lot of guesses, but put them together and it makes sense: Windows goes "aha! Old program, sounds like it is going to want to write to .exe files in a restricted directory. Better display the UAC prompt".

c# application doesn't perform batch file command correctly

public void runBatchfile(String batchfilename)
{
try
{
ProcessStartInfo processInfo = new ProcessStartInfo(batchfilename);
processInfo.UseShellExecute = false;
Process batchProcess = new Process();
batchProcess.StartInfo = processInfo;
batchProcess.StartInfo.CreateNoWindow = true;
batchProcess.Start();
batchProcess.WaitForExit();
}
catch (Exception r) { }
}
runBatchfile(#"c:\lol.bat");
lol.bat contains these 2 lines
dir c:\ /s /b > c:\filelist.txt
exit
and when I run my code all it does is creating a filelist.txt file, but doesn't actually perform the rest of the command, which does work if I manually insert it into CMD.
Btw I've tried making the extension .cmd and I also tried without the exit command, without any other results.
please help me :)
On my Windows 7 64-bit machine with Visual Studio 2010, running this code straight from the IDE doesn't do anything whatsoever.
On a hunch that it might have something to do with permission to write to the root directory of drive C:, I tried running the .exe directly from an Explorer window with admin rights (right-click, Run as Administrator) and that worked.
I'd say it's a permission problem.
Maybe you could redirect the output to a file located elsewhere?
update:
I changed the batch file so that the dir command gets redirected to my desktop and it runs just fine.
I've had issues with this as well when calling from C#. The workaround that I usually use is to physically allow it to show the window when running the command. Not sure why this makes a difference but it has worked for me in the past.

Process.Start("IIS Manager.lnk") fails with "The system cannot find the file specified"

I'm launching the path C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Administrative Tools\IIS Manager.lnk via Process.Start, but it fails with The system cannot find the file specified.
The link shows up on a dir, so it exists.
Can it be permissions?
Notes:
The path is auto-discovered by iterating over the Start Menu directory.
I can launch it via explorer and command line.
Clarifications:
Code is as follows:
public void Execute() { Process.Start(_shortcut.FullName);}
_shortcut is of type FileInfo
_shortcut.Exists is true, so the file can be found
replacing _shortcut.FullName with the explicit path #"C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Administrative Tools\IIS Manager.lnk" has the same effect.
This is a WPF app using Caliburn and MEF.
Running as Administrator has the same effect.
This here on the other hand seems to work:
[Fact]
public void TestIisManager()
{
var path = new FileInfo(#"C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Administrative Tools\IIS Manager.lnk");
Process.Start(path.FullName);
}
It does seem to be a bit "environment" based.
Second clarification:
It seems to work in a Windows 7 x86 but not in a Windows 7 x64.
I ran into this recently. Windows Forms based solution, VS2013, x64 machine. Process.Start() could not launch applications via .lnk file. Using process explorer, it seemed that the target specified in the .lnk file was resolving incorrectly to c:\program files (x86)... instead of c:\program files... I followed Bruno's excellent advice, but then again my Target was already marked as "AnyCPU".
After some head scratching, it turned out there's a new compiler flag in VS11+ called "Prefer 32-bit" that was checked by default. This was forcing the EXE output to be 32-bit even though my OS was 64-bit and platform was set to AnyCPU. After I unchecked and recompiled, the problem was fixed.
More reading at: http://blogs.microsoft.co.il/sasha/2012/04/04/what-anycpu-really-means-as-of-net-45-and-visual-studio-11/
Found the issue.
The WPF application was compiled as x86 (all other dlls were compiled as AnyCPU), and when launching some executables or links in a 64 bit machine it failed.
Changing the "Platform Target" to AnyCPU fixes this.
This may not actually relate to your situation, but you can launch the IIS Manager by using
Process.Start("inetmgr.exe")
If you want to continue to use the shortcut, it will probably work if you start the process using a ProcessStartInfo and set ProcessStartInfo.UseShellExecute to true
Can you make sure that you are trying this from an STA thread? You can see whether the apartment state is a problem if the following sample succeeds:
using System;
using System.Diagnostics;
public class Program
{
// make sure to call Process.Start from an STA thread
[STAThread]
static void Main(string[] args)
{
Process.Start(#"C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Administrative Tools\IIS Manager.lnk");
}
}
Process.Start calls ShellExecute under the hood to run the file passed. As described by Raymond Chen, shell functions require an STA thread:
One possible reason why ShellExecute returns SE_ERR_ACCESSDENIED and ShellExecuteEx returns ERROR_ACCESS_DENIED
As stated already, you will see the "The system cannot find the file specified" error because Windows is looking for inetmgr.exe in ...\SysWOW64\intsrv\ (caused by file system redirection), but it only exists in ...\System32\intsrv\.
This is caused by your 32-bit executable attempting to launch a 64-bit executable. As suggested, not using a 32-bit executable will solve this, but for anyone who must build for 32-bit (a WiX installer bundle in my case), try the following.
Using the start menu LNK/shortcut to inetmgr.exe instead of the executable is a good start, but an extra level of distance is required. This can be provided by using explorer.exe, which can be launched from a 32-bit executable:
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.FileName = "explorer.exe";
startInfo.Arguments = "/seperate /root,\"C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\Administrative Tools\\IIS Manager.lnk\"";
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo = startInfo;
process.Start();
It's a bit of a hack, but try launching it like this:
string path = #"C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Administrative Tools\IIS Manager.lnk";
Process.Start("cmd.exe", String.Format("/k \"\"{0}\"\"",path));
Note the double quotes needed to save the spaces in the path.
That way, you might see a more precise error message and/or walk around in the command environment afterwards to see what is wrong with the path.

Categories

Resources