Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exec doesn't work well with forward slash arguments #209

Closed
CoenraadS opened this issue Mar 5, 2023 · 7 comments
Closed

Exec doesn't work well with forward slash arguments #209

CoenraadS opened this issue Mar 5, 2023 · 7 comments

Comments

@CoenraadS
Copy link

CoenraadS commented Mar 5, 2023

Hello, first of all, really nice project :)

I am trying to run InnoSetup, which uses forward slash arguments, e.g.

    exec { $installerPath /verysilent /allusers /dir=$innoSetupDir } -Echo

This doesn't work very well, as powershell complains You must provide a value expression following the '/' operator.

So then I try to workaround by using &

    exec { & $installerPath /verysilent /allusers /dir=$innoSetupDir } -Echo

But now it returns immediately, and doesn't behave correctly on errors.

I understand this is limitation of using [scriptblock] to pass the arguments.

I was wondering if perhaps it's an idea to make something like exec-process ($Command, $ArgumentList), which would just call Start-Process under the hood to handle these situations.

Then I could use e.g. exec-process $installerPath "/verysilent /allusers /dir=$innoSetupDir"

@nightroman
Copy link
Owner

@CoenraadS I am not yet sure it's about exec or Invoke-Build. Can you run your command in plain PowerShell console?

& $installerPath /verysilent /allusers /dir=$innoSetupDir

The first command is not correct, indeed. The second looks correct. What is in your $installerPath exactly? What errors do you get? What version of PowerShell and Invoke-Build do you use?

@CoenraadS
Copy link
Author

CoenraadS commented Mar 5, 2023

The full command is:

C:\Users\asdf\innosetup-6.2.2.exe /verysilent /allusers /dir=C:\Users\asdf\Example

If I run it directly in powershell, it also returns immediately, unless I add | Wait-Process to the end.

=> Works ok:
C:\Users\asdf\innosetup-6.2.2.exe /verysilent /allusers /dir=C:\Users\asdf\Example | Wait-Process

But if I try to that to the exec block, I get Dangling scriptblock at... errors.

e.g. exec { & $installerPath /verysilent /allusers /dir=$innoSetupDir | Wait-Process }

The innosetup installer does trigger a UAC prompt, not sure if related.

@nightroman
Copy link
Owner

nightroman commented Mar 5, 2023

I do not think you use Wait-Process how it is supposed to be used, see Wait-Process

@CoenraadS
Copy link
Author

CoenraadS commented Mar 5, 2023

Hmm I got it from this answer and it works for me: https://stackoverflow.com/a/24439202/4503491
Apparently in newer versions of Powershell it may not work anymore.

Powershell version: 5.1.19041.2364

Invoke Build version: 5.10.2

It's not really a big problem, for now I am just using my own helper function as workaround:

function Run{
    param(
        [String]$FilePath,
        [String]$Arguments,
        [Bool]$ContinueOnError = $False,
        [Bool]$Echo = $True
    )

    if ($Echo)
    {
        "$FilePath $Arguments"
    }

    $elapsed = Measure-Command { $process = Start-Process -FilePath $FilePath -ArgumentList $Arguments -Wait -PassThru -NoNewWindow }

    "Finished in $(Round $elapsed.TotalSeconds 2) seconds"

    if ($ContinueOnError)
    {
        "Exited with status code $($process.ExitCode)"
        return
    }

    if ($process.ExitCode -ne 0)
    {
        throw "Exited with status code $($process.ExitCode)"
    }
}

@nightroman
Copy link
Owner

nightroman commented Mar 5, 2023

Like I said, it is not about exec or Invoke-Build. It is about how innosetup works and you handle it in PowerShell. If it starts and returns immediately then you should not use exec at all. Start it by Start-Process and use -PassThru in order to get the process instance. Then use this instance as input for Wait-Process in order to wait for its exit and then get and check its exit code.

Disclaimer. I do not use innosetup, the above thoughts are just common sense.

@CoenraadS
Copy link
Author

CoenraadS commented Mar 5, 2023

Yes, but I use this nice framework so I could avoid having to write my own helper scripts. Would be nice to support this out of the box, since I don't think it's so unusual, that was all. Indeed I see now it has nothing to do with the forward arguments as I first though.

@nightroman
Copy link
Owner

Start-Process -Wait -PassThru is your friend for not standard cases like innosetup.
In your case something like

$process = Start-Process $installerPath "/verysilent /allusers /dir=$innoSetupDir" -Wait -PassThru
# check $process exit code here

I do not think any support from Invoke-Build is needed for such cases.
(1) PowerShell out of the box tools do the job well.
(2) Commands like innosetup are not typical.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants