Repository navigation
Expand file tree
/
Copy pathDirectory.Build.props
More file actions
214 lines (180 loc) · 11.7 KB
/
Copy pathDirectory.Build.props
File metadata and controls
214 lines (180 loc) · 11.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
<Project>
<!--
Settings shared by every project. Rationale lives in the planning documents:
- net10.0-windows10.0.17763.0 ADR-1 and ADR-5 in one line. The product is
Windows-only, so every project says so. Declaring
plain net10.0 would claim the code runs anywhere,
and the platform analyser would rightly complain the
moment the core opens the service control manager.
The version suffix is Server 2019 / Windows 10 1809,
which turns the supported floor from a sentence in a
document into something the compiler checks. It has
to sit in the framework name itself: a separate
SupportedOSPlatformVersion above the target platform
version is rejected by the SDK.
- x64 only ADR-17. A 32-bit process reads redirected paths and
registry keys, which is a silent wrong answer.
- nullable + warnings as errors 06-STRUKTURA-I-KONWENCJE, part 3: "not read yet",
"read", "absent" and "denied" are four different
states. The compiler cannot model all four, but it
can stop null from standing in for two of them.
RuntimeIdentifier is deliberately NOT set here. It belongs to publishing, and forcing
it on test projects only makes the test host harder to run.
Individual projects must not repeat these. A local copy would quietly win and there
would be two sources for one setting.
-->
<PropertyGroup>
<TargetFramework>net10.0-windows10.0.17763.0</TargetFramework>
<Platforms>x64</Platforms>
<PlatformTarget>x64</PlatformTarget>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<NeutralLanguage>en</NeutralLanguage>
</PropertyGroup>
<!--
No startup hooks, in any process this repository builds - security report S-2, 2026-10-06.
The runtime runs every assembly named in DOTNET_STARTUP_HOOKS before Main. This tool is meant
to run with administrator rights, and an elevated process inherits the environment of the
account that started it - measured that day: every value in the account's own environment
was present in an elevated process. So anything able to set a variable for that account could
have had code run inside the elevated tool before a line of ours. Nothing here uses a startup
hook, so switching the feature off costs nothing the product has.
THE SWITCH IS WHAT IS ASSERTED, NOT THIS LINE. StartupHookGuards asks the runtime of the test
host - which is built from this same file - whether the switch is on, rather than reading the
property back from here. Set here rather than in the two shipped projects because a setting
that has to be repeated is a setting that is one day repeated wrongly, and the test projects
carrying it too is what lets a running process be asked.
WHAT THIS DOES NOT CLOSE, said so nobody assumes otherwise: a CoreCLR profiler is loaded from
the environment as well, and Microsoft's own table for it has no runtimeconfig.json setting at
all. That is why Session.RuntimeSettingsFromEnvironment exists - the tool cannot switch those
off, so an elevated process names them instead.
-->
<PropertyGroup>
<StartupHookSupport>false</StartupHookSupport>
</PropertyGroup>
<!--
A documentation file, written and never shipped.
Written because the compiler reports an unnecessary using directive (IDE0005) during a build
only when it writes one. That is the whole reason, and the side effect turned out worth more:
with the file on, every XML comment is read, and a reference to a member that no longer exists
fails the build. Nine of those were found the day this went in, 2026-09-23.
Never shipped, and MEASURED rather than assumed that day: with the file on, dotnet publish put
bws.xml, BetterWindowsServices.xml and Bws.Core.xml beside the executables. With the two lines
below it put exactly what it put before. A release carries what somebody decided it carries.
A project switching the file off does not build - the SDK refuses with its own error,
EnableGenerateDocumentationFile, measured the same day. The two publish lines have nobody
watching them but AnalyzerRuleGuards, which refuses them anywhere but here.
-->
<PropertyGroup>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PublishDocumentationFile>false</PublishDocumentationFile>
<PublishReferencesDocumentationFiles>false</PublishReferencesDocumentationFiles>
</PropertyGroup>
<!--
A package with a published advisory stops the restore rather than warning inside it.
THESE THREE LINES CHANGE NOTHING TODAY, AND THAT IS THE POINT OF WRITING THEM. Measured on
2026-09-22 by asking MSBuild rather than by recalling the documentation: on this SDK the
effective values for Bws.Core, Bws.Gui and Bws.Core.Tests were already true, all and low.
They are the SDK's defaults, which means they are somebody else's decision, they moved once
already - the mode was direct-only before .NET 9 - and they will move again without a line
in any changelog of ours.
WHAT IT IS WORTH, measured the same day with a throwaway project rather than assumed,
because the mechanism is not obvious. NuGet reports an advisory as NU1901 to NU1904, which
are restore WARNINGS. TreatWarningsAsErrors above covers NU codes, so:
with it: error NU1903 ... restore exits 1
without it: warning NU1903 ... restore exits 0
So this repository has had a blocking supply chain gate on every push since the day warnings
became errors, and nobody had written it down. tools/supply-chain/audit-blocks.ps1 runs that
experiment again on demand, and SupplyChainGuards holds the three settings here.
Audit needs a source that publishes vulnerability data. nuget.org does. A build pointed at a
feed that does not gets NU1905, which TreatWarningsAsErrors also turns into an error - loud,
rather than an audit that quietly checked nothing. That is rule 8 of CLAUDE.md applied to the
build: silence is the one outcome that is not allowed.
`all` rather than `direct` matters more here than it looks. Seven of this project's packages
are direct and the resolved graph behind them is an order of magnitude larger, which is
where an advisory is actually likely to sit.
-->
<PropertyGroup>
<NuGetAudit>true</NuGetAudit>
<NuGetAuditMode>all</NuGetAuditMode>
<NuGetAuditLevel>low</NuGetAuditLevel>
<!--
RESTORING these projects on Linux is allowed. BUILDING them there still is not, and the
two are different questions - this property only answers the first.
Why it is needed at all, in a product that is Windows-only by ADR-1. GitHub's automatic
dependency submission runs on a LINUX runner, finds every .csproj in the tree and restores
it, and that is how the dependency graph learns the resolved package tree rather than the
seven names written in our project files. Without this line the SDK refuses at the first
project with NETSDK1100 - "To build a project targeting Windows on this operating system,
set the EnableWindowsTargeting property to true" - and the whole submission fails.
MEASURED RATHER THAN SUSPECTED, 2026-09-22, and it is the reason this line exists. The
feature was already switched on for this repository and had NEVER succeeded: one run in
its whole history, failing on Bws.Core and Bws.Site with exactly that error. So the
dependency graph held 13 entries - the direct packages GitHub parses out of the csproj
files - while the resolved tree behind them is an order of magnitude larger. Nothing
reported this. A submission that never ran looks identical to a project with no
transitive dependencies.
What it does NOT weaken. It permits the restore to download Windows reference packs on a
non-Windows host. It does not change the target framework, it does not make anything
build or run off Windows, and the platform analyser still holds every call in Bws.Core to
the supported floor. On Windows this property does nothing at all.
-->
<EnableWindowsTargeting>true</EnableWindowsTargeting>
</PropertyGroup>
<!--
Identity of the product. One place, so the name never drifts between the executable,
the package metadata and the About window (ADR-12a).
-->
<!--
Version. Set by the owner on 2026-08-01 and nowhere else: rule 11 of CLAUDE.md makes
raising it a declaration to users rather than housekeeping, so it is not something a
session changes on its own.
It exists at all because the absence was not neutral. With no Version anywhere the SDK
stamps 1.0.0.0, so every binary already claimed to be a first release while both
changelogs held everything under [Unreleased]. A number below one says what is true.
0.2.0 on 2026-09-24, the owner's decision, for the first release. 0.1.0 was never released:
it named the binaries while everything stood under [Unreleased].
0.3.0 on 2026-09-25, the owner's decision.
0.4.0 on 2026-10-07, the owner's decision.
-->
<PropertyGroup>
<Version>0.4.0</Version>
</PropertyGroup>
<PropertyGroup>
<Product>Better Windows Services</Product>
<Company>Better Windows Services</Company>
<!--
The holder is the owner's name, as in README.md and in the licence sections of the owner's
other public projects - decided 2026-09-22, when this line said "Better Windows Services
contributors" and README said the name, and one of the two had to follow the other. The
same line is repeated in cli.en.json under cli.version, because the version text is a
translation key and cannot read this file.
-->
<Copyright>Copyright (C) 2026 DonislawDev</Copyright>
<PackageLicenseExpression>GPL-3.0-or-later</PackageLicenseExpression>
<Description>Service management for Windows administrators: search, bulk operations, audit and drift.</Description>
</PropertyGroup>
<!--
Meziantou.Analyzer, MIT, build time only - PrivateAssets stops it reaching anything that
ships. Taken on 2026-08-02 for three rules out of more than two hundred, TWO since
2026-09-23, and the rest are switched off by name in .editorconfig with what they cost
measured beside them.
The justification ADR-15 asks for, in one line: MA0009 guards the one surface where this
product takes hostile input, which is a regular expression somebody typed into a search box,
and MA0011 is culture-safe parsing where a compiler can check it.
This comment used to say MA0051 was the reason, and that the reference REPLACED a dependency
on Roslyn. Both stopped being true on 2026-09-23: method length counted every comment line in
a project that keeps its reasons beside its code, so it is off, and the shape of the code is
measured by a parser in tests/Bws.Architecture.Tests instead - which does take a test-only
dependency on Roslyn, recorded in ADR-15. Nothing that ships carries it.
-->
<ItemGroup>
<PackageReference Include="Meziantou.Analyzer" Version="3.0.290">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>