Context
Support receives usage reports that appear invalid — in particular, reports attributed to long-obsolete
PostSharp versions. One plausible explanation is that a build agent was not recognized as an unattended
build, so the build consumed and audited a user license instead of falling back to the free unattended-build
license.
This issue covers two related questions:
- Does the current code correctly skip license verification and auditing under TFS / Azure DevOps Server
/ Azure Pipelines, in all the ways an agent can be run?
- Was there an early PostSharp version that did not detect TFS accurately, which would explain the
invalid usage reports attributed to obsolete versions?
How the detection works today
ProcessUtilities.DetectUnattendedProcess (Core/PostSharp.Platform/Utilities/ProcessUtility.cs) returns
true when any of the following holds, in order:
- The OS is not Windows.
Environment.UserInteractive is false.
- The process runs in a container (
IContainerDetectionService).
Process.GetCurrentProcess().SessionId == 0.
- A process in the parent process chain has one of these image names:
services, java, bamboo, agent.worker, runner.worker, buildkite-agent, circleci-agent,
agent, sshd: travis [priv].
When the result is true, SharedUserLicenseManager.AddUnattendedLicense adds an internal
CoreUnattendedLicense, whose IsAudited() returns false, and which is loaded before any user-configured
key. So a correctly detected agent neither consumes nor audits a user license.
The result is written to the build log as PS0256 — Process unattended: {0} ({1}). — at ImportantInfo
severity, and the second placeholder contains the full parent process chain. This is the artifact to request
from any customer reporting the problem.
Historical finding: TFS detection was incomplete before PostSharp 4.3
agent.worker — the image name of the TFS 2015+ / Azure Pipelines agent worker — was added on 2016-08-26 by
commit e8bee773c3, for issue #13585, "Build on TFS is not recognized as unattended when running build
agent on command-line", released in 4.3. Before that commit the list was only { "services", "java" }.
The consequence: on any PostSharp older than 4.3, a TFS build agent started interactively from the
command line rather than installed as a Windows service was not recognized as unattended — neither
services (no service parent), nor SessionId == 0, nor Environment.UserInteractive == false would fire.
Those builds consumed and audited a user license. That matches the reported symptom exactly: spurious usage
reports from long-obsolete versions.
The process list was extended again on 2022-11-18 (a9958ef9ff, #31100, 6.11) for Bamboo, BuildKite,
CircleCI, Semaphore and Travis, but nothing TFS-specific was added at that time.
What to check
Current behavior
- On a self-hosted Azure Pipelines / Azure DevOps Server agent, verify PS0256 reports
true and that no user
license is consumed or audited, in both agent run modes: installed as a Windows service, and run
interactively via run.cmd.
- Verify the same for a Microsoft-hosted agent.
- Check the pipe server path.
BuildClient computes isProcessUnattended in the MSBuild process and uses it
only to decide whether to use the pipe server (AllowPipeServerWhenUnattended). The licensing decision is
taken in the compiler process. When a long-lived pipe server process is reused, its parent chain may no
longer contain agent.worker, in which case DetectUnattendedProcess would return false inside the
server. Determine whether this path is reachable and whether the client's value is propagated (currently
OverrideUnattendedBuild is only read from project properties, and appears to be used by tests only).
Known gaps in the process list
Agent.Listener.exe is not listed; only Agent.Worker.exe is. Confirm the worker is always in the chain.
- The older VSO / TFS 2015-preview agent (
VSOAgent.exe, VSOWorker.exe) is not listed and never was.
- TFS 2010/2012/2013 XAML builds run under
TFSBuildServiceHost.exe, which is covered only when installed as
a Windows service (parent services); the command-line case has the same gap as #13585.
Deliverable for support
Determine the exact version boundary and produce a statement support can use: which PostSharp versions can
produce spurious usage reports under TFS, and under which agent configuration. If the answer is "everything
before 4.3 when the agent runs interactively", usage reports from those versions should be treated as
unreliable rather than as evidence of unlicensed use.
-- Claude for Gael
Context
Support receives usage reports that appear invalid — in particular, reports attributed to long-obsolete
PostSharp versions. One plausible explanation is that a build agent was not recognized as an unattended
build, so the build consumed and audited a user license instead of falling back to the free unattended-build
license.
This issue covers two related questions:
/ Azure Pipelines, in all the ways an agent can be run?
invalid usage reports attributed to obsolete versions?
How the detection works today
ProcessUtilities.DetectUnattendedProcess(Core/PostSharp.Platform/Utilities/ProcessUtility.cs) returnstruewhen any of the following holds, in order:Environment.UserInteractiveisfalse.IContainerDetectionService).Process.GetCurrentProcess().SessionId == 0.services,java,bamboo,agent.worker,runner.worker,buildkite-agent,circleci-agent,agent,sshd: travis [priv].When the result is
true,SharedUserLicenseManager.AddUnattendedLicenseadds an internalCoreUnattendedLicense, whoseIsAudited()returnsfalse, and which is loaded before any user-configuredkey. So a correctly detected agent neither consumes nor audits a user license.
The result is written to the build log as PS0256 —
Process unattended: {0} ({1}).— atImportantInfoseverity, and the second placeholder contains the full parent process chain. This is the artifact to request
from any customer reporting the problem.
Historical finding: TFS detection was incomplete before PostSharp 4.3
agent.worker— the image name of the TFS 2015+ / Azure Pipelines agent worker — was added on 2016-08-26 bycommit
e8bee773c3, for issue #13585, "Build on TFS is not recognized as unattended when running buildagent on command-line", released in 4.3. Before that commit the list was only
{ "services", "java" }.The consequence: on any PostSharp older than 4.3, a TFS build agent started interactively from the
command line rather than installed as a Windows service was not recognized as unattended — neither
services(no service parent), norSessionId == 0, norEnvironment.UserInteractive == falsewould fire.Those builds consumed and audited a user license. That matches the reported symptom exactly: spurious usage
reports from long-obsolete versions.
The process list was extended again on 2022-11-18 (
a9958ef9ff, #31100, 6.11) for Bamboo, BuildKite,CircleCI, Semaphore and Travis, but nothing TFS-specific was added at that time.
What to check
Current behavior
trueand that no userlicense is consumed or audited, in both agent run modes: installed as a Windows service, and run
interactively via
run.cmd.BuildClientcomputesisProcessUnattendedin the MSBuild process and uses itonly to decide whether to use the pipe server (
AllowPipeServerWhenUnattended). The licensing decision istaken in the compiler process. When a long-lived pipe server process is reused, its parent chain may no
longer contain
agent.worker, in which caseDetectUnattendedProcesswould returnfalseinside theserver. Determine whether this path is reachable and whether the client's value is propagated (currently
OverrideUnattendedBuildis only read from project properties, and appears to be used by tests only).Known gaps in the process list
Agent.Listener.exeis not listed; onlyAgent.Worker.exeis. Confirm the worker is always in the chain.VSOAgent.exe,VSOWorker.exe) is not listed and never was.TFSBuildServiceHost.exe, which is covered only when installed asa Windows service (parent
services); the command-line case has the same gap as #13585.Deliverable for support
Determine the exact version boundary and produce a statement support can use: which PostSharp versions can
produce spurious usage reports under TFS, and under which agent configuration. If the answer is "everything
before 4.3 when the agent runs interactively", usage reports from those versions should be treated as
unreliable rather than as evidence of unlicensed use.
-- Claude for Gael