Reputation: 527
I have a C# code that starts a "custom action", usually a .bat file that installs/re-installs a Windows service on a machine, but my application only knows that this custom action can be started using Process.Start(). Custom action is triggered when my application downloads files to a user defined folder. This is my folder structure: "new" contains new files, "service" contains files for running a windows service.
My batch file looks like this:
net stop DataExchangeProxyService
installutil /u .\service\DataExchangeProxyService.exe
copy .\new\*.* .\service
installutil .\service\DataExchangeProxyService.exe
net start DataExchangeProxyService
PAUSE
Problem is when i start a process from C# with "runas" verb, then a current directoy is "C:\Windows\System32..."
Process process = new Process();
ProcessStartInfo startinfo = new ProcessStartInfo();
startinfo.FileName = Path.Combine(this.destinationFolder, customAction);
startinfo.Verb = "runas";
process.StartInfo = startinfo;
process.Start();
This way my process cannot find those files because it doesn't run in a destination folder. Batch file has to be like this because it cannot contain absolute paths. How to make a process stay in current destination folder?
Upvotes: 0
Views: 1871
Reputation: 3471
Since I can't reply yet as I'm not a user for that long but you were wondering what pushd "%~dp0"
does;
the pushd command is used to go to a folder, a bit like cd, but also saves that foldername to a stack. With popd you can later return to the stack item at the top. %~dp0
is the folder from which the current bat file is executed.
In conclusion, this code is used to return to the folder from which you executed the batch file and save the folder to the stack.
Upvotes: 0
Reputation: 70971
Another solution could be to modify the batch file to locate itself, change to this folder and then execute the rest of the process
setlocal enableextensions disabledelayedexpansion
call :reinstall
pause
exit /b
:reinstall
pushd "%~dp0" && (
net stop DataExchangeProxyService
installutil /u .\service\DataExchangeProxyService.exe
copy .\new\*.* .\service
installutil .\service\DataExchangeProxyService.exe
net start DataExchangeProxyService
popd
)
Where %~dp0
is the drive and path of the folder that contains the batch file. You can change all file references using this variable so you work with absolute paths or, following your code, change the current active directory and use relative paths
If you are asking why a subroutine, please read In Batch file ~dp0 changes on changing directory
Upvotes: 0
Reputation: 4750
Put this line very near the top of your bat file (before referencing any files/folders)
pushd "%~dp0"
That will work whether 'Run as admin' or not.
Upvotes: 3
Reputation: 56
I don't have all of your source code, so I can't test for you, but I suggest you save the executing directory, and then set your new process to execute there. It's possible that Windows will still take you to the new user's default path, but then you can play around with timing to ensure you're in the right folder at the right time. Something like this:
string savedDirectory = Directory.GetCurrentDirectory();
Process process = new Process();
ProcessStartInfo startinfo = new ProcessStartInfo();
startinfo.FileName = Path.Combine(this.destinationFolder, customAction);
startinfo.Verb = "runas";
startinfo.WorkingDirectory = savedDirectory;
process.StartInfo = startinfo;
process.Start();
Upvotes: 0
Reputation: 7856
I think the ProcessStartInfo.WorkingDirectory
might be what you're looking for
Upvotes: 0