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

build: dotnet 6.0.408 #166

Closed
wants to merge 11 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions .github/workflows/code-style.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,16 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
global-json-file: global.json
global-json-file: "./global.json"

- name: Restore dependencies
run: dotnet restore

- name: Check dotnet version
run: dotnet --version
continue-on-error: false

- name: Check code format (editorconfig)
run: dotnet run --project .\test\test.csproj

- name: Check code format (editorconfig)
run: dotnet format --verify-no-changes
continue-on-error: false
36 changes: 18 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,20 @@
[![Nuget:Lib](https://img.shields.io/nuget/v/dSPACE.Runtime.InteropServices?label=dSPACE.Runtime.InteropServices&style=flat)](https://www.nuget.org/packages/dSPACE.Runtime.InteropServices/)
[![Nuget:LibBuildTask](https://img.shields.io/nuget/v/dSPACE.Runtime.InteropServices?label=dSPACE.Runtime.InteropServices.BuildTasks&style=flat)](https://www.nuget.org/packages/dSPACE.Runtime.InteropServices.BuildTasks/)

[![Release](https://img.shields.io/github/v/release/dspace-group/dscom?label=release)](https://github.com/dspace-group/dscom/releases)
![License](https://img.shields.io/github/license/dspace-group/dscom)
[![dSPACE](https://img.shields.io/badge/-OpenSource%20powered%20by%20dSPACE-blue)](https://www.dspace.com/)

[![Unit Tests](https://github.com/dspace-group/dscom/actions/workflows/unit-test.yaml/badge.svg)](https://github.com/dspace-group/dscom/actions/workflows/unit-test.yaml)
[![Example Tests](https://github.com/dspace-group/dscom/actions/workflows/example-test.yaml/badge.svg)](https://github.com/dspace-group/dscom/actions/workflows/example-test.yaml)
[![Code Style Check](https://github.com/dspace-group/dscom/actions/workflows/code-style.yaml/badge.svg)](https://github.com/dspace-group/dscom/actions/workflows/code-style.yaml)

The command line client `dscom` is a replacement for `tlbexp.exe` and creates and registers TLBs from .NET assemblies.
The `dSPACE.Runtime.InteropServices` library contains various classes and methods for COM.
It can be used in `net5+` or in `net48` projects. With the library you can register assemblies and classes for COM and programmatically generate TLBs at runtime.
With the library `dSPACE.Runtime.InteropServices` you can, among other things, register assemblies and classes for COM and programmatically generate TLBs at runtime.
The `dSPACE.Runtime.InteropServices.BuildTasks` library provides build tasks which can be used to automatically generate TLBs at compile time.

> This is an unstable prerelease. Anything may change at any time!
Example:

```pwsh
PS C:\> dotnet tool install --global dscom
PS C:\> dscom tlbexport myassembly.dll
```

- [dSPACE COM tools](#dspace-com-tools)
- [Introducing](#introducing)
Expand Down Expand Up @@ -271,17 +271,17 @@ This way the build stops, if the type library is not exported.

The build task can be parameterized with the following [properties](https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-properties?view=vs-2022):

| **Name** | **Description** |
| ---------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| _DsComTlbExt | Extension of the resulting type library. <br /> Default Value: `.tlb` |
| _DsComForceToolUsage | Use DsCom Exe files to create the TLB <br/> Default value: `false` | false |
| DsComTypeLibraryUniqueId | Overwrite the library UUID <br/> Default Value: Empty Guid |
| DsComOverideLibraryName | Overwrite the IDL name of the library. <br/> Default Value: Empty string |
| DsComRegisterTypeLibrariesAfterBuild | Use regasm call after the build to register type library after the build <br/> Default value: `false` |
| DsComTlbExportAutoAddReferences | Add referenced assemblies automatically to type libraries <br/> Default value: `true` |
| DsComTlbExportIncludeReferencesWithoutHintPath | If a `Reference` assembly does not provide a `HintPath` Metadata, the item spec shall be task. <br/> Default value: `false` |
| _DsComExportTypeLibraryTargetFile | Path to the resulting file. <br/> Default value: `$(TargetDir)\$(TargetName)$(_DsComTlbExt)` * |
| _DsComExportTypeLibraryAssemblyFile | Path to the source assembly file. <br/> Default value: `$(TargetPath)` * |
| **Name** | **Description** |
| ---------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| _DsComTlbExt | Extension of the resulting type library. <br /> Default Value: `.tlb` |
| _DsComForceToolUsage | Use DsCom Exe files to create the TLB <br/> Default value: `false` | false |
| DsComTypeLibraryUniqueId | Overwrite the library UUID <br/> Default Value: Empty Guid |
| DsComOverideLibraryName | Overwrite the IDL name of the library. <br/> Default Value: Empty string |
| DsComRegisterTypeLibrariesAfterBuild | Use regasm call after the build to register type library after the build <br/> Default value: `false` |
| DsComTlbExportAutoAddReferences | Add referenced assemblies automatically to type libraries <br/> Default value: `true` |
| DsComTlbExportIncludeReferencesWithoutHintPath | If a `Reference` assembly does not provide a `HintPath` Metadata, the item spec shall be task. <br/> Default value: `false` |
| _DsComExportTypeLibraryTargetFile | Path to the resulting file. <br/> Default value: `$(TargetDir)\$(TargetName)$(_DsComTlbExt)` * |
| _DsComExportTypeLibraryAssemblyFile | Path to the source assembly file. <br/> Default value: `$(TargetPath)` * |

*) This value cannot be overridden.

Expand Down
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"sdk": {
"version": "6.0.406",
"version": "6.0.408",
"rollForward": "latestPatch"
}
}
194 changes: 194 additions & 0 deletions test/ProcessRunner.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Threading.Tasks;

namespace Microsoft.CodeAnalysis.Tools.Utilities
{
public readonly struct ProcessResult
{
public Process Process { get; }
public int ExitCode { get; }
public ReadOnlyCollection<string> OutputLines { get; }
public ReadOnlyCollection<string> ErrorLines { get; }

public ProcessResult(Process process, int exitCode, ReadOnlyCollection<string> outputLines, ReadOnlyCollection<string> errorLines)
{
Process = process;
ExitCode = exitCode;
OutputLines = outputLines;
ErrorLines = errorLines;
}
}

public readonly struct ProcessInfo
{
public Process Process { get; }
public ProcessStartInfo StartInfo { get; }
public Task<ProcessResult> Result { get; }

public int Id => Process.Id;

public ProcessInfo(Process process, ProcessStartInfo startInfo, Task<ProcessResult> result)
{
Process = process;
StartInfo = startInfo;
Result = result;
}
}

public static class ProcessRunner
{
public static void OpenFile(string file)
{
if (File.Exists(file))
{
Process.Start(file);
}
}

public static ProcessInfo CreateProcess(
string executable,
string arguments,
bool lowPriority = false,
string? workingDirectory = null,
bool captureOutput = false,
bool displayWindow = true,
Dictionary<string, string>? environmentVariables = null,
Action<Process>? onProcessStartHandler = null,
CancellationToken cancellationToken = default) =>
CreateProcess(
CreateProcessStartInfo(executable, arguments, workingDirectory, captureOutput, displayWindow, environmentVariables),
lowPriority: lowPriority,
onProcessStartHandler: onProcessStartHandler,
cancellationToken: cancellationToken);

public static ProcessInfo CreateProcess(
ProcessStartInfo processStartInfo,
bool lowPriority = false,
Action<Process>? onProcessStartHandler = null,
CancellationToken cancellationToken = default)
{
var errorLines = new List<string>();
var outputLines = new List<string>();
var process = new Process();
var tcs = new TaskCompletionSource<ProcessResult>();

process.EnableRaisingEvents = true;
process.StartInfo = processStartInfo;

process.OutputDataReceived += (s, e) =>
{
if (e.Data != null)
{
outputLines.Add(e.Data);
}
};

process.ErrorDataReceived += (s, e) =>
{
if (e.Data != null)
{
errorLines.Add(e.Data);
}
};

process.Exited += (s, e) =>
{
// We must call WaitForExit to make sure we've received all OutputDataReceived/ErrorDataReceived calls
// or else we'll be returning a list we're still modifying. For paranoia, we'll start a task here rather
// than enter right back into the Process type and start a wait which isn't guaranteed to be safe.
Task.Run(() =>
{
process.WaitForExit();
var result = new ProcessResult(
process,
process.ExitCode,
new ReadOnlyCollection<string>(outputLines),
new ReadOnlyCollection<string>(errorLines));
tcs.TrySetResult(result);
});
};

_ = cancellationToken.Register(() =>
{
if (tcs.TrySetCanceled())
{
// If the underlying process is still running, we should kill it
if (!process.HasExited)
{
try
{
process.Kill();
}
catch (InvalidOperationException)
{
// Ignore, since the process is already dead
}
}
}
});

process.Start();
onProcessStartHandler?.Invoke(process);

if (lowPriority)
{
process.PriorityClass = ProcessPriorityClass.BelowNormal;
}

if (processStartInfo.RedirectStandardOutput)
{
process.BeginOutputReadLine();
}

if (processStartInfo.RedirectStandardError)
{
process.BeginErrorReadLine();
}

return new ProcessInfo(process, processStartInfo, tcs.Task);
}

public static ProcessStartInfo CreateProcessStartInfo(
string executable,
string arguments,
string? workingDirectory = null,
bool captureOutput = false,
bool displayWindow = true,
Dictionary<string, string>? environmentVariables = null)
{
var processStartInfo = new ProcessStartInfo(executable, arguments);

if (!string.IsNullOrEmpty(workingDirectory))
{
processStartInfo.WorkingDirectory = workingDirectory;
}

if (environmentVariables != null)
{
foreach (var pair in environmentVariables)
{
processStartInfo.EnvironmentVariables[pair.Key] = pair.Value;
}
}

if (captureOutput)
{
processStartInfo.UseShellExecute = false;
processStartInfo.RedirectStandardOutput = true;
processStartInfo.RedirectStandardError = true;
}
else
{
processStartInfo.CreateNoWindow = !displayWindow;
processStartInfo.UseShellExecute = displayWindow;
}

return processStartInfo;
}
}
}
22 changes: 22 additions & 0 deletions test/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Microsoft.CodeAnalysis.Tools.Utilities;

internal class Program
{
private static int Main(string[] args)
{
TryGetDotNetCliVersion(out string a);
Console.WriteLine(a);

return 0;
}


internal static bool TryGetDotNetCliVersion(out string dotnetVersion)
{
var processInfo = ProcessRunner.CreateProcess("dotnet", "--version", captureOutput: true, displayWindow: false);
var versionResult = processInfo.Result.GetAwaiter().GetResult();

dotnetVersion = versionResult.OutputLines[0].Trim();
return true;
}
}
10 changes: 10 additions & 0 deletions test/test.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>