@ -0,0 +1,27 @@ |
|||
[Equipment] |
|||
Timeout=5000 |
|||
SettleMilliseconds=300 |
|||
|
|||
[DMM] |
|||
Model=Keysight 34465A |
|||
Measurement=Voltage |
|||
Connection=LAN |
|||
Resource= |
|||
IdnMatch=34465A |
|||
Host=192.168.10.13 |
|||
Port=5025 |
|||
PortName= |
|||
BaudRate=115200 |
|||
Terminator=LF |
|||
SetupCommand= |
|||
CleanupCommand= |
|||
ReadCommand=MEAS:VOLT:DC? |
|||
|
|||
[OriginalHardwareIniKeys] |
|||
Connection=VoltageConnection |
|||
Resource=VoltageResource |
|||
IdnMatch=VoltageIdnMatch |
|||
Host=VoltageHost |
|||
Port=VoltagePort |
|||
SetupCommand=VoltageSetupCommand |
|||
ReadCommand=VoltageReadCommand |
|||
@ -0,0 +1,155 @@ |
|||
# DMM Related Code |
|||
|
|||
This file is a reference-only extraction. It is not compiled by the Housing app. |
|||
|
|||
## Source Files |
|||
|
|||
- `Services/EquipmentMeasurementSettings.cs` |
|||
- `Services/EquipmentMeasurementService.cs` |
|||
- `Services/IScpiClient.cs` |
|||
- `Services/TcpScpiClient.cs` |
|||
- `Services/SerialScpiClient.cs` |
|||
- `Services/VisaScpiClient.cs` |
|||
|
|||
## Hardware.ini Keys |
|||
|
|||
```ini |
|||
[Equipment] |
|||
Timeout=5000 |
|||
SettleMilliseconds=300 |
|||
|
|||
; 34465A DMM |
|||
VoltageConnection=LAN |
|||
VoltageResource= |
|||
VoltageIdnMatch=34465A |
|||
VoltageHost=192.168.10.13 |
|||
VoltagePort=5025 |
|||
VoltageSetupCommand= |
|||
VoltageReadCommand=MEAS:VOLT:DC? |
|||
``` |
|||
|
|||
## Settings Load Code |
|||
|
|||
```csharp |
|||
Voltage = LoadChannel( |
|||
values, |
|||
"Voltage", |
|||
"MEAS:VOLT:DC?", |
|||
"34460,34461,34465,34470,3446,3447"); |
|||
``` |
|||
|
|||
```csharp |
|||
private static ScpiChannelSettings LoadChannel( |
|||
Dictionary<string, string> values, |
|||
string prefix, |
|||
string defaultReadCommand, |
|||
string defaultIdnMatch) |
|||
{ |
|||
return new ScpiChannelSettings |
|||
{ |
|||
Connection = GetString(values, prefix + "Connection", string.Empty), |
|||
ResourceName = GetString(values, prefix + "Resource", string.Empty), |
|||
IdnMatch = GetString(values, prefix + "IdnMatch", defaultIdnMatch), |
|||
Host = GetString(values, prefix + "Host", string.Empty), |
|||
Port = GetInt(values, prefix + "Port", 5025), |
|||
PortName = GetString(values, prefix + "PortName", string.Empty), |
|||
BaudRate = GetInt(values, prefix + "BaudRate", 115200), |
|||
Terminator = GetString(values, prefix + "Terminator", string.Empty), |
|||
SetupCommand = GetString(values, prefix + "SetupCommand", string.Empty), |
|||
CleanupCommand = GetString(values, prefix + "CleanupCommand", string.Empty), |
|||
ReadCommand = GetString(values, prefix + "ReadCommand", defaultReadCommand) |
|||
}; |
|||
} |
|||
``` |
|||
|
|||
## Voltage Read Flow |
|||
|
|||
```csharp |
|||
var voltage = await ReadChannelAsync("VOLTAGE", _settings.Voltage, log); |
|||
``` |
|||
|
|||
```csharp |
|||
private async Task<decimal> ReadChannelAsync( |
|||
string label, |
|||
ScpiChannelSettings channel, |
|||
StringBuilder log, |
|||
bool skipSetupCommand = false) |
|||
{ |
|||
if (IsDisabled(channel)) |
|||
{ |
|||
log.AppendLine($"> {label} SKIP: disabled in Hardware.ini"); |
|||
return 0m; |
|||
} |
|||
|
|||
if (string.IsNullOrWhiteSpace(channel.ReadCommand)) |
|||
{ |
|||
throw new InvalidOperationException($"Hardware.ini [Equipment] {label} ReadCommand 값을 확인하세요."); |
|||
} |
|||
|
|||
using var client = await CreateClientAsync(label, channel); |
|||
return await ReadChannelWithClientAsync(label, channel, client, log, skipSetupCommand); |
|||
} |
|||
``` |
|||
|
|||
```csharp |
|||
private static async Task<decimal> ReadChannelWithClientAsync( |
|||
string label, |
|||
ScpiChannelSettings channel, |
|||
IScpiClient client, |
|||
StringBuilder log, |
|||
bool skipSetupCommand = false) |
|||
{ |
|||
if (string.IsNullOrWhiteSpace(channel.ReadCommand)) |
|||
{ |
|||
throw new InvalidOperationException($"Hardware.ini [Equipment] {label} ReadCommand 값을 확인하세요."); |
|||
} |
|||
|
|||
log.AppendLine($"> {label} CONNECT: {DescribeClient(client, channel)}"); |
|||
if (!skipSetupCommand && !string.IsNullOrWhiteSpace(channel.SetupCommand)) |
|||
{ |
|||
log.AppendLine($"> {label} SETUP: {channel.SetupCommand}"); |
|||
await SendCommandListAsync(client, channel.SetupCommand); |
|||
} |
|||
|
|||
log.AppendLine($"> {label} READ: {channel.ReadCommand}"); |
|||
var response = await client.QueryAsync(channel.ReadCommand); |
|||
log.AppendLine(response); |
|||
|
|||
return ExtractFirstDecimal(response, label); |
|||
} |
|||
``` |
|||
|
|||
## Shared SCPI Connection Code |
|||
|
|||
```csharp |
|||
private Task<IScpiClient> CreateClientAsync(string label, ScpiChannelSettings channel) |
|||
{ |
|||
var connection = GetConnectionType(channel); |
|||
return connection switch |
|||
{ |
|||
"TCP" or "LAN" or "ETHERNET" => CreateTcpClientAsync(label, channel), |
|||
"SERIAL" or "COM" => Task.FromResult<IScpiClient>( |
|||
new SerialScpiClient( |
|||
channel.PortName, |
|||
channel.BaudRate, |
|||
_settings.Timeout, |
|||
channel.GetIdnMatches(), |
|||
channel.GetTerminator())), |
|||
"VISA" or "USB" => CreateVisaClientAsync(channel), |
|||
_ => throw new InvalidOperationException($"{label} 장비 연결 방식은 Visa, Serial, Tcp 중 하나로 설정하세요.") |
|||
}; |
|||
} |
|||
``` |
|||
|
|||
```csharp |
|||
private static decimal ExtractFirstDecimal(string response, string label) |
|||
{ |
|||
var match = Regex.Match(response, @"[-+]?\d+(?:\.\d+)?(?:[Ee][-+]?\d+)?"); |
|||
if (!match.Success) |
|||
{ |
|||
throw new InvalidOperationException($"{label} 측정값 파싱 실패"); |
|||
} |
|||
|
|||
return decimal.Parse(match.Value, NumberStyles.Float, CultureInfo.InvariantCulture); |
|||
} |
|||
``` |
|||
@ -0,0 +1,37 @@ |
|||
[Equipment] |
|||
Timeout=5000 |
|||
SettleMilliseconds=300 |
|||
|
|||
[PowerSupply] |
|||
Model=Keysight E36233A |
|||
Measurement=Current |
|||
PreBoardCommand=VOLT 5, (@2);OUTP ON, (@2) |
|||
PreBoardDelayMilliseconds=2000 |
|||
LogoutCommand=OUTP OFF, (@1) |
|||
Connection=LAN |
|||
Resource= |
|||
IdnMatch=E36233A |
|||
Host=192.168.10.12 |
|||
Port=5025 |
|||
PortName= |
|||
BaudRate=9600 |
|||
Terminator=LF |
|||
SetupCommand=OUTP ON, (@1) |
|||
CleanupCommand=OUTP OFF, (@1) |
|||
ReadCommand=MEAS:CURR? (@1) |
|||
|
|||
[OriginalHardwareIniKeys] |
|||
PreBoardCommand=PreBoardCommand |
|||
PreBoardDelayMilliseconds=PreBoardDelayMilliseconds |
|||
LogoutCommand=LogoutCommand |
|||
Connection=CurrentConnection |
|||
Resource=CurrentResource |
|||
IdnMatch=CurrentIdnMatch |
|||
Host=CurrentHost |
|||
Port=CurrentPort |
|||
PortName=CurrentPortName |
|||
BaudRate=CurrentBaudRate |
|||
Terminator=CurrentTerminator |
|||
SetupCommand=CurrentSetupCommand |
|||
CleanupCommand=CurrentCleanupCommand |
|||
ReadCommand=CurrentReadCommand |
|||
@ -0,0 +1,144 @@ |
|||
# Power Supply Related Code |
|||
|
|||
This file is a reference-only extraction. It is not compiled by the Housing app. |
|||
|
|||
## Source Files |
|||
|
|||
- `Services/EquipmentMeasurementSettings.cs` |
|||
- `Services/EquipmentMeasurementService.cs` |
|||
- `Services/IScpiClient.cs` |
|||
- `Services/TcpScpiClient.cs` |
|||
- `Services/SerialScpiClient.cs` |
|||
- `Services/VisaScpiClient.cs` |
|||
|
|||
## Hardware.ini Keys |
|||
|
|||
```ini |
|||
[Equipment] |
|||
Timeout=5000 |
|||
SettleMilliseconds=300 |
|||
PreBoardCommand=VOLT 5, (@2);OUTP ON, (@2) |
|||
PreBoardDelayMilliseconds=2000 |
|||
LogoutCommand=OUTP OFF, (@1) |
|||
|
|||
; E36233A Power Supply |
|||
CurrentConnection=LAN |
|||
CurrentResource= |
|||
CurrentIdnMatch=E36233A |
|||
CurrentHost=192.168.10.12 |
|||
CurrentPort=5025 |
|||
CurrentPortName= |
|||
CurrentBaudRate=9600 |
|||
CurrentTerminator=LF |
|||
CurrentSetupCommand=OUTP ON, (@1) |
|||
CurrentCleanupCommand=OUTP OFF, (@1) |
|||
CurrentReadCommand=MEAS:CURR? (@1) |
|||
``` |
|||
|
|||
## Settings Load Code |
|||
|
|||
```csharp |
|||
PreBoardCommand = GetString(values, "PreBoardCommand", string.Empty); |
|||
PreBoardDelayMilliseconds = GetInt(values, "PreBoardDelayMilliseconds", 0); |
|||
LogoutCommand = GetString(values, "LogoutCommand", string.Empty); |
|||
Current = LoadChannel(values, "Current", "MEAS:CURR? CH1", "E362"); |
|||
``` |
|||
|
|||
## Pre-Board Output Control |
|||
|
|||
```csharp |
|||
public async Task<string> RunPreBoardCommandAsync() |
|||
{ |
|||
var log = new StringBuilder(); |
|||
if (IsDisabled(_settings.Current) || string.IsNullOrWhiteSpace(_settings.PreBoardCommand)) |
|||
{ |
|||
return string.Empty; |
|||
} |
|||
|
|||
using var client = await CreateClientAsync("CURRENT", _settings.Current); |
|||
log.AppendLine($"> CURRENT PRE-BOARD CONNECT: {DescribeClient(client, _settings.Current)}"); |
|||
log.AppendLine($"> CURRENT PRE-BOARD SETUP: {_settings.PreBoardCommand}"); |
|||
await SendCommandListAsync(client, _settings.PreBoardCommand); |
|||
return log.ToString(); |
|||
} |
|||
``` |
|||
|
|||
## Current Read Flow |
|||
|
|||
```csharp |
|||
if (!IsDisabled(_settings.Current) && !string.IsNullOrWhiteSpace(_settings.Current.SetupCommand)) |
|||
{ |
|||
currentClient = await CreateClientAsync("CURRENT", _settings.Current); |
|||
log.AppendLine($"> CURRENT PRE-READ CONNECT: {DescribeClient(currentClient, _settings.Current)}"); |
|||
log.AppendLine($"> CURRENT PRE-READ SETUP: {_settings.Current.SetupCommand}"); |
|||
await SendCommandListAsync(currentClient, _settings.Current.SetupCommand); |
|||
} |
|||
|
|||
var current = currentClient is null |
|||
? await ReadChannelAsync("CURRENT", _settings.Current, log) |
|||
: await ReadChannelWithClientAsync("CURRENT", _settings.Current, currentClient, log, skipSetupCommand: true); |
|||
``` |
|||
|
|||
## Cleanup And Logout |
|||
|
|||
```csharp |
|||
private static async Task SendCleanupCommandAsync(IScpiClient? client, ScpiChannelSettings channel, StringBuilder log) |
|||
{ |
|||
if (client is null || string.IsNullOrWhiteSpace(channel.CleanupCommand)) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
try |
|||
{ |
|||
log.AppendLine($"> CURRENT CLEANUP: {channel.CleanupCommand}"); |
|||
await SendCommandListAsync(client, channel.CleanupCommand); |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
log.AppendLine($"> CURRENT CLEANUP FAILED: {ex.Message}"); |
|||
} |
|||
} |
|||
``` |
|||
|
|||
```csharp |
|||
public async Task<string> RunLogoutCommandAsync() |
|||
{ |
|||
var log = new StringBuilder(); |
|||
if (IsDisabled(_settings.Current) || string.IsNullOrWhiteSpace(_settings.LogoutCommand)) |
|||
{ |
|||
return string.Empty; |
|||
} |
|||
|
|||
using var client = await CreateClientAsync("CURRENT", _settings.Current); |
|||
log.AppendLine($"> CURRENT LOGOUT CONNECT: {DescribeClient(client, _settings.Current)}"); |
|||
log.AppendLine($"> CURRENT LOGOUT: {_settings.LogoutCommand}"); |
|||
await SendCommandListAsync(client, _settings.LogoutCommand); |
|||
return log.ToString(); |
|||
} |
|||
``` |
|||
|
|||
## Protected Power-Off Command Guard |
|||
|
|||
```csharp |
|||
private static async Task SendCommandListAsync(IScpiClient client, string commands) |
|||
{ |
|||
foreach (var command in SplitCommands(commands)) |
|||
{ |
|||
if (IsProtectedPowerOffCommand(command)) |
|||
{ |
|||
continue; |
|||
} |
|||
|
|||
await client.SendAsync(command); |
|||
await Task.Delay(100); |
|||
} |
|||
} |
|||
``` |
|||
|
|||
```csharp |
|||
private static bool IsProtectedPowerOffCommand(string command) |
|||
{ |
|||
return Regex.IsMatch(command, @"^\s*OUTP(?:UT)?\s+OFF\s*,?\s*\(@2\)\s*$", RegexOptions.IgnoreCase); |
|||
} |
|||
``` |
|||
@ -0,0 +1,733 @@ |
|||
"DeployProject" |
|||
{ |
|||
"VSVersion" = "3:800" |
|||
"ProjectType" = "8:{978C614F-708E-4E1A-B201-565925725DBA}" |
|||
"IsWebType" = "8:FALSE" |
|||
"ProjectName" = "8:Setup100" |
|||
"LanguageId" = "3:1042" |
|||
"CodePage" = "3:949" |
|||
"UILanguageId" = "3:1042" |
|||
"SccProjectName" = "8:" |
|||
"SccLocalPath" = "8:" |
|||
"SccAuxPath" = "8:" |
|||
"SccProvider" = "8:" |
|||
"Hierarchy" |
|||
{ |
|||
"Entry" |
|||
{ |
|||
"MsmKey" = "8:_579C5BF19AF141B38F44C957EADB21FC" |
|||
"OwnerKey" = "8:_UNDEFINED" |
|||
"MsmSig" = "8:_UNDEFINED" |
|||
} |
|||
"Entry" |
|||
{ |
|||
"MsmKey" = "8:_8883E9101F6441DEB01A93D9ED8184BB" |
|||
"OwnerKey" = "8:_UNDEFINED" |
|||
"MsmSig" = "8:_UNDEFINED" |
|||
} |
|||
} |
|||
"Configurations" |
|||
{ |
|||
"Debug" |
|||
{ |
|||
"DisplayName" = "8:Debug" |
|||
"IsDebugOnly" = "11:TRUE" |
|||
"IsReleaseOnly" = "11:FALSE" |
|||
"OutputFilename" = "8:Debug\\Setup100.msi" |
|||
"PackageFilesAs" = "3:2" |
|||
"PackageFileSize" = "3:-2147483648" |
|||
"CabType" = "3:1" |
|||
"Compression" = "3:2" |
|||
"SignOutput" = "11:FALSE" |
|||
"CertificateFile" = "8:" |
|||
"PrivateKeyFile" = "8:" |
|||
"TimeStampServer" = "8:" |
|||
"InstallerBootstrapper" = "3:2" |
|||
} |
|||
"Release" |
|||
{ |
|||
"DisplayName" = "8:Release" |
|||
"IsDebugOnly" = "11:FALSE" |
|||
"IsReleaseOnly" = "11:TRUE" |
|||
"OutputFilename" = "8:Release\\Setup100.msi" |
|||
"PackageFilesAs" = "3:2" |
|||
"PackageFileSize" = "3:-2147483648" |
|||
"CabType" = "3:1" |
|||
"Compression" = "3:2" |
|||
"SignOutput" = "11:FALSE" |
|||
"CertificateFile" = "8:" |
|||
"PrivateKeyFile" = "8:" |
|||
"TimeStampServer" = "8:" |
|||
"InstallerBootstrapper" = "3:2" |
|||
} |
|||
} |
|||
"Deployable" |
|||
{ |
|||
"CustomAction" |
|||
{ |
|||
} |
|||
"DefaultFeature" |
|||
{ |
|||
"Name" = "8:DefaultFeature" |
|||
"Title" = "8:" |
|||
"Description" = "8:" |
|||
} |
|||
"ExternalPersistence" |
|||
{ |
|||
"LaunchCondition" |
|||
{ |
|||
"{A06ECF26-33A3-4562-8140-9B0E340D4F24}:_340FFED54D9141C0B594E0BF67568967" |
|||
{ |
|||
"Name" = "8:.NET Core" |
|||
"Message" = "8:[VSDNETCOREMSG]" |
|||
"AllowLaterVersions" = "11:FALSE" |
|||
"InstallUrl" = "8:https://dotnet.microsoft.com/download/dotnet-core/[NetCoreVerMajorDotMinor]" |
|||
"IsNETCore" = "11:TRUE" |
|||
"Architecture" = "2:0" |
|||
"Runtime" = "2:0" |
|||
} |
|||
} |
|||
} |
|||
"File" |
|||
{ |
|||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_579C5BF19AF141B38F44C957EADB21FC" |
|||
{ |
|||
"SourcePath" = "8:..\\Resources\\Housing_voltage_current_icon_msi_noborder.ico" |
|||
"TargetName" = "8:Housing_voltage_current_icon_msi_noborder.ico" |
|||
"Tag" = "8:" |
|||
"Folder" = "8:_25EEF778496E404083BDF310C935E38F" |
|||
"Condition" = "8:" |
|||
"Transitive" = "11:FALSE" |
|||
"Vital" = "11:TRUE" |
|||
"ReadOnly" = "11:FALSE" |
|||
"Hidden" = "11:FALSE" |
|||
"System" = "11:FALSE" |
|||
"Permanent" = "11:FALSE" |
|||
"SharedLegacy" = "11:FALSE" |
|||
"PackageAs" = "3:1" |
|||
"Register" = "3:1" |
|||
"Exclude" = "11:FALSE" |
|||
"IsDependency" = "11:FALSE" |
|||
"IsolateTo" = "8:" |
|||
} |
|||
} |
|||
"FileType" |
|||
{ |
|||
} |
|||
"Folder" |
|||
{ |
|||
"{3C67513D-01DD-4637-8A68-80971EB9504F}:_25EEF778496E404083BDF310C935E38F" |
|||
{ |
|||
"DefaultLocation" = "8:[ProgramFiles64Folder][Manufacturer]\\[ProductName]" |
|||
"Name" = "8:#1925" |
|||
"AlwaysCreate" = "11:FALSE" |
|||
"Condition" = "8:" |
|||
"Transitive" = "11:FALSE" |
|||
"Property" = "8:TARGETDIR" |
|||
"Folders" |
|||
{ |
|||
} |
|||
} |
|||
"{1525181F-901A-416C-8A58-119130FE478E}:_66AFF44728114DBBA9BCE34144FAAB41" |
|||
{ |
|||
"Name" = "8:#1916" |
|||
"AlwaysCreate" = "11:FALSE" |
|||
"Condition" = "8:" |
|||
"Transitive" = "11:FALSE" |
|||
"Property" = "8:DesktopFolder" |
|||
"Folders" |
|||
{ |
|||
} |
|||
} |
|||
"{1525181F-901A-416C-8A58-119130FE478E}:_BEE777F673764227A190AF65ACD21AC2" |
|||
{ |
|||
"Name" = "8:#1919" |
|||
"AlwaysCreate" = "11:FALSE" |
|||
"Condition" = "8:" |
|||
"Transitive" = "11:FALSE" |
|||
"Property" = "8:ProgramMenuFolder" |
|||
"Folders" |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
"LaunchCondition" |
|||
{ |
|||
} |
|||
"Locator" |
|||
{ |
|||
} |
|||
"MsiBootstrapper" |
|||
{ |
|||
"LangId" = "3:1042" |
|||
"RequiresElevation" = "11:FALSE" |
|||
} |
|||
"Product" |
|||
{ |
|||
"Name" = "8:Microsoft Visual Studio" |
|||
"ProductName" = "8:Setup100" |
|||
"ProductCode" = "8:{42EE0882-2178-4689-8512-0C0FC32A0125}" |
|||
"PackageCode" = "8:{6CF458C9-AF29-44D4-943F-464C3DC7E545}" |
|||
"UpgradeCode" = "8:{610D4218-DD05-4EAB-BAE2-1A802D29ADD4}" |
|||
"AspNetVersion" = "8:" |
|||
"RestartWWWService" = "11:FALSE" |
|||
"RemovePreviousVersions" = "11:FALSE" |
|||
"DetectNewerInstalledVersion" = "11:TRUE" |
|||
"InstallAllUsers" = "11:FALSE" |
|||
"ProductVersion" = "8:1.0.0" |
|||
"Manufacturer" = "8:temp" |
|||
"ARPHELPTELEPHONE" = "8:" |
|||
"ARPHELPLINK" = "8:" |
|||
"Title" = "8:Setup100" |
|||
"Subject" = "8:" |
|||
"ARPCONTACT" = "8:temp" |
|||
"Keywords" = "8:" |
|||
"ARPCOMMENTS" = "8:" |
|||
"ARPURLINFOABOUT" = "8:" |
|||
"ARPPRODUCTICON" = "8:" |
|||
"ARPIconIndex" = "3:0" |
|||
"SearchPath" = "8:" |
|||
"UseSystemSearchPath" = "11:TRUE" |
|||
"TargetPlatform" = "3:1" |
|||
"PreBuildEvent" = "8:" |
|||
"PostBuildEvent" = "8:" |
|||
"RunPostBuildEvent" = "3:0" |
|||
} |
|||
"Registry" |
|||
{ |
|||
"HKLM" |
|||
{ |
|||
"Keys" |
|||
{ |
|||
"{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_39EF283C652B4AC69FFE46D72F8A9F1F" |
|||
{ |
|||
"Name" = "8:Software" |
|||
"Condition" = "8:" |
|||
"AlwaysCreate" = "11:FALSE" |
|||
"DeleteAtUninstall" = "11:FALSE" |
|||
"Transitive" = "11:FALSE" |
|||
"Keys" |
|||
{ |
|||
"{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_9526C11DBE504CBB8BC54ACE4A67A452" |
|||
{ |
|||
"Name" = "8:[Manufacturer]" |
|||
"Condition" = "8:" |
|||
"AlwaysCreate" = "11:FALSE" |
|||
"DeleteAtUninstall" = "11:FALSE" |
|||
"Transitive" = "11:FALSE" |
|||
"Keys" |
|||
{ |
|||
} |
|||
"Values" |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
"Values" |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
} |
|||
"HKCU" |
|||
{ |
|||
"Keys" |
|||
{ |
|||
"{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_9B0F05EAC02645F99F3EA4153E6985B4" |
|||
{ |
|||
"Name" = "8:Software" |
|||
"Condition" = "8:" |
|||
"AlwaysCreate" = "11:FALSE" |
|||
"DeleteAtUninstall" = "11:FALSE" |
|||
"Transitive" = "11:FALSE" |
|||
"Keys" |
|||
{ |
|||
"{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_0EE8870A6A344A6EA9C888D961766653" |
|||
{ |
|||
"Name" = "8:[Manufacturer]" |
|||
"Condition" = "8:" |
|||
"AlwaysCreate" = "11:FALSE" |
|||
"DeleteAtUninstall" = "11:FALSE" |
|||
"Transitive" = "11:FALSE" |
|||
"Keys" |
|||
{ |
|||
} |
|||
"Values" |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
"Values" |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
} |
|||
"HKCR" |
|||
{ |
|||
"Keys" |
|||
{ |
|||
} |
|||
} |
|||
"HKU" |
|||
{ |
|||
"Keys" |
|||
{ |
|||
} |
|||
} |
|||
"HKPU" |
|||
{ |
|||
"Keys" |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
"Sequences" |
|||
{ |
|||
} |
|||
"Shortcut" |
|||
{ |
|||
"{970C0BB2-C7D0-45D7-ABFA-7EC378858BC0}:_0869784F4F8841ACA5963F59D7B16198" |
|||
{ |
|||
"Name" = "8:Housing" |
|||
"Arguments" = "8:" |
|||
"Description" = "8:" |
|||
"ShowCmd" = "3:1" |
|||
"IconIndex" = "3:0" |
|||
"Transitive" = "11:FALSE" |
|||
"Target" = "8:_8883E9101F6441DEB01A93D9ED8184BB" |
|||
"Folder" = "8:_66AFF44728114DBBA9BCE34144FAAB41" |
|||
"WorkingFolder" = "8:_25EEF778496E404083BDF310C935E38F" |
|||
"Icon" = "8:_579C5BF19AF141B38F44C957EADB21FC" |
|||
"Feature" = "8:" |
|||
} |
|||
} |
|||
"UserInterface" |
|||
{ |
|||
"{DF760B10-853B-4699-99F2-AFF7185B4A62}:_04AB189F79C141D4B656C539A572FAEF" |
|||
{ |
|||
"Name" = "8:#1900" |
|||
"Sequence" = "3:2" |
|||
"Attributes" = "3:1" |
|||
"Dialogs" |
|||
{ |
|||
"{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_02368588C083450E83F88B39FF14CFA1" |
|||
{ |
|||
"Sequence" = "3:100" |
|||
"DisplayName" = "8:환영" |
|||
"UseDynamicProperties" = "11:TRUE" |
|||
"IsDependency" = "11:FALSE" |
|||
"SourcePath" = "8:<VsdDialogDir>\\VsdAdminWelcomeDlg.wid" |
|||
"Properties" |
|||
{ |
|||
"BannerBitmap" |
|||
{ |
|||
"Name" = "8:BannerBitmap" |
|||
"DisplayName" = "8:#1001" |
|||
"Description" = "8:#1101" |
|||
"Type" = "3:8" |
|||
"ContextData" = "8:Bitmap" |
|||
"Attributes" = "3:4" |
|||
"Setting" = "3:1" |
|||
"UsePlugInResources" = "11:TRUE" |
|||
} |
|||
"CopyrightWarning" |
|||
{ |
|||
"Name" = "8:CopyrightWarning" |
|||
"DisplayName" = "8:#1002" |
|||
"Description" = "8:#1102" |
|||
"Type" = "3:3" |
|||
"ContextData" = "8:" |
|||
"Attributes" = "3:0" |
|||
"Setting" = "3:1" |
|||
"Value" = "8:#1202" |
|||
"DefaultValue" = "8:#1202" |
|||
"UsePlugInResources" = "11:TRUE" |
|||
} |
|||
"Welcome" |
|||
{ |
|||
"Name" = "8:Welcome" |
|||
"DisplayName" = "8:#1003" |
|||
"Description" = "8:#1103" |
|||
"Type" = "3:3" |
|||
"ContextData" = "8:" |
|||
"Attributes" = "3:0" |
|||
"Setting" = "3:1" |
|||
"Value" = "8:#1203" |
|||
"DefaultValue" = "8:#1203" |
|||
"UsePlugInResources" = "11:TRUE" |
|||
} |
|||
} |
|||
} |
|||
"{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_6B2319BBA43F4B0E98499B17431AABC7" |
|||
{ |
|||
"Sequence" = "3:300" |
|||
"DisplayName" = "8:설치 확인" |
|||
"UseDynamicProperties" = "11:TRUE" |
|||
"IsDependency" = "11:FALSE" |
|||
"SourcePath" = "8:<VsdDialogDir>\\VsdAdminConfirmDlg.wid" |
|||
"Properties" |
|||
{ |
|||
"BannerBitmap" |
|||
{ |
|||
"Name" = "8:BannerBitmap" |
|||
"DisplayName" = "8:#1001" |
|||
"Description" = "8:#1101" |
|||
"Type" = "3:8" |
|||
"ContextData" = "8:Bitmap" |
|||
"Attributes" = "3:4" |
|||
"Setting" = "3:1" |
|||
"UsePlugInResources" = "11:TRUE" |
|||
} |
|||
} |
|||
} |
|||
"{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_8199646E4ADF4CA497CB35DD5D9B4EA3" |
|||
{ |
|||
"Sequence" = "3:200" |
|||
"DisplayName" = "8:설치 폴더" |
|||
"UseDynamicProperties" = "11:TRUE" |
|||
"IsDependency" = "11:FALSE" |
|||
"SourcePath" = "8:<VsdDialogDir>\\VsdAdminFolderDlg.wid" |
|||
"Properties" |
|||
{ |
|||
"BannerBitmap" |
|||
{ |
|||
"Name" = "8:BannerBitmap" |
|||
"DisplayName" = "8:#1001" |
|||
"Description" = "8:#1101" |
|||
"Type" = "3:8" |
|||
"ContextData" = "8:Bitmap" |
|||
"Attributes" = "3:4" |
|||
"Setting" = "3:1" |
|||
"UsePlugInResources" = "11:TRUE" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
"{DF760B10-853B-4699-99F2-AFF7185B4A62}:_48A28929DD8F42FA8754A057491B7190" |
|||
{ |
|||
"Name" = "8:#1902" |
|||
"Sequence" = "3:2" |
|||
"Attributes" = "3:3" |
|||
"Dialogs" |
|||
{ |
|||
"{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_1958E6FF4D7644948E621DB2C391ABB5" |
|||
{ |
|||
"Sequence" = "3:100" |
|||
"DisplayName" = "8:마침" |
|||
"UseDynamicProperties" = "11:TRUE" |
|||
"IsDependency" = "11:FALSE" |
|||
"SourcePath" = "8:<VsdDialogDir>\\VsdAdminFinishedDlg.wid" |
|||
"Properties" |
|||
{ |
|||
"BannerBitmap" |
|||
{ |
|||
"Name" = "8:BannerBitmap" |
|||
"DisplayName" = "8:#1001" |
|||
"Description" = "8:#1101" |
|||
"Type" = "3:8" |
|||
"ContextData" = "8:Bitmap" |
|||
"Attributes" = "3:4" |
|||
"Setting" = "3:1" |
|||
"UsePlugInResources" = "11:TRUE" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
"{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_48FD9E8D7F534713B0B26FD39C225534" |
|||
{ |
|||
"UseDynamicProperties" = "11:FALSE" |
|||
"IsDependency" = "11:FALSE" |
|||
"SourcePath" = "8:<VsdDialogDir>\\VsdUserInterface.wim" |
|||
} |
|||
"{DF760B10-853B-4699-99F2-AFF7185B4A62}:_5722F25259EC4038B82754A82CD8314C" |
|||
{ |
|||
"Name" = "8:#1900" |
|||
"Sequence" = "3:1" |
|||
"Attributes" = "3:1" |
|||
"Dialogs" |
|||
{ |
|||
"{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_7AD188584ACC4527B8ADF78D4B8C1E94" |
|||
{ |
|||
"Sequence" = "3:300" |
|||
"DisplayName" = "8:설치 확인" |
|||
"UseDynamicProperties" = "11:TRUE" |
|||
"IsDependency" = "11:FALSE" |
|||
"SourcePath" = "8:<VsdDialogDir>\\VsdConfirmDlg.wid" |
|||
"Properties" |
|||
{ |
|||
"BannerBitmap" |
|||
{ |
|||
"Name" = "8:BannerBitmap" |
|||
"DisplayName" = "8:#1001" |
|||
"Description" = "8:#1101" |
|||
"Type" = "3:8" |
|||
"ContextData" = "8:Bitmap" |
|||
"Attributes" = "3:4" |
|||
"Setting" = "3:1" |
|||
"UsePlugInResources" = "11:TRUE" |
|||
} |
|||
} |
|||
} |
|||
"{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_8F418472D442448A82EF5B715330C4AD" |
|||
{ |
|||
"Sequence" = "3:100" |
|||
"DisplayName" = "8:환영" |
|||
"UseDynamicProperties" = "11:TRUE" |
|||
"IsDependency" = "11:FALSE" |
|||
"SourcePath" = "8:<VsdDialogDir>\\VsdWelcomeDlg.wid" |
|||
"Properties" |
|||
{ |
|||
"BannerBitmap" |
|||
{ |
|||
"Name" = "8:BannerBitmap" |
|||
"DisplayName" = "8:#1001" |
|||
"Description" = "8:#1101" |
|||
"Type" = "3:8" |
|||
"ContextData" = "8:Bitmap" |
|||
"Attributes" = "3:4" |
|||
"Setting" = "3:1" |
|||
"UsePlugInResources" = "11:TRUE" |
|||
} |
|||
"CopyrightWarning" |
|||
{ |
|||
"Name" = "8:CopyrightWarning" |
|||
"DisplayName" = "8:#1002" |
|||
"Description" = "8:#1102" |
|||
"Type" = "3:3" |
|||
"ContextData" = "8:" |
|||
"Attributes" = "3:0" |
|||
"Setting" = "3:1" |
|||
"Value" = "8:#1202" |
|||
"DefaultValue" = "8:#1202" |
|||
"UsePlugInResources" = "11:TRUE" |
|||
} |
|||
"Welcome" |
|||
{ |
|||
"Name" = "8:Welcome" |
|||
"DisplayName" = "8:#1003" |
|||
"Description" = "8:#1103" |
|||
"Type" = "3:3" |
|||
"ContextData" = "8:" |
|||
"Attributes" = "3:0" |
|||
"Setting" = "3:1" |
|||
"Value" = "8:#1203" |
|||
"DefaultValue" = "8:#1203" |
|||
"UsePlugInResources" = "11:TRUE" |
|||
} |
|||
} |
|||
} |
|||
"{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_A70CDD4D26FE416E85635A6477E83C99" |
|||
{ |
|||
"Sequence" = "3:200" |
|||
"DisplayName" = "8:설치 폴더" |
|||
"UseDynamicProperties" = "11:TRUE" |
|||
"IsDependency" = "11:FALSE" |
|||
"SourcePath" = "8:<VsdDialogDir>\\VsdFolderDlg.wid" |
|||
"Properties" |
|||
{ |
|||
"BannerBitmap" |
|||
{ |
|||
"Name" = "8:BannerBitmap" |
|||
"DisplayName" = "8:#1001" |
|||
"Description" = "8:#1101" |
|||
"Type" = "3:8" |
|||
"ContextData" = "8:Bitmap" |
|||
"Attributes" = "3:4" |
|||
"Setting" = "3:1" |
|||
"UsePlugInResources" = "11:TRUE" |
|||
} |
|||
"InstallAllUsersVisible" |
|||
{ |
|||
"Name" = "8:InstallAllUsersVisible" |
|||
"DisplayName" = "8:#1059" |
|||
"Description" = "8:#1159" |
|||
"Type" = "3:5" |
|||
"ContextData" = "8:1;True=1;False=0" |
|||
"Attributes" = "3:0" |
|||
"Setting" = "3:0" |
|||
"Value" = "3:1" |
|||
"DefaultValue" = "3:1" |
|||
"UsePlugInResources" = "11:TRUE" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
"{DF760B10-853B-4699-99F2-AFF7185B4A62}:_61DB10700E264A71B89788C6597725A2" |
|||
{ |
|||
"Name" = "8:#1902" |
|||
"Sequence" = "3:1" |
|||
"Attributes" = "3:3" |
|||
"Dialogs" |
|||
{ |
|||
"{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_849D9D5D0F5A481A8AEDAE597AE94504" |
|||
{ |
|||
"Sequence" = "3:100" |
|||
"DisplayName" = "8:마침" |
|||
"UseDynamicProperties" = "11:TRUE" |
|||
"IsDependency" = "11:FALSE" |
|||
"SourcePath" = "8:<VsdDialogDir>\\VsdFinishedDlg.wid" |
|||
"Properties" |
|||
{ |
|||
"BannerBitmap" |
|||
{ |
|||
"Name" = "8:BannerBitmap" |
|||
"DisplayName" = "8:#1001" |
|||
"Description" = "8:#1101" |
|||
"Type" = "3:8" |
|||
"ContextData" = "8:Bitmap" |
|||
"Attributes" = "3:4" |
|||
"Setting" = "3:1" |
|||
"UsePlugInResources" = "11:TRUE" |
|||
} |
|||
"UpdateText" |
|||
{ |
|||
"Name" = "8:UpdateText" |
|||
"DisplayName" = "8:#1058" |
|||
"Description" = "8:#1158" |
|||
"Type" = "3:15" |
|||
"ContextData" = "8:" |
|||
"Attributes" = "3:0" |
|||
"Setting" = "3:1" |
|||
"Value" = "8:#1258" |
|||
"DefaultValue" = "8:#1258" |
|||
"UsePlugInResources" = "11:TRUE" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
"{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_66D5A4849DA74893B5DE7BC91285BF39" |
|||
{ |
|||
"UseDynamicProperties" = "11:FALSE" |
|||
"IsDependency" = "11:FALSE" |
|||
"SourcePath" = "8:<VsdDialogDir>\\VsdBasicDialogs.wim" |
|||
} |
|||
"{DF760B10-853B-4699-99F2-AFF7185B4A62}:_9ECC9BE8279449D08E3879378D28F5F4" |
|||
{ |
|||
"Name" = "8:#1901" |
|||
"Sequence" = "3:1" |
|||
"Attributes" = "3:2" |
|||
"Dialogs" |
|||
{ |
|||
"{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_11605F0AA4EF461C9ED97277B3198620" |
|||
{ |
|||
"Sequence" = "3:100" |
|||
"DisplayName" = "8:진행률" |
|||
"UseDynamicProperties" = "11:TRUE" |
|||
"IsDependency" = "11:FALSE" |
|||
"SourcePath" = "8:<VsdDialogDir>\\VsdProgressDlg.wid" |
|||
"Properties" |
|||
{ |
|||
"BannerBitmap" |
|||
{ |
|||
"Name" = "8:BannerBitmap" |
|||
"DisplayName" = "8:#1001" |
|||
"Description" = "8:#1101" |
|||
"Type" = "3:8" |
|||
"ContextData" = "8:Bitmap" |
|||
"Attributes" = "3:4" |
|||
"Setting" = "3:1" |
|||
"UsePlugInResources" = "11:TRUE" |
|||
} |
|||
"ShowProgress" |
|||
{ |
|||
"Name" = "8:ShowProgress" |
|||
"DisplayName" = "8:#1009" |
|||
"Description" = "8:#1109" |
|||
"Type" = "3:5" |
|||
"ContextData" = "8:1;True=1;False=0" |
|||
"Attributes" = "3:0" |
|||
"Setting" = "3:0" |
|||
"Value" = "3:1" |
|||
"DefaultValue" = "3:1" |
|||
"UsePlugInResources" = "11:TRUE" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
"{DF760B10-853B-4699-99F2-AFF7185B4A62}:_A39EAE152FD34A3D8E60FA00E71EE82E" |
|||
{ |
|||
"Name" = "8:#1901" |
|||
"Sequence" = "3:2" |
|||
"Attributes" = "3:2" |
|||
"Dialogs" |
|||
{ |
|||
"{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_96B06613F8184F7CB033D968D7ACAB56" |
|||
{ |
|||
"Sequence" = "3:100" |
|||
"DisplayName" = "8:진행률" |
|||
"UseDynamicProperties" = "11:TRUE" |
|||
"IsDependency" = "11:FALSE" |
|||
"SourcePath" = "8:<VsdDialogDir>\\VsdAdminProgressDlg.wid" |
|||
"Properties" |
|||
{ |
|||
"BannerBitmap" |
|||
{ |
|||
"Name" = "8:BannerBitmap" |
|||
"DisplayName" = "8:#1001" |
|||
"Description" = "8:#1101" |
|||
"Type" = "3:8" |
|||
"ContextData" = "8:Bitmap" |
|||
"Attributes" = "3:4" |
|||
"Setting" = "3:1" |
|||
"UsePlugInResources" = "11:TRUE" |
|||
} |
|||
"ShowProgress" |
|||
{ |
|||
"Name" = "8:ShowProgress" |
|||
"DisplayName" = "8:#1009" |
|||
"Description" = "8:#1109" |
|||
"Type" = "3:5" |
|||
"ContextData" = "8:1;True=1;False=0" |
|||
"Attributes" = "3:0" |
|||
"Setting" = "3:0" |
|||
"Value" = "3:1" |
|||
"DefaultValue" = "3:1" |
|||
"UsePlugInResources" = "11:TRUE" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
"MergeModule" |
|||
{ |
|||
} |
|||
"ProjectOutput" |
|||
{ |
|||
"{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_8883E9101F6441DEB01A93D9ED8184BB" |
|||
{ |
|||
"SourcePath" = "8:..\\obj\\Release\\net9.0-windows\\apphost.exe" |
|||
"TargetName" = "8:" |
|||
"Tag" = "8:" |
|||
"Folder" = "8:_25EEF778496E404083BDF310C935E38F" |
|||
"Condition" = "8:" |
|||
"Transitive" = "11:FALSE" |
|||
"Vital" = "11:TRUE" |
|||
"ReadOnly" = "11:FALSE" |
|||
"Hidden" = "11:FALSE" |
|||
"System" = "11:FALSE" |
|||
"Permanent" = "11:FALSE" |
|||
"SharedLegacy" = "11:FALSE" |
|||
"PackageAs" = "3:1" |
|||
"Register" = "3:1" |
|||
"Exclude" = "11:FALSE" |
|||
"IsDependency" = "11:FALSE" |
|||
"IsolateTo" = "8:" |
|||
"ProjectOutputGroupRegister" = "3:1" |
|||
"OutputConfiguration" = "8:" |
|||
"OutputGroupCanonicalName" = "8:PublishItemsOutputGroup" |
|||
"OutputProjectGuid" = "8:{7364A567-F115-4ACE-9207-C6FDEEF0A394}" |
|||
"ShowKeyOutput" = "11:TRUE" |
|||
"ExcludeFilters" |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
After Width: | Height: | Size: 64 KiB |
|
After Width: | Height: | Size: 65 KiB |
@ -0,0 +1,12 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
<PropertyGroup> |
|||
<OutputType>Exe</OutputType> |
|||
<TargetFramework>net9.0-windows</TargetFramework> |
|||
<UseWPF>true</UseWPF> |
|||
<Nullable>enable</Nullable> |
|||
<ImplicitUsings>enable</ImplicitUsings> |
|||
</PropertyGroup> |
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\Housing.csproj" /> |
|||
</ItemGroup> |
|||
</Project> |
|||
@ -0,0 +1,216 @@ |
|||
using System.Reflection; |
|||
using System.IO; |
|||
using System.Windows; |
|||
using System.Windows.Controls; |
|||
using System.Windows.Media; |
|||
using System.Windows.Media.Imaging; |
|||
using Housing; |
|||
using Housing.Login; |
|||
|
|||
internal static class Program |
|||
{ |
|||
private const int MainWidth = 1200; |
|||
private const int MainHeight = 800; |
|||
private const string ExampleBarcode = "A251001AM46110901T00001-01"; |
|||
private const string ExampleIcSn = "025949A8492CFEAC"; |
|||
|
|||
[STAThread] |
|||
private static void Main() |
|||
{ |
|||
var outputDirectory = Path.GetFullPath( |
|||
Path.Combine(AppContext.BaseDirectory, "..", "..", "..", "..", "manual-screens")); |
|||
Directory.CreateDirectory(outputDirectory); |
|||
|
|||
var app = new App(); |
|||
app.InitializeComponent(); |
|||
|
|||
CaptureLogin(Path.Combine(outputDirectory, "01-login.png")); |
|||
CaptureMainScreens(outputDirectory); |
|||
|
|||
Console.WriteLine(outputDirectory); |
|||
} |
|||
|
|||
private static void CaptureLogin(string path) |
|||
{ |
|||
var window = new StartupLoginWindow |
|||
{ |
|||
WindowState = WindowState.Normal, |
|||
Width = 760, |
|||
Height = 760 |
|||
}; |
|||
|
|||
SelectFirst(window, "MakerComboBox"); |
|||
SelectFirst(window, "ModelComboBox"); |
|||
SelectFirst(window, "Variant1ComboBox"); |
|||
SelectFirst(window, "Variant2ComboBox"); |
|||
SelectFirst(window, "LineNoComboBox"); |
|||
SelectFirst(window, "JigNoComboBox"); |
|||
SetText(window, "OperatorTextBox", "OP1001"); |
|||
SetPassword(window, "PasswordBox", "manual"); |
|||
SetText(window, "LotNoTextBox", "LOT26001"); |
|||
|
|||
RenderWindowContent(window, path, 760, 760); |
|||
window.Close(); |
|||
} |
|||
|
|||
private static void CaptureMainScreens(string outputDirectory) |
|||
{ |
|||
CaptureMain(Path.Combine(outputDirectory, "02-waiting-barcode.png"), window => |
|||
{ |
|||
PrepareMain(window); |
|||
SetText(window, "BarcodeTextBox", string.Empty); |
|||
SetText(window, "IcSnOutputTextBox", string.Empty); |
|||
Invoke(window, "SetProcessStatus", "WAITING BARCODE", "HmiAccentBrush"); |
|||
Invoke(window, "ShowResultStatusMessage", "스캐너로 PCB_Barcode를 스캔해주세요."); |
|||
}); |
|||
|
|||
CaptureMain(Path.Combine(outputDirectory, "03-wait-start-signal.png"), window => |
|||
{ |
|||
PrepareMain(window); |
|||
SetText(window, "BarcodeTextBox", ExampleBarcode); |
|||
Invoke(window, "SetProcessStatus", "WAIT START SIGNAL", "HmiWarningBrush"); |
|||
Invoke( |
|||
window, |
|||
"ShowResultStatusMessage", |
|||
"장비 시작 신호 대기\nNI-6501 Dev1/port0/line0\n시료를 넣고 Housing 장비 시작 버튼을 눌러주세요."); |
|||
}); |
|||
|
|||
CaptureMain(Path.Combine(outputDirectory, "04-board-test.png"), window => |
|||
{ |
|||
PrepareMain(window); |
|||
SetText(window, "BarcodeTextBox", ExampleBarcode); |
|||
SetText(window, "IcSnOutputTextBox", ExampleIcSn); |
|||
Invoke(window, "SetProcessStatus", "BOARD TEST", "HmiWarningBrush"); |
|||
Invoke( |
|||
window, |
|||
"ShowResultStatusMessage", |
|||
"보드 테스트 시작\n1. 시료 연결 확인\n2. IC_SN 읽기\n3. CAL DEFAULT 조건 설정\n4. 시작 신호 기준 지연 후 계측 장비에서 V/A 읽기"); |
|||
}); |
|||
|
|||
CaptureMain(Path.Combine(outputDirectory, "05-result-ok.png"), window => |
|||
{ |
|||
PrepareMain(window); |
|||
SetText(window, "BarcodeTextBox", ExampleBarcode); |
|||
SetText(window, "IcSnOutputTextBox", ExampleIcSn); |
|||
SetText(window, "VOutputTextBox", "5.02"); |
|||
SetText(window, "AOutputTextBox", "118.40"); |
|||
Invoke(window, "ApplyMeasurementOutputState", Find<TextBox>(window, "VOutputTextBox"), true); |
|||
Invoke(window, "ApplyMeasurementOutputState", Find<TextBox>(window, "AOutputTextBox"), true); |
|||
Invoke(window, "ShowInspectionResult", true); |
|||
Invoke(window, "SetProcessStatus", "COMPLETE OK", "HmiRunBrush"); |
|||
}); |
|||
|
|||
CaptureMain(Path.Combine(outputDirectory, "06-result-ng.png"), window => |
|||
{ |
|||
PrepareMain(window); |
|||
SetText(window, "BarcodeTextBox", ExampleBarcode); |
|||
SetText(window, "IcSnOutputTextBox", ExampleIcSn); |
|||
SetText(window, "VOutputTextBox", "5.84"); |
|||
SetText(window, "AOutputTextBox", "122.10"); |
|||
Invoke(window, "ApplyMeasurementOutputState", Find<TextBox>(window, "VOutputTextBox"), false); |
|||
Invoke(window, "ApplyMeasurementOutputState", Find<TextBox>(window, "AOutputTextBox"), true); |
|||
Invoke(window, "ShowInspectionResult", false); |
|||
Invoke(window, "SetProcessStatus", "COMPLETE NG", "HmiDangerBrush"); |
|||
}); |
|||
|
|||
CaptureMain(Path.Combine(outputDirectory, "07-db-save-error.png"), window => |
|||
{ |
|||
PrepareMain(window); |
|||
SetText(window, "BarcodeTextBox", ExampleBarcode); |
|||
SetText(window, "IcSnOutputTextBox", ExampleIcSn); |
|||
SetText(window, "VOutputTextBox", "5.01"); |
|||
SetText(window, "AOutputTextBox", "117.80"); |
|||
Invoke(window, "ApplyMeasurementOutputState", Find<TextBox>(window, "VOutputTextBox"), true); |
|||
Invoke(window, "ApplyMeasurementOutputState", Find<TextBox>(window, "AOutputTextBox"), true); |
|||
Invoke(window, "ShowInspectionResult", true); |
|||
Invoke(window, "SetProcessStatus", "DB SAVE ERROR", "HmiDangerBrush"); |
|||
}); |
|||
} |
|||
|
|||
private static void CaptureMain(string path, Action<MainWindow> arrange) |
|||
{ |
|||
var window = new MainWindow |
|||
{ |
|||
WindowState = WindowState.Normal, |
|||
Width = MainWidth, |
|||
Height = MainHeight |
|||
}; |
|||
|
|||
arrange(window); |
|||
RenderWindowContent(window, path, MainWidth, MainHeight); |
|||
window.Close(); |
|||
} |
|||
|
|||
private static void PrepareMain(MainWindow window) |
|||
{ |
|||
SetTextBlock(window, "OperatorTextBlock", "OP1001"); |
|||
Find<Button>(window, "LogoutButton").Visibility = Visibility.Visible; |
|||
SetText(window, "VMinTextBox", "4.50"); |
|||
SetText(window, "VMaxTextBox", "5.50"); |
|||
SetText(window, "AMinTextBox", "80.00"); |
|||
SetText(window, "AMaxTextBox", "150.00"); |
|||
SetText(window, "VOutputTextBox", "0.00"); |
|||
SetText(window, "AOutputTextBox", "0.00"); |
|||
} |
|||
|
|||
private static void RenderWindowContent(Window window, string path, int width, int height) |
|||
{ |
|||
if (window.Content is not FrameworkElement content) |
|||
{ |
|||
throw new InvalidOperationException("Window content was not a FrameworkElement."); |
|||
} |
|||
|
|||
content.Width = width; |
|||
content.Height = height; |
|||
content.Measure(new Size(width, height)); |
|||
content.Arrange(new Rect(0, 0, width, height)); |
|||
content.UpdateLayout(); |
|||
|
|||
var bitmap = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32); |
|||
bitmap.Render(content); |
|||
|
|||
var encoder = new PngBitmapEncoder(); |
|||
encoder.Frames.Add(BitmapFrame.Create(bitmap)); |
|||
using var stream = File.Create(path); |
|||
encoder.Save(stream); |
|||
} |
|||
|
|||
private static T Find<T>(FrameworkElement owner, string name) where T : FrameworkElement |
|||
{ |
|||
return owner.FindName(name) as T |
|||
?? throw new InvalidOperationException($"{name} was not found."); |
|||
} |
|||
|
|||
private static void SetText(FrameworkElement owner, string name, string value) |
|||
{ |
|||
Find<TextBox>(owner, name).Text = value; |
|||
} |
|||
|
|||
private static void SetTextBlock(FrameworkElement owner, string name, string value) |
|||
{ |
|||
Find<TextBlock>(owner, name).Text = value; |
|||
} |
|||
|
|||
private static void SetPassword(FrameworkElement owner, string name, string value) |
|||
{ |
|||
Find<PasswordBox>(owner, name).Password = value; |
|||
} |
|||
|
|||
private static void SelectFirst(FrameworkElement owner, string name) |
|||
{ |
|||
var comboBox = Find<ComboBox>(owner, name); |
|||
if (comboBox.Items.Count > 0) |
|||
{ |
|||
comboBox.SelectedIndex = 0; |
|||
} |
|||
} |
|||
|
|||
private static object? Invoke(object target, string methodName, params object?[] arguments) |
|||
{ |
|||
var method = target.GetType().GetMethod( |
|||
methodName, |
|||
BindingFlags.Instance | BindingFlags.NonPublic) |
|||
?? throw new MissingMethodException(target.GetType().FullName, methodName); |
|||
return method.Invoke(target, arguments); |
|||
} |
|||
} |
|||
|
After Width: | Height: | Size: 69 KiB |
|
After Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 80 KiB |
|
After Width: | Height: | Size: 89 KiB |
|
After Width: | Height: | Size: 77 KiB |
|
After Width: | Height: | Size: 77 KiB |
|
After Width: | Height: | Size: 76 KiB |