88using System . Security . Cryptography ;
99using System . Reflection ;
1010using CSharpFunctionalExtensions ;
11+ using DotnetPackaging ;
1112using DotnetPackaging . Publish ;
1213using Serilog ;
1314using RuntimeArchitecture = System . Runtime . InteropServices . Architecture ;
@@ -55,7 +56,8 @@ public Task<Result<FileInfo>> BuildFromDirectory(
5556 ToMaybe ( vendor ) ,
5657 ToMaybe ( runtimeIdentifier ) ,
5758 ToMaybe ( stubFile ) ,
58- Maybe < string > . None ) ;
59+ Maybe < string > . None ,
60+ Maybe < ProjectMetadata > . None ) ;
5961
6062 return Build ( request ) ;
6163 }
@@ -87,22 +89,46 @@ public async Task<Result<FileInfo>> BuildFromProject(
8789 return Result . Failure < FileInfo > ( publishResult . Error ) ;
8890 }
8991
92+ var projectMetadata = ReadProjectMetadata ( projectFile ) ;
93+
9094 var request = new ExePackagingRequest (
9195 new DirectoryInfo ( publishResult . Value . OutputDirectory ) ,
9296 outputFile ,
9397 options ,
9498 ToMaybe ( vendor ) ,
9599 ToMaybe ( runtimeIdentifier ) ,
96100 ToMaybe ( stubFile ) ,
97- publishResult . Value . Name ) ;
101+ publishResult . Value . Name ,
102+ projectMetadata ) ;
98103
99104 return await Build ( request ) ;
100105 }
101106
107+ private Maybe < ProjectMetadata > ReadProjectMetadata ( FileInfo projectFile )
108+ {
109+ var metadataResult = ProjectMetadataReader . Read ( projectFile ) ;
110+ if ( metadataResult . IsFailure )
111+ {
112+ logger . Warning (
113+ "Unable to read project metadata from {ProjectFile}: {Error}" ,
114+ projectFile . FullName ,
115+ metadataResult . Error ) ;
116+ return Maybe < ProjectMetadata > . None ;
117+ }
118+
119+ return Maybe < ProjectMetadata > . From ( metadataResult . Value ) ;
120+ }
121+
102122 private async Task < Result < FileInfo > > Build ( ExePackagingRequest request )
103123 {
104124 var inferredExecutable = InferExecutableName ( request . PublishDirectory , request . ProjectName ) ;
105- var metadata = BuildInstallerMetadata ( request . Options , request . PublishDirectory , request . Vendor , inferredExecutable , request . ProjectName ) ;
125+ var metadata = BuildInstallerMetadata (
126+ request . Options ,
127+ request . PublishDirectory ,
128+ request . Vendor ,
129+ inferredExecutable ,
130+ request . ProjectName ,
131+ request . ProjectMetadata ) ;
106132
107133 if ( request . Stub . HasValue )
108134 {
@@ -186,10 +212,17 @@ private static InstallerMetadata BuildInstallerMetadata(
186212 DirectoryInfo contextDir ,
187213 Maybe < string > vendor ,
188214 Maybe < string > inferredExecutable ,
189- Maybe < string > projectName )
215+ Maybe < string > projectName ,
216+ Maybe < ProjectMetadata > projectMetadata )
190217 {
191- // Prefer explicit --application-name, then project name (when packaging from-project), then publish directory name
218+ var metadataProduct = projectMetadata
219+ . Bind ( meta => meta . Product
220+ . Or ( ( ) => meta . AssemblyName )
221+ . Or ( ( ) => meta . AssemblyTitle ) ) ;
222+
223+ // Prefer explicit --application-name, then project metadata, then project name (from publish), then publish directory name
192224 var appName = options . Name
225+ . Or ( ( ) => metadataProduct )
193226 . Or ( ( ) => projectName )
194227 . GetValueOrDefault ( contextDir . Name ) ;
195228 var packageName = appName . ToLowerInvariant ( ) . Replace ( " " , string . Empty ) . Replace ( "-" , string . Empty ) ;
@@ -199,7 +232,15 @@ private static InstallerMetadata BuildInstallerMetadata(
199232 . Or ( ( ) => inferredExecutable )
200233 . Map ( NormalizeExecutableRelativePath )
201234 . Match ( value => value , ( ) => ( string ? ) null ) ;
202- var effectiveVendor = vendor . Match ( value => value , ( ) => "Unknown" ) ;
235+ var vendorFromProject = projectMetadata
236+ . Bind ( meta => meta . Company
237+ . Or ( ( ) => meta . Product )
238+ . Or ( ( ) => meta . AssemblyName )
239+ . Or ( ( ) => meta . AssemblyTitle ) ) ;
240+
241+ var effectiveVendor = vendor
242+ . Or ( ( ) => vendorFromProject )
243+ . GetValueOrDefault ( "Unknown" ) ;
203244 var description = options . Comment . Match ( value => value , ( ) => ( string ? ) null ) ;
204245
205246 return new InstallerMetadata ( appId , appName , version , effectiveVendor , description , executable ) ;
@@ -747,5 +788,6 @@ private sealed record ExePackagingRequest(
747788 Maybe < string > Vendor ,
748789 Maybe < string > RuntimeIdentifier ,
749790 Maybe < FileInfo > Stub ,
750- Maybe < string > ProjectName ) ;
791+ Maybe < string > ProjectName ,
792+ Maybe < ProjectMetadata > ProjectMetadata ) ;
751793}
0 commit comments