JuliaInterop / MATLAB.jl

Calling MATLAB in Julia through MATLAB Engine
MIT License
270 stars 63 forks source link

Automatic COM server registration on Windows #182

Closed stillyslalom closed 3 years ago

stillyslalom commented 3 years ago

Matlab versions >= R2020a include a comserver function for COM server registration which doesn't require admin permissions. For earlier versions, it's possible to use a PS script (like this) to raise the UAC prompt for matlab -regserver instead of requiring users to open an admin command prompt. Sketching out a flowchart,

musm commented 3 years ago

Sounds great to me. Do you intend to open a PR?

stillyslalom commented 3 years ago

Yeah, I'll put something together.

musm commented 3 years ago

https://github.com/stillyslalom/Velocimetry.jl/blob/c191192c2cd0145a2a67ac7514f4e61a64538abd/deps/matlabCOM.bat

Do you need the batch script because you need to launch a UAC prompt? I wonder if we can't do that directly using an elevated process.

stillyslalom commented 3 years ago

Yes, the batch script launches the prompt. If there's a more direct way to do that, I'm happy to take a look at it.

stillyslalom commented 3 years ago

I just checked - if you run the batch script from an already-elevated process, it doesn't raise the UAC prompt.

musm commented 3 years ago

Can't you directly run the processes in Julia through run (see https://docs.julialang.org/en/v1/manual/running-external-programs/#Running-External-Programs) ? (I'm uncertain we can prompt for elevated privileges)

stillyslalom commented 3 years ago

You can run the process, but it doesn't allow you to prompt for elevated privileges, which is why I'm using the batch script.

julia> run(`matlab -regserver`)
Process(`matlab -regserver`, ProcessExited(0))

image

musm commented 3 years ago

Unrelated, but we should probably find a way to enable that in Julia. Thanks for trying.

stillyslalom commented 3 years ago

I'll do a bit more work to figure out how to check if a COM server is already registered in pre-2020a versions, since it'd be painful for users in permissions-limited corporate environments to get a UAC popup every time they need to build MATLAB.jl.

stillyslalom commented 3 years ago

Actually - I'm not sure this is necessary for recent versions of Matlab? From Register Matlab as a COM server,

When you install a new version of MATLAB, MATLAB automatically registers this version as a COM server for all users

I'll try installing R2020b to see whether it gets auto-registered as promised.

stillyslalom commented 3 years ago

I can verify that R2020b gets auto-registered. It'd be nice to only raise the UAC prompt for pre-2020a versions, but I haven't found a clean way to query the version without launching Matlab (which can't be done silently for pre-2020a versions!). The best option seems to be matlab -help, which includes the version number, but it's throwing a fit on my machine when I try to run the command through Julia instead of the command line (it works fine with cmd):

julia> run(`matlab -h`)
matlab [-? ^| -h ^| -help]
       [-c licensefile]
       [-nosplash]
       [-singleCompThread]
       [-batch MATLAB_command | -r MATLAB_command]
[...]
    Version: 9.9.0,1444674

ERROR: failed process: Process(`matlab -h`, ProcessExited(4294967295)) [4294967295]

Stacktrace:
 [1] pipeline_error at .\process.jl:525 [inlined]
 [2] run(::Cmd; wait::Bool) at .\process.jl:440
 [3] run(::Cmd) at .\process.jl:438
 [4] top-level scope at REPL[61]:1

...so it prints the version to stdout, then fails, which means that I can't use read(`cmd`, String) to grab that version string.