PowerShell:为PowerShell生成的可执行文件设置版本及发布者属性
Hey there! It looks like you've got the core service stub generation working, but need to add those important version and publisher properties to your .EXE file. Here are two straightforward ways to do this, with the first being the most direct for your current setup:
Method 1: Add Assembly Metadata Directly to Your Embedded C# Code
The easiest way is to include assembly-level attributes at the top of your C# source code. These attributes will be compiled into the EXE and show up in the file properties (right-click > Details tab).
Here's how to modify your script's $source block, plus a fix for your $serviceName variable (right now it's grabbing the full script path, not just the service name):
[CmdletBinding(DefaultParameterSetName='Status')] Param( [Parameter(ParameterSetName='Start', Mandatory=$true)] [Switch]$Start, # 启动服务 [Parameter(ParameterSetName='Stop', Mandatory=$true)] [Switch]$Stop, # 停止服务 [Parameter(ParameterSetName='Setup', Mandatory=$true)] [Switch]$Setup # Add this to match your Inno Setup -setup flag ) $scriptVersion = "1.2.3.4" # Fix: Get just the script filename (without path/extension) for the service name $serviceName = (Get-Item $MyInvocation.MyCommand.Definition).BaseName $exeFullName = "MyService.exe" # Modified source with assembly metadata $source = @" using System; using System.ServiceProcess; using System.Reflection; // Assembly metadata attributes - customize these values! [assembly: AssemblyTitle("$serviceName Service")] [assembly: AssemblyVersion("$scriptVersion")] [assembly: AssemblyFileVersion("$scriptVersion")] [assembly: AssemblyCompany("Your Company Name")] [assembly: AssemblyProduct("Your Service Product Name")] [assembly: AssemblyCopyright("© 2024 Your Company. All rights reserved.")] public class Service_$serviceName : ServiceBase { public static void Main() { ServiceBase.Run(new Service_$serviceName()); } } "@ # Rest of your script remains the same... if ($Start) { Write-Verbose "Starting service $serviceName" Start-Service $serviceName return } if ($Stop) { Write-Verbose "Stopping service $serviceName" Stop-Service $serviceName return } if ($Setup) { # Add your setup logic here if needed (e.g., service installation) } try { Write-Verbose "Compiling $exeFullName" Add-Type -TypeDefinition $source -Language CSharp -OutputAssembly $exeFullName -OutputType ConsoleApplication -ReferencedAssemblies "System.ServiceProcess" -Debug:$false } catch { $msg = $_.Exception.Message Write-error "Failed to create the $exeFullName service stub. $msg" exit 1 }
Key Notes:
AssemblyVersionsets the "Product Version" in file propertiesAssemblyFileVersionsets the "File Version" (can matchAssemblyVersionor use a separate build number)- Customize
AssemblyCompany,AssemblyCopyright, and other attributes to match your project's details - I added a
$Setupparameter to align with your Inno Setup command line (you were using-setupbut it wasn't defined in your original script)
Method 2: Use a Resource File with csc.exe (Alternative)
If you prefer not to embed metadata in the C# code, you can create a .rc resource file and compile it with csc.exe directly (instead of using Add-Type):
- Create a file named
service.rcwith version info (use a template from Microsoft docs or a tool like Resource Hacker to generate it) - Compile the
.rcto a.resfile usingrc.exe(included with Visual Studio Build Tools) - Call
csc.exewith the/win32res:service.resparameter to embed the metadata into your EXE
This is more involved, so Method 1 is better for your current PowerShell-based workflow.
Testing the Result
After running the modified script, right-click your MyService.exe > Properties > Details tab. You should see all the metadata you added!
内容的提问来源于stack exchange,提问作者why it doesnt work

