vpetrovic
vpetrovic

Reputation: 527

Start batch process as administrator and stay in current folder

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.

enter image description here

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

Answers (5)

Dennis van Gils
Dennis van Gils

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

MC ND
MC ND

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

RGuggisberg
RGuggisberg

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

trapsuutjies
trapsuutjies

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

kͩeͣmͮpͥ ͩ
kͩeͣmͮpͥ ͩ

Reputation: 7856

I think the ProcessStartInfo.WorkingDirectory might be what you're looking for

Upvotes: 0

Related Questions