Skip to content

Commit

Permalink
Python: allow newer .net versions STUD-71044 (#451)
Browse files Browse the repository at this point in the history
* Python: allow newer .net versions STUD-71044

* Python: Fix robot hang when net runtime not installed (24.12) [STUD-71044]

Use Connect with timeout when connecting pipes
Throw exception when the host process has exit

---------

Co-authored-by: viogroza <[email protected]>
  • Loading branch information
alexandru-petre and viogroza authored Nov 22, 2024
1 parent e8c5d76 commit b34f72e
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<Import Project="..\Python.build.props" />
<PropertyGroup>
<TargetFrameworks>net461;net6.0-windows;net6.0</TargetFrameworks>
<RollForward>Major</RollForward>
<OutputPath>..\..\Output\Activities\Python\</OutputPath>
<OutputType>Exe</OutputType>
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
Expand All @@ -20,7 +21,7 @@
<Import Project="..\..\Shared\UiPath.Shared.Service\UiPath.Shared.Service.projitems" Label="Shared" />
<Import Project="..\UiPath.Python.Host.Shared\UiPath.Python.Host.Shared.projitems" Label="Shared" />
<Import Project="..\..\Shared\UiPath.Shared\UiPath.Shared.projitems" Label="Shared" />

<ItemGroup Condition=" '$(TargetFramework)' == 'net461' ">
<Reference Include="System.ServiceModel" />
<Reference Include="System.Xaml" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<Import Project="..\Python.build.props" />
<PropertyGroup>
<TargetFrameworks>net461;net6.0-windows;net6.0</TargetFrameworks>
<RollForward>Major</RollForward>
<OutputPath>..\..\Output\Activities\Python\</OutputPath>
<OutputType>Exe</OutputType>
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
Expand All @@ -17,7 +18,7 @@
<Import Project="..\..\Shared\UiPath.Shared.Service\UiPath.Shared.Service.projitems" Label="Shared" />
<Import Project="..\UiPath.Python.Host.Shared\UiPath.Python.Host.Shared.projitems" Label="Shared" />
<Import Project="..\..\Shared\UiPath.Shared\UiPath.Shared.projitems" Label="Shared" />

<ItemGroup Condition=" '$(TargetFramework)' == 'net461' ">
<Reference Include="System.ServiceModel" />
<Reference Include="System.Xaml" />
Expand Down
59 changes: 52 additions & 7 deletions Activities/Shared/UiPath.Shared.Service/Client/Controller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ internal class Controller<T>
/// </summary>
private readonly TimeSpan RetryInterval = TimeSpan.FromMilliseconds(50);

//Timeout in milliseconds for pipe connection (attempt)
private readonly int PipeConnectionTimeoutMs = 1000;

internal int ProcessId { get; private set; }

internal string Arguments { get; set; } = null;
Expand Down Expand Up @@ -59,7 +62,7 @@ private NamedPipeClientStream StartHostService()
else
{
folder = Path.GetDirectoryName(Assembly.GetAssembly(typeof(T)).Location).Replace("/lib/", "/bin/");
Arguments = string.Concat(Path.Combine(folder, ExeFile.Replace(".exe",".dll")), " ", Arguments);
Arguments = string.Concat(Path.Combine(folder, ExeFile.Replace(".exe", ".dll")), " ", Arguments);
exeFullPath = "dotnet";
}

Expand All @@ -73,28 +76,70 @@ private NamedPipeClientStream StartHostService()
// start the host process
ProcessStartInfo psi = new ProcessStartInfo()
{
UseShellExecute = true,
UseShellExecute = false,
FileName = exeFullPath,
WorkingDirectory = folder,
Arguments = Arguments,
WindowStyle = Visible ? ProcessWindowStyle.Normal : ProcessWindowStyle.Hidden
WindowStyle = Visible ? ProcessWindowStyle.Normal : ProcessWindowStyle.Hidden,
RedirectStandardError = true,
RedirectStandardOutput = true
};
Process process = Process.Start(psi);

// wait for service to become available
bool ServiceReady()
{
pipeClient =
new NamedPipeClientStream(".", process.Id.ToString(), PipeDirection.InOut,
PipeOptions.Asynchronous);
if (HostProcessHasExited())
{
using (var readerOutput = process.StandardOutput)
using (var readerError = process.StandardError)
{
string output = readerOutput.ReadToEnd();
string error = readerError.ReadToEnd();
throw new Exception($"Host process has exit!\n output: {output} \n error: {error} \n");
}
}

if (pipeClient == null)
{
pipeClient = new NamedPipeClientStream(".", process.Id.ToString(), PipeDirection.InOut, PipeOptions.Asynchronous);
}

pipeClient.Connect();
TryConnectPipeClient();
if (pipeClient.IsConnected)
{
return true;
}
return false;
}

void TryConnectPipeClient()
{
try
{
pipeClient.Connect(PipeConnectionTimeoutMs);
}
catch
{
//In case of exception we are going to retry to connect next time
//On timeout, if failure persists exception will be thrown
}
}

bool HostProcessHasExited()
{
try
{
return process.HasExited;
}
catch
{
//For wathever reason if HasExited throws, we assume that the process has not exited
//Error will be thrown when timeout expires
return false;
}
}

Retry(ServiceReady, StartTimeout, RetryInterval);
return pipeClient;
}
Expand Down

0 comments on commit b34f72e

Please sign in to comment.