Compare commits

...

4 Commits

Author SHA1 Message Date
1d6c51df3b .. 2025-10-14 22:14:31 +09:00
40842778e0 WebView2 통합 및 Fixed Version 배포 방식 구현
- WebView2 Fixed Version 지원 추가 (오프라인 환경 대응)
- Frm_WebManual에 InitializeWebView2Async() 구현
  - WebView2Runtime 폴더 우선 사용 (Fixed Version)
  - 시스템 런타임으로 폴백
- MdiMain에 CheckWebView2Runtime() 추가
- Setup1.vdproj에 .NET Framework 4.8 배포 설정 반영
- .gitignore에 WebView2Runtime/, WebView2Data/ 추가
- claudedocs/WebView2_Deployment_Guide.md 배포 가이드 추가
  - Fixed Version 다운로드 및 배포 방법
  - 테스트 및 문제 해결 가이드

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-10 16:53:42 +09:00
6cd2abe560 .NET Framework 4.8 업그레이드 및 WebView2 통합
- 모든 프로젝트를 .NET Framework 4.0 → 4.8로 업그레이드
- WebView2 NuGet 패키지 추가 (v1.0.3537.50)
- 사용자 매뉴얼 폼 추가 (Frm_WebManual)
  * WebView2 컨트롤 통합
  * localhost:58123 자동 로드
  * MDI 메인 메뉴에 Manual 항목 추가

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-10 15:37:23 +09:00
0eaeeb0aac add webhosting 2025-10-04 22:13:51 +09:00
36 changed files with 6405 additions and 195 deletions

8
.gitignore vendored
View File

@@ -8,3 +8,11 @@ obj
/Setup1/Debug
/Dotfuscated
UpgradeLog.htm
Packages
.vs
/NUL
# WebView2 Runtime (Fixed Version - 약 100-150MB, 설치 프로그램에 포함)
WebView2Runtime/
# WebView2 User Data (캐시, 쿠키 등 - 런타임 시 자동 생성)
WebView2Data/

View File

@@ -13,7 +13,7 @@
<AssemblyName>ArinLog.Net4</AssemblyName>
<FileAlignment>512</FileAlignment>
<MyType>Windows</MyType>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>

View File

@@ -15,7 +15,7 @@
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<OldToolsVersion>3.5</OldToolsVersion>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">

View File

@@ -15,7 +15,7 @@
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<OldToolsVersion>3.5</OldToolsVersion>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">

View File

@@ -17,6 +17,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Utility", "Utility\Utility.
EndProject
Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "Setup1", "Setup1\Setup1.vdproj", "{0E52FBAC-1A86-4722-93D0-CA7B8570B617}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{A01A7396-C1BE-4D13-8B51-C9C1830DA088}"
ProjectSection(SolutionItems) = preProject
CLAUDE.md = CLAUDE.md
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
CD_ROM|Any CPU = CD_ROM|Any CPU

View File

@@ -29,7 +29,7 @@
<OldToolsVersion>3.5</OldToolsVersion>
<ApplicationManifest>My Project\app.manifest</ApplicationManifest>
<ApplicationIcon>002.ico</ApplicationIcon>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<TargetFrameworkProfile />
<PublishUrl>ftp://tindevil.com/www/mynetapp/t4/</PublishUrl>
<Install>true</Install>
@@ -51,6 +51,8 @@
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -111,8 +113,41 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\Interop.VBIDE.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin, Version=2.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\lib\Microsoft.Owin.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin.FileSystems, Version=2.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\lib\Microsoft.Owin.FileSystems.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin.Host.HttpListener, Version=2.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\lib\Microsoft.Owin.Host.HttpListener.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin.Hosting, Version=2.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\lib\Microsoft.Owin.Hosting.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin.StaticFiles, Version=2.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\lib\Microsoft.Owin.StaticFiles.dll</HintPath>
</Reference>
<Reference Include="Microsoft.ReportViewer.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<Reference Include="Microsoft.ReportViewer.WinForms, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
<Reference Include="Microsoft.Web.WebView2.Core, Version=1.0.3537.50, Culture=neutral, PublicKeyToken=2a8ab48044d2601e, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Web.WebView2.1.0.3537.50\lib\net462\Microsoft.Web.WebView2.Core.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Web.WebView2.WinForms, Version=1.0.3537.50, Culture=neutral, PublicKeyToken=2a8ab48044d2601e, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Web.WebView2.1.0.3537.50\lib\net462\Microsoft.Web.WebView2.WinForms.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Web.WebView2.Wpf, Version=1.0.3537.50, Culture=neutral, PublicKeyToken=2a8ab48044d2601e, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Web.WebView2.1.0.3537.50\lib\net462\Microsoft.Web.WebView2.Wpf.dll</HintPath>
</Reference>
<Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\lib\Owin.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Data.DataSetExtensions" />
@@ -173,6 +208,12 @@
<Compile Include="Forms_Basic\frm_batch.vb">
<SubType>Form</SubType>
</Compile>
<Compile Include="Forms_Basic\Frm_WebManual.Designer.vb">
<DependentUpon>Frm_WebManual.vb</DependentUpon>
</Compile>
<Compile Include="Forms_Basic\Frm_WebManual.vb">
<SubType>Form</SubType>
</Compile>
<Compile Include="Forms_Basic\fSelectWeatherGroup.Designer.vb">
<DependentUpon>fSelectWeatherGroup.vb</DependentUpon>
</Compile>
@@ -483,6 +524,9 @@
<Compile Include="Forms_Basic\Frm_FileInfo.vb">
<SubType>Form</SubType>
</Compile>
<Compile Include="WebServer\Example_WebServer_Usage.vb" />
<Compile Include="WebServer\Startup.vb" />
<Compile Include="WebServer\StaticFileServer.vb" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Forms_Basic\Frm_DisplayGubun.resx">
@@ -497,6 +541,9 @@
<EmbeddedResource Include="Forms_Basic\frm_batch.resx">
<DependentUpon>frm_batch.vb</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms_Basic\Frm_WebManual.resx">
<DependentUpon>Frm_WebManual.vb</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms_Basic\Frm_Work.resx">
<DependentUpon>Frm_Work.vb</DependentUpon>
<SubType>Designer</SubType>
@@ -702,6 +749,7 @@
</None>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<None Include="Resources\user_24.png" />
</ItemGroup>
<ItemGroup>
@@ -789,6 +837,7 @@
<Content Include="icon5.ico" />
<None Include="Resources\select_by_difference.png" />
<None Include="Resources\page_copy.png" />
<Content Include="WebServer\INSTALL.txt" />
<Content Include="단축키.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -807,6 +856,7 @@
<Content Include="Forms_Input\ReadMe.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<None Include="WebServer\README.md" />
<None Include="방위2.png" />
<None Include="방위.png" />
<None Include="방위.jpg" />
@@ -857,6 +907,13 @@
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildBinPath)\Microsoft.VisualBasic.targets" />
<Import Project="..\packages\Microsoft.Web.WebView2.1.0.3537.50\build\Microsoft.Web.WebView2.targets" Condition="Exists('..\packages\Microsoft.Web.WebView2.1.0.3537.50\build\Microsoft.Web.WebView2.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>이 프로젝트는 이 컴퓨터에 없는 NuGet 패키지를 참조합니다. 해당 패키지를 다운로드하려면 NuGet 패키지 복원을 사용하십시오. 자세한 내용은 http://go.microsoft.com/fwlink/?LinkID=322105를 참조하십시오. 누락된 파일은 {0}입니다.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Microsoft.Web.WebView2.1.0.3537.50\build\Microsoft.Web.WebView2.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Web.WebView2.1.0.3537.50\build\Microsoft.Web.WebView2.targets'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">

View File

@@ -0,0 +1,56 @@
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class Frm_WebManual
Inherits System.Windows.Forms.Form
'Form은 Dispose를 재정의하여 구성 요소 목록을 정리합니다.
<System.Diagnostics.DebuggerNonUserCode()> _
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
'Windows Form 디자이너에 필요합니다.
Private components As System.ComponentModel.IContainer
'참고: 다음 프로시저는 Windows Form 디자이너에 필요합니다.
'수정하려면 Windows Form 디자이너를 사용하십시오.
'코드 편집기에서는 수정하지 마세요.
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
Me.WebView21 = New Microsoft.Web.WebView2.WinForms.WebView2()
CType(Me.WebView21, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SuspendLayout()
'
'WebView21
'
Me.WebView21.AllowExternalDrop = True
Me.WebView21.CreationProperties = Nothing
Me.WebView21.DefaultBackgroundColor = System.Drawing.Color.White
Me.WebView21.Dock = System.Windows.Forms.DockStyle.Fill
Me.WebView21.Location = New System.Drawing.Point(0, 0)
Me.WebView21.Name = "WebView21"
Me.WebView21.Size = New System.Drawing.Size(1350, 700)
Me.WebView21.TabIndex = 0
Me.WebView21.ZoomFactor = 1.0R
'
'Frm_WebManual
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(7.0!, 12.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(1350, 700)
Me.Controls.Add(Me.WebView21)
Me.Name = "Frm_WebManual"
Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen
Me.Text = "사용자 매뉴얼"
CType(Me.WebView21, System.ComponentModel.ISupportInitialize).EndInit()
Me.ResumeLayout(False)
End Sub
Friend WithEvents WebView21 As Microsoft.Web.WebView2.WinForms.WebView2
End Class

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -0,0 +1,65 @@
Imports System.IO
Imports System.Threading.Tasks
Imports Microsoft.Web.WebView2.Core
Public Class Frm_WebManual
Public Sub Navigate(url As String)
Try
If WebView21 IsNot Nothing AndAlso WebView21.CoreWebView2 IsNot Nothing Then
WebView21.CoreWebView2.Navigate(url)
End If
Catch ex As Exception
MessageBox.Show("웹페이지 이동 중 오류가 발생했습니다: " & ex.Message,
"오류", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
Private Async Sub Frm_WebManual_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Try
' WebView2 초기화 (Runtime이 없으면 자동 다운로드)
Await InitializeWebView2Async()
' 로컬 웹서버 페이지 로드
If WebView21.CoreWebView2 IsNot Nothing Then
WebView21.CoreWebView2.Navigate("http://localhost:58123/")
End If
Catch ex As Exception
MessageBox.Show("웹페이지 로드 중 오류가 발생했습니다: " & ex.Message,
"오류", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
Private Async Function InitializeWebView2Async() As Task
Try
' Fixed Version 경로 설정
Dim fixedVersionPath = Path.Combine(Application.StartupPath, "WebView2Runtime")
Dim userDataFolder = Path.Combine(Application.StartupPath, "WebView2Data")
' Fixed Version이 있는지 확인
If Directory.Exists(fixedVersionPath) Then
' Fixed Version 사용
Dim env = Await CoreWebView2Environment.CreateAsync(fixedVersionPath, userDataFolder)
Await WebView21.EnsureCoreWebView2Async(env)
Else
' 시스템에 설치된 Runtime 사용 (폴백)
Await WebView21.EnsureCoreWebView2Async(Nothing)
End If
Catch ex As Exception
' WebView2 Runtime을 찾을 수 없는 경우
MessageBox.Show(
"WebView2 구성 요소를 찾을 수 없습니다." & vbCrLf & vbCrLf &
"프로그램 설치가 올바르지 않을 수 있습니다." & vbCrLf &
"관리자에게 문의하시기 바랍니다.",
"오류",
MessageBoxButtons.OK,
MessageBoxIcon.Error)
Me.Close()
End Try
End Function
End Class

View File

@@ -109,6 +109,7 @@ Partial Class MdiMain
Me.비교데이터백업ToolStripMenuItem = New System.Windows.Forms.ToolStripMenuItem()
Me.데이터비교ToolStripMenuItem = New System.Windows.Forms.ToolStripMenuItem()
Me.순실체적ToolStripMenuItem = New System.Windows.Forms.ToolStripMenuItem()
Me.ManualToolStripMenuItem = New System.Windows.Forms.ToolStripMenuItem()
Me.StatusStrip1.SuspendLayout()
Me.MenuStrip1.SuspendLayout()
Me.ContextMenuStrip1.SuspendLayout()
@@ -178,7 +179,7 @@ Partial Class MdiMain
'MenuStrip1
'
Me.MenuStrip1.Font = New System.Drawing.Font("돋움", 9.0!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(129, Byte))
Me.MenuStrip1.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.ReportToolStripMenuItem, Me.건물개요ToolStripMenuItem, Me.환경설정ToolStripMenuItem, Me.bt_계산결과, Me.결과그래프ToolStripMenuItem, Me.정보ToolStripMenuItem1, Me.bt_etc, Me.WindowsMenu, Me.btcustomprofile})
Me.MenuStrip1.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.ReportToolStripMenuItem, Me.건물개요ToolStripMenuItem, Me.환경설정ToolStripMenuItem, Me.bt_계산결과, Me.결과그래프ToolStripMenuItem, Me.정보ToolStripMenuItem1, Me.bt_etc, Me.WindowsMenu, Me.btcustomprofile, Me.ManualToolStripMenuItem})
Me.MenuStrip1.Location = New System.Drawing.Point(0, 0)
Me.MenuStrip1.MdiWindowListItem = Me.WindowsMenu
Me.MenuStrip1.Name = "MenuStrip1"
@@ -696,6 +697,13 @@ Partial Class MdiMain
Me.순실체적ToolStripMenuItem.Size = New System.Drawing.Size(170, 22)
Me.순실체적ToolStripMenuItem.Text = "3.순실체적"
'
'ManualToolStripMenuItem
'
Me.ManualToolStripMenuItem.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right
Me.ManualToolStripMenuItem.Name = "ManualToolStripMenuItem"
Me.ManualToolStripMenuItem.Size = New System.Drawing.Size(59, 20)
Me.ManualToolStripMenuItem.Text = "Manual"
'
'MdiMain
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(7.0!, 12.0!)
@@ -821,5 +829,5 @@ Partial Class MdiMain
Friend WithEvents BatchUpdateProfileToolStripMenuItem As System.Windows.Forms.ToolStripMenuItem
Friend WithEvents btcustomprofile As System.Windows.Forms.ToolStripMenuItem
Friend WithEvents btMacro2 As System.Windows.Forms.ToolStripMenuItem
Friend WithEvents ManualToolStripMenuItem As ToolStripMenuItem
End Class

View File

@@ -127,31 +127,6 @@
<value>235, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="bt_filesave.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
R0lGODlhEAAQAIQAAJXD9Iasxm6MqnSn2lZtjVaRyEpXbYu767TX/2KZztvr/4Gy5KrT/3ut32+gzlFh
e+r0/0RNX9/u/9Ln+8Xg//n8/4e36CkxQz9GVkSCvKjL35/N/Je91K7T5bDS4////yH/C05FVFNDQVBF
Mi4wAwEBAAAh+QQAAAAAACwAAAAAEAAQAAAIuQA/CBxIsKDACRwScggQwIGAhwIICBDYQcEEgwg+bNjw
QKCHCQgkQBgpQcKBCg0AEBCoAaRIkhIsVBigUiAHCgwkKNjJU8GAAx0/3NwIAMABCwsaDHCwIGgAChuK
HjiQdMDSAQYEPpWKtKqDBA6yfgiAwGhXpUsTJIgg0AGCo0nRfi1QgO0HAQyQNpCrtkAGDAIFbKi69GsC
un8FEohqdEFavxkyXAhMoPKDBwYMRIiAAcOFoAZDCwwIADs=
</value>
</data>
<data name="bt_데이터관리.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29m
dHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAIcSURBVDhPjVPJqhpBFO1VFvmAt0g+Iav3E9nlM7LM
ZyS7rLoc2wFbbGi7bRBxJYojIk6o+BTFCQVHTKsIL1HfDaeIIv0IScGB4tY9Q93qFohIsCKbzX6LxWIz
WZZfAOxRs/YBrwqRSORBVdVfZFmoKYryztp/7ziSZfkiyzJFo1F6enqiy+VC5/OZWq0Wr+EMPei9JuIC
qqo+37uNx2PSdZ0ajQaHpmm8dr/+cATBMAy/YRjUbre5I1AsFikej1MwGOTAHjWkOZ1O1Gw2CRyv16sI
uq6fut0uVatVqtVq3BHu1nVNVKlUKJPJUCqVIkmSToKmaebhcKDlckmDwYCGwyFls1nq9Xq3RNjncjnq
dDqUSCQ46vU6ud1uUwiHw1xgt9vRdrulyWTC45bL5dsM4IohgphOpzmQ1uVymRggFzBNkzabDa1WK5rN
ZtwVV8vn85yIyEiGJBCAgdPpNAVFUX4ej0fa7/c0n885eTQaUb/f50+JZhCvSCaTXKxUKpHNZnsWQqFQ
AoXpdMqvARHMAgkggDMMDUASOENUURRijGWEYDD4Rpblz4FAoI+mxWJB6/WaDxMC16GBiNngm2CMjRlj
X0RRfHv7JP1+/4PP5/vq9Xp/FAoFLgIxDBBPHIvFEPnAGPsuiuL7v/4LHo/ngyRJIbfb/QIi7hwIBEDW
GWOP1v5XAlc4nc6PDocjZbfb8zab7ZP1/J8C/4vfXG8tHKjVxdQAAAAASUVORK5CYII=
</value>
</data>
<data name="ReportToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
R0lGODlhEAAQAIQfAOvGUf7ztuvPMf/78/fkl/Pbg+u8Rvjqteu2Pf3zxPz36Pz0z+vTmPzurPvuw/np
@@ -248,6 +223,31 @@
b6AQ75sCVnsVfDHIceuzCVkfYyw4KQ2Mqa8QnWkVq15THp6eXNzdMla0d1nuyiIoVKNTHJMGrFWX2Jhu
IjLRwPp4HeGRGrEaFNQEhh/it1TSde9IOmC327HZbAyVX+Bd6TnxUKYHZ+hVnsKQfwL9/eNoc4/SKT9M
h+wQKpVKnLQN/mV+AQV66PCS6TFTAAAAAElFTkSuQmCC
</value>
</data>
<data name="bt_filesave.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
R0lGODlhEAAQAIQAAJXD9Iasxm6MqnSn2lZtjVaRyEpXbYu767TX/2KZztvr/4Gy5KrT/3ut32+gzlFh
e+r0/0RNX9/u/9Ln+8Xg//n8/4e36CkxQz9GVkSCvKjL35/N/Je91K7T5bDS4////yH/C05FVFNDQVBF
Mi4wAwEBAAAh+QQAAAAAACwAAAAAEAAQAAAIuQA/CBxIsKDACRwScggQwIGAhwIICBDYQcEEgwg+bNjw
QKCHCQgkQBgpQcKBCg0AEBCoAaRIkhIsVBigUiAHCgwkKNjJU8GAAx0/3NwIAMABCwsaDHCwIGgAChuK
HjiQdMDSAQYEPpWKtKqDBA6yfgiAwGhXpUsTJIgg0AGCo0nRfi1QgO0HAQyQNpCrtkAGDAIFbKi69GsC
un8FEohqdEFavxkyXAhMoPKDBwYMRIiAAcOFoAZDCwwIADs=
</value>
</data>
<data name="bt_데이터관리.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29m
dHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAIcSURBVDhPjVPJqhpBFO1VFvmAt0g+Iav3E9nlM7LM
ZyS7rLoc2wFbbGi7bRBxJYojIk6o+BTFCQVHTKsIL1HfDaeIIv0IScGB4tY9Q93qFohIsCKbzX6LxWIz
WZZfAOxRs/YBrwqRSORBVdVfZFmoKYryztp/7ziSZfkiyzJFo1F6enqiy+VC5/OZWq0Wr+EMPei9JuIC
qqo+37uNx2PSdZ0ajQaHpmm8dr/+cATBMAy/YRjUbre5I1AsFikej1MwGOTAHjWkOZ1O1Gw2CRyv16sI
uq6fut0uVatVqtVq3BHu1nVNVKlUKJPJUCqVIkmSToKmaebhcKDlckmDwYCGwyFls1nq9Xq3RNjncjnq
dDqUSCQ46vU6ud1uUwiHw1xgt9vRdrulyWTC45bL5dsM4IohgphOpzmQ1uVymRggFzBNkzabDa1WK5rN
ZtwVV8vn85yIyEiGJBCAgdPpNAVFUX4ej0fa7/c0n885eTQaUb/f50+JZhCvSCaTXKxUKpHNZnsWQqFQ
AoXpdMqvARHMAgkggDMMDUASOENUURRijGWEYDD4Rpblz4FAoI+mxWJB6/WaDxMC16GBiNngm2CMjRlj
X0RRfHv7JP1+/4PP5/vq9Xp/FAoFLgIxDBBPHIvFEPnAGPsuiuL7v/4LHo/ngyRJIbfb/QIi7hwIBEDW
GWOP1v5XAlc4nc6PDocjZbfb8zab7ZP1/J8C/4vfXG8tHKjVxdQAAAAASUVORK5CYII=
</value>
</data>
<metadata name="ContextMenuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
@@ -335,10 +335,10 @@
P/V955x7T1/AksaeqnEVX9W/zu3bl3vv9+v/953Tt7HZtmM7tmM7tmM7tmM7bDabvWXy++kti3+f1Ljw
A1JGm/fvks97/5aU1TT/N29S2iXnX1rP+WcRQTkDBaFFD1bSznyFP1Zx+cMvQnLv3NhRW/u+9Trf2tiV
e2t50P0aL14D95yv0fzFy6+lsw9f4tLoa6Q2OHzBOQOR1ut8a+NQWc/ahYfLuDW0huyLC0i/8C5a5DGD
tluFTvc9R3DWndWglJ5/tF7rWxnBWZ+vlnZ7RQIqsVaZlJak3/v6a3msefwC7Pa09f0FAzet1/pWhgLA
SXBSi0hvJVkAcLL++zNaSQrColDrAgodS4g98dWrvdl9pXvyen8QkO/4q29Snxb3f2DN663jYOngSkmX
SEpBoESMT1kmKZJV2xKGZn9+TwFrXUD7oxew25PWrY3ym1JQdn/vzoyuH1rze2MoACJ5LUH5iaraVgA4
aZWsdIM43v/vy68tYWrBB88qcHN6/RtVtwuw24+u78nq67bm98YIIwC3VFK6rUUp+H/yAojpAn2fVg7a
tluFTvc9R3DWndWglJ5/tF7rWxnBWZ+vlnZ7RQIqsVaZlJak3/v6a3msefwC7Paj6/sLBm5ar/WtDAWA
k+CkFpHeSrIA4GT992e0khSERaHWBRQ6lhB74qtXe7P7Svfk9f4gIN/xV9+kPi3u/8Ca11vHwdLBlZIu
kZSCQIkYn7JMUiSrtiUMzf78ngLWuoD2Ry9gtyeuWxvlN6Wg7P7enRldP7Tm98ZQAETyWoLyE1W1rQBw
0ipZ6QZxvP/fl19bwtSCD55V4Ob0+jeqbhdgt6eu78nq67bm98YIIwC3VFK6rUUp+H/yAojpAn2fVg7a
aP69Ki3t/LLcNp5LOs+AvfHvTS0ir30RrcOvsCenf9Fud3zHmuOWsWNH7fvUA4pvepF2wWs5sboh/aI6
EB2Q9T0TiH4uQzTbaMduBnrD36h9F633Q/sWkH15CcFHe5f2ZXR9z5rnlvFju+M7BKDophdJjW7NxkKZ
8mbpouLGpeSN+Ce1yTFbJWIc84ZzvY3o/uQ59uQOLL4TgE8/7f8grKRnrfCGF/F100hsdImktZvI1G9G
@@ -382,7 +382,7 @@
TW2Z55koq20ZAfljNPUlWXP2i/2Fd3md/8sYB35p72QQ+Y5ZftJz8MRTxNS4WXZNDKLWzTODAUQvEVkm
olS0MmkQELhUjBLxarOJbKDa+oKnVCoP2S8UEHPlaU6pBCmh0SNeX1xCUPaAd2929z9Yc/YLBeDD6Kv4
RbSDvxPkdswhvPwJIk85EV3tQky125CdRj8YCogAIUYqFQGEoRgwBAizRFTP8G+gmzZP5QrdHdQ4tfVF
QtMsAyAYdnvyelB2X5M13w0hALjw88gr+DDqCjLbaNU3hdAyegrkEqpyCRA8mjBYBgxygwnjiAGB3OHZ
QtMsAyAYdnvSelB2X5M13w0hALjw88gr+DDqCjLbaNU3hdAyegrkEqpyCRA8mjBYBgxygwnjiAGB3OHZ
4Iw46Qx9WqWZRG+cqldscIbflCocQbaPrZ3hY6lMQjL75vZkdv2LNd8NQQAKOl342eEO/D6lG9mXFxFe
Po6Dnz1DVKULUVUuRFXO8MgglNgZLsTUkDQQ3CdoFCUSq7nDcIXmCNEztKlV9QzpCKNnWGYRsQwXzZMg
xNfT9WcYBj2FDsruH7TmumkoADsi2vmZf3ydCwdK6THYDCceSRBY9FpuW0EYzpDlYi0PJcMZqnlaXLHp
@@ -392,11 +392,11 @@
OyDzdrQ1zy3jQNFdnPtiGc4FH8LLRhF8bJgh7Ct+jNDj4xY9YYWVKU0gvGxCjOWkpwg/YYr6yCFSxSQO
VTxDRMWk0MkpHCadcgqddiKSVOlEVCUtvclVNE4jpmoGMdUzAuCZGVlWLh6pv0SenkJY+Thi69zcRAOz
+730f0nWPLeM0JIH/MCAfggNKRxG8LEhTfRaE71vEf2Nn4pGEFI4IkapfVYVP2bt18b9JUqjOFA6igM8
joltqdDjY/4qG0NY2TgiKp6xMyLt8euBWf3V1hy3jOJ+fHDw+Jf8wCC5cZY/QbrhdwFglTV5q3QABghK
joltqdDjY/4qG0NY2TgiKp6xMyLtceuBWf3V1hy3jOJ+fHDw+Jf8wCC5cZY/QbrhdwFglTV5q3QABghK
3AKBQShpEFgaBFqvUOlQiQTb777ck9H1I2ueW0ae48WHIfl3+WFhZO3cn7Uiql3YlWn+NvhWcbi8v+5I
jcO3K60HQXkPsL/oEQ4UD31zKhlCaPEQQmlUoh9i1Fg6zApjjSDs+OYKPz6Cg2VKjxFWMoRA++3X//FR
SqLNZvsnm832dv8u98N//tFP/+1/Ptlps9n+80+o/9pk31Z6l2PfRpT8dmzHdmzHdmzHdmzHdrwp/h8w
TliMzfocqQAAAABJRU5ErkJggg==
SqLNZvsnm832dv8u98N//tFP/+1/Ptlps9n+80+o/9pk31Z6l2PfRpT8dmzHdmzHdmzHdmzHdrwp/h9d
k1iG/rMj4QAAAABJRU5ErkJggg==
</value>
</data>
<data name="ToolStripButton3.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">

View File

@@ -1,4 +1,5 @@
Imports System.IO
Imports Eco2Ar.WebServer
Public Class MdiMain
@@ -20,9 +21,17 @@ Public Class MdiMain
'''현재열려있는폼의 이름을 변경한다.
Public OpenedForm As E_MenuIdx = E_MenuIdx.NONE
Private webServer As StaticFileServer
Private Sub MdiMain_FormClosed(sender As Object, e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
pLog.Add("FormClosed", True)
' 웹 서버 정리
If webServer IsNot Nothing Then
webServer.Stop()
webServer.Dispose()
End If
End Sub
Private Sub MdiMain_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
@@ -243,6 +252,23 @@ Public Class MdiMain
pLog.Add("Program Start")
Try
' 웹 서버 초기화 및 시작
Dim wwwPath = Path.Combine(Application.StartupPath, "wwwroot")
webServer = New StaticFileServer(wwwPath, 58123)
webServer.Start()
'If System.Diagnostics.Debugger.IsAttached Then
' webServer.OpenInBrowser()
'End If
Catch ex As Exception
' 웹 서버 시작 실패해도 프로그램은 계속 실행
Debug.WriteLine("웹 서버 시작 실패: " & ex.Message)
End Try
' WebView2 Fixed Version 체크
CheckWebView2Runtime()
If Me.bt_etc.Visible = False AndAlso System.Diagnostics.Debugger.IsAttached Then
MsgBox("debugmode import on")
Me.bt_etc.Visible = True
@@ -778,14 +804,14 @@ Public Class MdiMain
If Prj.UIVersion <> CurrentUIVersion() Then
If CInt(Prj.UIVersion.Substring(0, 4)) >= 2016 Then
MsgBox("해당 파일은 현재 프로그램과 동일한 버젼에서 생성된 파일이 아닙니다" + vbCrLf + vbCrLf + _
"파일 Version : " + Prj.UIVersion + vbCrLf + _
"현재 Version : " + CurrentUIVersion() + vbCrLf + vbCrLf + _
MsgBox("해당 파일은 현재 프로그램과 동일한 버젼에서 생성된 파일이 아닙니다" + vbCrLf + vbCrLf +
"파일 Version : " + Prj.UIVersion + vbCrLf +
"현재 Version : " + CurrentUIVersion() + vbCrLf + vbCrLf +
"파일을 생성한 버젼과 결과 혹은 화면이 일치하지 않을 수 있습니다", MsgBoxStyle.Information, "버전확인")
Else
MsgBox("해당 파일은 현재 프로그램과 동일한 버젼에서 생성된 파일이 아닙니다" + vbCrLf + vbCrLf + _
"파일 Version : " + vbCrLf + _
"현재 Version : " + CurrentUIVersion() + vbCrLf + vbCrLf + _
MsgBox("해당 파일은 현재 프로그램과 동일한 버젼에서 생성된 파일이 아닙니다" + vbCrLf + vbCrLf +
"파일 Version : " + vbCrLf +
"현재 Version : " + CurrentUIVersion() + vbCrLf + vbCrLf +
"파일을 생성한 버젼과 결과 혹은 화면이 일치하지 않을 수 있습니다", MsgBoxStyle.Information, "버전확인")
End If
@@ -976,7 +1002,7 @@ Public Class MdiMain
Dim oldfi As New System.IO.FileInfo(FileName)
Dim newfi As New System.IO.FileInfo(bakdi.FullName + "\open_" + oldfi.Name)
If newfi.Exists Then
If MsgBox("백업된 파일이 존재합니다." + vbCrLf + vbCrLf + _
If MsgBox("백업된 파일이 존재합니다." + vbCrLf + vbCrLf +
"백업일자 : " + newfi.CreationTime.ToShortDateString + " " + newfi.CreationTime.ToShortTimeString + vbCrLf + "백업된 파일을 불러오시겠습니까?", MsgBoxStyle.YesNo Or MsgBoxStyle.Question, "확인") = MsgBoxResult.Yes Then
Open_File(newfi.FullName)
End If
@@ -1073,7 +1099,7 @@ Public Class MdiMain
DSET1.tbl_zone.Rows(i - 1)("순실체적") = CSng(면적) * CSng(천장고)
End If
End If
If DSET1.tbl_zone.Rows(i - 1).RowState = DataRowState.Deleted OrElse _
If DSET1.tbl_zone.Rows(i - 1).RowState = DataRowState.Deleted OrElse
DSET1.tbl_zone.Rows(i - 1).RowState = DataRowState.Detached Then
Continue For
End If
@@ -1087,7 +1113,7 @@ Public Class MdiMain
If Not DSET2 Is Nothing Then
For i As Integer = 1 To DSET2.tbl_zone.Rows.Count
If DSET2.tbl_zone.Rows(i - 1).RowState = DataRowState.Deleted OrElse _
If DSET2.tbl_zone.Rows(i - 1).RowState = DataRowState.Deleted OrElse
DSET2.tbl_zone.Rows(i - 1).RowState = DataRowState.Detached Then
Continue For
End If
@@ -1102,7 +1128,7 @@ Public Class MdiMain
'//입력면
If Not DSET1 Is Nothing Then
For i As Integer = 1 To DSET1.tbl_myoun.Rows.Count
If DSET1.tbl_myoun.Rows(i - 1).RowState = DataRowState.Deleted OrElse _
If DSET1.tbl_myoun.Rows(i - 1).RowState = DataRowState.Deleted OrElse
DSET1.tbl_myoun.Rows(i - 1).RowState = DataRowState.Detached Then
Continue For
End If
@@ -1121,7 +1147,7 @@ Public Class MdiMain
If Not DSET2 Is Nothing Then
For i As Integer = 1 To DSET2.tbl_myoun.Rows.Count
If DSET2.tbl_myoun.Rows(i - 1).RowState = DataRowState.Deleted OrElse _
If DSET2.tbl_myoun.Rows(i - 1).RowState = DataRowState.Deleted OrElse
DSET2.tbl_myoun.Rows(i - 1).RowState = DataRowState.Detached Then
Continue For
End If
@@ -2009,8 +2035,8 @@ Public Class MdiMain
'MsgBox(autoselecttagname)
'//추가할메뉴선택
Dim Menus() As String = New String() {"입력존", "공조처리", _
"난방기기", "난방공급시스템", "난방분배시스템", "냉방기기", _
Dim Menus() As String = New String() {"입력존", "공조처리",
"난방기기", "난방공급시스템", "난방분배시스템", "냉방기기",
"냉방분배시스템", "신재생및열병합", "열관류율", "월별에너지사용량"}
For Each m As String In Menus
@@ -2684,8 +2710,8 @@ ENDSTAT: '//오류발생시 강제종료를 위한 분기문
Private Sub ToolStripMenuItem13_Click(sender As System.Object, e As System.EventArgs) Handles ToolStripMenuItem13.Click
If MsgBox("정말로 서버의 데이터를 수정하시겠습니까?" & vbCrLf & _
"서버의 기상데이터가 삭제되고 현재데이터가 씌여집니다." & vbCrLf & _
If MsgBox("정말로 서버의 데이터를 수정하시겠습니까?" & vbCrLf &
"서버의 기상데이터가 삭제되고 현재데이터가 씌여집니다." & vbCrLf &
"이작업은 되돌릴 수없습니다", MsgBoxStyle.Information Or MsgBoxStyle.OkCancel, "확인") <> MsgBoxResult.Ok Then Return
Dim pass As String = InputBox("암호입력")
@@ -2719,11 +2745,11 @@ ENDSTAT: '//오류발생시 강제종료를 위한 분기문
Rcnt += Ta2.Insert(Dr.pcode, Dr.code, Dr.설명, Dr.최대부하, Dr.m01, Dr.m02, Dr.m03, Dr.m04, Dr.m05, Dr.m06, Dr.m07, Dr.m08, Dr.m09, Dr.m10, Dr.m11, Dr.m12)
Next
For Each Dr As DS.weather_supdoRow In DSET1.weather_supdo.Rows
Rcnt += Ta3.Insert(Dr.pcode, Dr.code, Dr.설명, Dr.t01, Dr.t02, Dr.t03, Dr.t04, Dr.t05, Dr.t06, Dr.t07, Dr.t08, Dr.t09, Dr.t10, _
Rcnt += Ta3.Insert(Dr.pcode, Dr.code, Dr.설명, Dr.t01, Dr.t02, Dr.t03, Dr.t04, Dr.t05, Dr.t06, Dr.t07, Dr.t08, Dr.t09, Dr.t10,
Dr.t11, Dr.t12, Dr.t13, Dr.t14, Dr.t15, Dr.t16, Dr.t17, Dr.t18, Dr.t19, Dr.t20, Dr.t21, Dr.t22, Dr.t23, Dr.t24)
Next
For Each Dr As DS.weather_tempRow In DSET1.weather_temp.Rows
Rcnt += Ta4.Insert(Dr.pcode, Dr.code, Dr.설명, Dr.t01, Dr.t02, Dr.t03, Dr.t04, Dr.t05, Dr.t06, Dr.t07, Dr.t08, Dr.t09, Dr.t10, _
Rcnt += Ta4.Insert(Dr.pcode, Dr.code, Dr.설명, Dr.t01, Dr.t02, Dr.t03, Dr.t04, Dr.t05, Dr.t06, Dr.t07, Dr.t08, Dr.t09, Dr.t10,
Dr.t11, Dr.t12, Dr.t13, Dr.t14, Dr.t15, Dr.t16, Dr.t17, Dr.t18, Dr.t19, Dr.t20, Dr.t21, Dr.t22, Dr.t23, Dr.t24)
Next
MsgBox("업데이트완료", MsgBoxStyle.Information, "확인")
@@ -3876,8 +3902,8 @@ ENDSTAT: '//오류발생시 강제종료를 위한 분기문
End If
content.Append(vbTab + drm.설명 + vbTab + drm.건축부위방식 + vbTab + _
drm.건축부위면적 + vbTab + _
content.Append(vbTab + drm.설명 + vbTab + drm.건축부위방식 + vbTab +
drm.건축부위면적 + vbTab +
열관류율 + vbTab + drm.방위)
Next
content.AppendLine()
@@ -3961,4 +3987,35 @@ ENDSTAT: '//오류발생시 강제종료를 위한 분기문
Dim f As New Frm_Macro2
f.Show()
End Sub
Dim frmManual As Frm_WebManual = Nothing
Private Sub ManualToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ManualToolStripMenuItem.Click
If frmManual Is Nothing OrElse frmManual.IsDisposed Then
frmManual = New Frm_WebManual()
frmManual.Show()
End If
If frmManual.WindowState = FormWindowState.Minimized Then
frmManual.WindowState = FormWindowState.Normal
End If
frmManual.Activate()
End Sub
''' <summary>
''' WebView2 Fixed Version 런타임 체크
''' </summary>
Private Sub CheckWebView2Runtime()
Try
Dim fixedVersionPath = Path.Combine(Application.StartupPath, "WebView2Runtime")
' Fixed Version 폴더가 없으면 경고 (하지만 계속 실행)
If Not Directory.Exists(fixedVersionPath) Then
Debug.WriteLine("경고: WebView2 Fixed Version을 찾을 수 없습니다. Manual 기능이 제한될 수 있습니다.")
' 사용자에게는 Manual 메뉴를 클릭할 때만 알림
End If
Catch ex As Exception
Debug.WriteLine("WebView2 체크 중 오류: " & ex.Message)
End Try
End Sub
End Class

View File

@@ -0,0 +1,244 @@
' OWIN 정적 파일 호스팅 서버 사용 예제
'
' 이 파일은 StaticFileServer를 사용하는 방법을 보여줍니다.
' 실제 사용 시에는 MdiMain.vb 또는 필요한 폼에서 사용하세요.
Imports Eco2Ar.WebServer
Imports System.IO
Namespace Examples
''' <summary>
''' 웹 서버 사용 예제
''' </summary>
Public Class WebServerExample
Private server As StaticFileServer
''' <summary>
''' 예제 1: 기본 사용법
''' </summary>
Public Sub Example1_BasicUsage()
' 1. 정적 파일을 서빙할 디렉토리 경로 설정
Dim wwwrootPath As String = Path.Combine(Application.StartupPath, "wwwroot")
' 2. 서버 인스턴스 생성 (포트 58123 사용)
server = New StaticFileServer(wwwrootPath, 58123)
' 3. 서버 시작
server.Start()
' 4. 브라우저에서 열기 (선택사항)
' server.OpenInBrowser()
MsgBox("웹 서버가 시작되었습니다." & vbCrLf & _
"URL: " & server.BaseUrl & vbCrLf & _
"루트 경로: " & server.RootPath, _
MsgBoxStyle.Information, "웹 서버")
End Sub
''' <summary>
''' 예제 2: MdiMain에서 사용 (프로그램 시작 시 서버 시작)
''' </summary>
Public Sub Example2_IntegrationWithMdiMain()
' MdiMain.vb의 MdiMain_Load 이벤트에 추가:
'
' Private webServer As StaticFileServer
'
' Private Sub MdiMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' ' ... 기존 코드 ...
'
' Try
' ' 웹 서버 초기화 및 시작
' Dim wwwPath = Path.Combine(Application.StartupPath, "wwwroot")
' webServer = New StaticFileServer(wwwPath)
' webServer.Start()
' Catch ex As Exception
' ' 웹 서버 시작 실패해도 프로그램은 계속 실행
' Debug.WriteLine("웹 서버 시작 실패: " & ex.Message)
' End Try
' End Sub
'
' Private Sub MdiMain_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
' ' ... 기존 코드 ...
'
' ' 웹 서버 정리
' If webServer IsNot Nothing Then
' webServer.Stop()
' webServer.Dispose()
' End If
' End Sub
End Sub
''' <summary>
''' 예제 3: 특정 파일 브라우저에서 열기
''' </summary>
Public Sub Example3_OpenSpecificFile()
If server Is Nothing OrElse Not server.IsRunning Then
MsgBox("서버가 실행 중이 아닙니다.", MsgBoxStyle.Exclamation, "오류")
Return
End If
' 리포트 HTML 파일 열기
server.OpenFileInBrowser("report.html")
' 또는 URL만 가져오기
Dim reportUrl As String = server.GetFileUrl("reports/2025/report.html")
MsgBox("리포트 URL: " & reportUrl, MsgBoxStyle.Information, "URL")
End Sub
''' <summary>
''' 예제 4: 동적으로 HTML 파일 생성 후 표시
''' </summary>
Public Sub Example4_GenerateAndDisplay()
If server Is Nothing OrElse Not server.IsRunning Then
MsgBox("서버가 실행 중이 아닙니다.", MsgBoxStyle.Exclamation, "오류")
Return
End If
' HTML 파일 생성
Dim htmlContent As String = "<!DOCTYPE html>" & vbCrLf & _
"<html>" & vbCrLf & _
"<head>" & vbCrLf & _
" <meta charset=""utf-8"">" & vbCrLf & _
" <title>ECO2 리포트</title>" & vbCrLf & _
" <style>" & vbCrLf & _
" body { font-family: 'Malgun Gothic', sans-serif; margin: 20px; }" & vbCrLf & _
" h1 { color: #2c3e50; }" & vbCrLf & _
" table { border-collapse: collapse; width: 100%; }" & vbCrLf & _
" th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }" & vbCrLf & _
" th { background-color: #4CAF50; color: white; }" & vbCrLf & _
" </style>" & vbCrLf & _
"</head>" & vbCrLf & _
"<body>" & vbCrLf & _
" <h1>건물 에너지 분석 리포트</h1>" & vbCrLf & _
" <table>" & vbCrLf & _
" <tr><th>항목</th><th>값</th></tr>" & vbCrLf & _
" <tr><td>1차 에너지 소요량</td><td>123.45 kWh/m²·year</td></tr>" & vbCrLf & _
" <tr><td>CO2 배출량</td><td>45.67 kg/m²·year</td></tr>" & vbCrLf & _
" </table>" & vbCrLf & _
"</body>" & vbCrLf & _
"</html>"
' 파일 저장
Dim reportPath As String = Path.Combine(server.RootPath, "report.html")
File.WriteAllText(reportPath, htmlContent, System.Text.Encoding.UTF8)
' 브라우저에서 열기
server.OpenFileInBrowser("report.html")
End Sub
''' <summary>
''' 예제 5: 폼 버튼에서 웹 리포트 생성 및 표시
''' </summary>
Public Sub Example5_ButtonClick()
' 폼의 버튼 클릭 이벤트에 추가:
'
' Private Sub btnShowWebReport_Click(sender As Object, e As EventArgs) Handles btnShowWebReport.Click
' Try
' ' 서버가 실행 중이 아니면 시작
' If webServer Is Nothing OrElse Not webServer.IsRunning Then
' Dim wwwPath = Path.Combine(Application.StartupPath, "wwwroot")
' webServer = New StaticFileServer(wwwPath)
' webServer.Start()
' End If
'
' ' HTML 리포트 생성
' GenerateHtmlReport()
'
' ' 브라우저에서 열기
' webServer.OpenFileInBrowser("report.html")
' Catch ex As Exception
' MsgBox("리포트 생성 실패: " & ex.Message, MsgBoxStyle.Critical, "오류")
' End Try
' End Sub
'
' Private Sub GenerateHtmlReport()
' ' 실제 데이터를 사용하여 HTML 생성
' Dim html As String = BuildHtmlReport(DSET1, DSETR1, Result2)
' Dim path As String = Path.Combine(webServer.RootPath, "report.html")
' File.WriteAllText(path, html, System.Text.Encoding.UTF8)
' End Sub
End Sub
''' <summary>
''' 서버 중지
''' </summary>
Public Sub StopServer()
If server IsNot Nothing Then
server.Stop()
server.Dispose()
server = Nothing
End If
End Sub
End Class
''' <summary>
''' 간단한 HTML 빌더 헬퍼 클래스
''' </summary>
Public Class HtmlReportBuilder
Private html As System.Text.StringBuilder
Public Sub New(title As String)
html = New System.Text.StringBuilder()
html.AppendLine("<!DOCTYPE html>")
html.AppendLine("<html>")
html.AppendLine("<head>")
html.AppendLine(" <meta charset=""utf-8"">")
html.AppendLine(" <title>" & title & "</title>")
html.AppendLine(" <style>")
html.AppendLine(" body { font-family: 'Malgun Gothic', sans-serif; margin: 20px; }")
html.AppendLine(" h1 { color: #2c3e50; }")
html.AppendLine(" h2 { color: #34495e; border-bottom: 2px solid #3498db; padding-bottom: 5px; }")
html.AppendLine(" table { border-collapse: collapse; width: 100%; margin: 20px 0; }")
html.AppendLine(" th, td { border: 1px solid #ddd; padding: 12px; text-align: left; }")
html.AppendLine(" th { background-color: #4CAF50; color: white; }")
html.AppendLine(" tr:nth-child(even) { background-color: #f2f2f2; }")
html.AppendLine(" .section { margin: 30px 0; }")
html.AppendLine(" </style>")
html.AppendLine("</head>")
html.AppendLine("<body>")
html.AppendLine(" <h1>" & title & "</h1>")
End Sub
Public Sub AddSection(sectionTitle As String)
html.AppendLine(" <div class=""section"">")
html.AppendLine(" <h2>" & sectionTitle & "</h2>")
End Sub
Public Sub StartTable(ParamArray headers As String())
html.AppendLine(" <table>")
html.Append(" <tr>")
For Each headerItem As String In headers
html.Append("<th>" & headerItem & "</th>")
Next
html.AppendLine("</tr>")
End Sub
Public Sub AddRow(ParamArray cells As String())
html.Append(" <tr>")
For Each cellItem As String In cells
html.Append("<td>" & cellItem & "</td>")
Next
html.AppendLine("</tr>")
End Sub
Public Sub EndTable()
html.AppendLine(" </table>")
End Sub
Public Sub EndSection()
html.AppendLine(" </div>")
End Sub
Public Function Build() As String
html.AppendLine("</body>")
html.AppendLine("</html>")
Return html.ToString()
End Function
End Class
End Namespace

View File

@@ -0,0 +1,50 @@
=====================================================
OWIN 정적 파일 호스팅 서버 설치 가이드
=====================================================
1. Visual Studio에서 ECO2_2025V1 프로젝트 열기
2. 메뉴: 도구 > NuGet 패키지 관리자 > 패키지 관리자 콘솔
3. 다음 명령들을 순서대로 실행:
Install-Package Owin -Version 1.0
Install-Package Microsoft.Owin -Version 2.1.0
Install-Package Microsoft.Owin.Host.HttpListener -Version 2.1.0
Install-Package Microsoft.Owin.Hosting -Version 2.1.0
Install-Package Microsoft.Owin.StaticFiles -Version 2.1.0
4. 프로젝트 다시 빌드
5. wwwroot 폴더 생성 (없는 경우):
- 출력 디렉토리에 wwwroot 폴더 생성
- Debug: ..\..\..\..\..\eco2\debug_2016\wwwroot
- Release: c:\eco2\debug_2016\wwwroot
6. 기본 index.html 생성 (선택사항):
wwwroot\index.html 파일에 다음 내용 추가:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ECO2 Web Server</title>
</head>
<body>
<h1>ECO2 웹 서버가 정상 작동 중입니다</h1>
</body>
</html>
7. 사용 예제는 Example_WebServer_Usage.vb 참고
8. 관리자 권한 필요 시 (선택사항):
관리자 권한 명령 프롬프트에서:
netsh http add urlacl url=http://+:58123/ user=Everyone
=====================================================
문제 발생 시:
- README.md의 "문제 해결" 섹션 참고
- 패키지 버전이 정확한지 확인 (2.1.0)
- .NET Framework 4.0 타겟이 맞는지 확인
=====================================================

View File

@@ -0,0 +1,126 @@
# Visual Studio 2010 수동 설치 가이드
VS2010에는 NuGet이 기본 내장되어 있지 않으므로, 두 가지 방법 중 선택할 수 있습니다.
## 방법 1: NuGet Extension 설치 (권장)
1. Visual Studio 2010 열기
2. **도구** > **확장 관리자** 클릭
3. **온라인 갤러리** 선택
4. 검색창에 "NuGet Package Manager" 입력
5. **NuGet Package Manager** 찾아서 **다운로드** 클릭
6. 설치 후 Visual Studio 재시작
7. 이후 README.md의 NuGet 설치 방법 따라하기
또는 직접 다운로드:
https://visualstudiogallery.msdn.microsoft.com/27077b70-9dad-4c64-adcf-c7cf6bc9970c
## 방법 2: DLL 수동 추가 (NuGet 없이)
### 1단계: 필요한 DLL 다운로드
다음 NuGet 패키지를 직접 다운로드:
**다운로드 링크:**
- https://www.nuget.org/packages/Owin/1.0
- https://www.nuget.org/packages/Microsoft.Owin/2.1.0
- https://www.nuget.org/packages/Microsoft.Owin.Host.HttpListener/2.1.0
- https://www.nuget.org/packages/Microsoft.Owin.Hosting/2.1.0
- https://www.nuget.org/packages/Microsoft.Owin.StaticFiles/2.1.0
- https://www.nuget.org/packages/Microsoft.Owin.FileSystems/2.1.0
각 페이지에서 "Download package" 클릭
### 2단계: NuGet 패키지에서 DLL 추출
1. 다운로드한 `.nupkg` 파일의 확장자를 `.zip`으로 변경
2. 압축 해제
3. `lib\net40\` 폴더에서 DLL 파일 찾기
4. 프로젝트 폴더에 `lib` 디렉토리 생성
5. 모든 DLL을 `S:\Source\KICT\ECO2\lib\` 폴더에 복사
**필요한 DLL 목록:**
- Owin.dll
- Microsoft.Owin.dll
- Microsoft.Owin.Host.HttpListener.dll
- Microsoft.Owin.Hosting.dll
- Microsoft.Owin.StaticFiles.dll
- Microsoft.Owin.FileSystems.dll
### 3단계: Visual Studio 프로젝트에 참조 추가
1. 솔루션 탐색기에서 **ECO2_2025V1** 프로젝트 선택
2. **참조** 폴더 우클릭 > **참조 추가**
3. **찾아보기** 탭 선택
4. `S:\Source\KICT\ECO2\lib\` 폴더로 이동
5. 위의 모든 DLL 선택하여 추가
### 4단계: app.config에 바인딩 리디렉션 추가
`ArinWarev1\app.config` 파일을 열고 `</configuration>` 바로 앞에 추가:
```xml
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.1.0.0" newVersion="2.1.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
```
## 방법 3: 스크립트로 자동 다운로드 (PowerShell)
프로젝트 루트에서 PowerShell 실행:
```powershell
# lib 폴더 생성
New-Item -ItemType Directory -Force -Path "lib"
# NuGet.exe 다운로드
Invoke-WebRequest -Uri "https://dist.nuget.org/win-x86-commandline/v2.8.6/nuget.exe" -OutFile "nuget.exe"
# 패키지 다운로드
.\nuget.exe install Owin -Version 1.0 -OutputDirectory packages
.\nuget.exe install Microsoft.Owin -Version 2.1.0 -OutputDirectory packages
.\nuget.exe install Microsoft.Owin.Host.HttpListener -Version 2.1.0 -OutputDirectory packages
.\nuget.exe install Microsoft.Owin.Hosting -Version 2.1.0 -OutputDirectory packages
.\nuget.exe install Microsoft.Owin.StaticFiles -Version 2.1.0 -OutputDirectory packages
# DLL 복사
Copy-Item "packages\Owin.1.0\lib\net40\Owin.dll" -Destination "lib\"
Copy-Item "packages\Microsoft.Owin.2.1.0\lib\net40\Microsoft.Owin.dll" -Destination "lib\"
Copy-Item "packages\Microsoft.Owin.Host.HttpListener.2.1.0\lib\net40\Microsoft.Owin.Host.HttpListener.dll" -Destination "lib\"
Copy-Item "packages\Microsoft.Owin.Hosting.2.1.0\lib\net40\Microsoft.Owin.Hosting.dll" -Destination "lib\"
Copy-Item "packages\Microsoft.Owin.StaticFiles.2.1.0\lib\net40\Microsoft.Owin.StaticFiles.dll" -Destination "lib\"
Copy-Item "packages\Microsoft.Owin.FileSystems.2.1.0\lib\net40\Microsoft.Owin.FileSystems.dll" -Destination "lib\"
Write-Host "DLL 다운로드 완료! lib 폴더를 확인하세요."
```
## 방법 4: 미리 준비된 DLL 사용
팀원에게 이미 설치된 환경에서 다음 폴더의 DLL을 복사 받기:
- `packages\Owin.1.0\lib\net40\`
- `packages\Microsoft.Owin.2.1.0\lib\net40\`
- `packages\Microsoft.Owin.Host.HttpListener.2.1.0\lib\net40\`
- `packages\Microsoft.Owin.Hosting.2.1.0\lib\net40\`
- `packages\Microsoft.Owin.StaticFiles.2.1.0\lib\net40\`
- `packages\Microsoft.Owin.FileSystems.2.1.0\lib\net40\`
## 확인 방법
프로젝트를 빌드했을 때 다음 오류가 없으면 성공:
- "형식 또는 네임스페이스 이름 'Owin'을 찾을 수 없습니다"
- "형식 또는 네임스페이스 이름 'Microsoft'을 찾을 수 없습니다"
## 문제 해결
### "Could not load file or assembly" 오류
- app.config에 바인딩 리디렉션 추가했는지 확인
- DLL 버전이 2.1.0이 맞는지 확인 (2.x 버전만 .NET 4.0 호환)
### "파일을 찾을 수 없습니다" 오류
- 출력 디렉토리에 DLL이 복사되는지 확인
- 참조의 "로컬 복사" 속성이 True인지 확인

View File

@@ -0,0 +1,190 @@
# OWIN 정적 파일 호스팅 서버
ECO2 프로젝트에 OWIN 기반 내장 웹 서버를 추가하여 HTML 리포트 및 정적 파일을 호스팅할 수 있습니다.
## 설치 방법
### 1. NuGet 패키지 설치
Visual Studio에서 Package Manager Console을 열고 다음 명령을 실행하세요:
```powershell
# ECO2_2025V1 프로젝트를 기본 프로젝트로 선택 후 실행
Install-Package Microsoft.Owin -Version 2.1.0
Install-Package Microsoft.Owin.Host.HttpListener -Version 2.1.0
Install-Package Microsoft.Owin.Hosting -Version 2.1.0
Install-Package Microsoft.Owin.StaticFiles -Version 2.1.0
Install-Package Owin -Version 1.0
```
또는 패키지 관리자 UI에서 다음 패키지를 검색하여 설치:
- Microsoft.Owin (2.1.0)
- Microsoft.Owin.Host.HttpListener (2.1.0)
- Microsoft.Owin.Hosting (2.1.0)
- Microsoft.Owin.StaticFiles (2.1.0)
- Owin (1.0)
### 2. 프로젝트에 파일 추가
다음 파일들이 `WebServer` 폴더에 추가되었습니다:
- `StaticFileServer.vb` - 메인 서버 클래스
- `Startup.vb` - OWIN 시작 구성
- `Example_WebServer_Usage.vb` - 사용 예제
Visual Studio에서 프로젝트를 다시 로드하면 자동으로 인식됩니다.
## 사용 방법
### 기본 사용법
```vb
Imports Eco2Ar.WebServer
Imports System.IO
' 1. 서버 인스턴스 생성
Dim wwwrootPath As String = Path.Combine(Application.StartupPath, "wwwroot")
Dim server As New StaticFileServer(wwwrootPath, 58123)
' 2. 서버 시작
server.Start()
' 3. 브라우저에서 열기
server.OpenInBrowser()
' 4. 사용 후 서버 중지
server.Stop()
```
### MdiMain에 통합
`MdiMain.vb`에 다음 코드를 추가:
```vb
Public Class MdiMain
Private webServer As StaticFileServer
Private Sub MdiMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' ... 기존 코드 ...
' 웹 서버 시작
Try
Dim wwwPath = Path.Combine(Application.StartupPath, "wwwroot")
webServer = New StaticFileServer(wwwPath)
webServer.Start()
Catch ex As Exception
Debug.WriteLine("웹 서버 시작 실패: " & ex.Message)
End Try
End Sub
Private Sub MdiMain_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
' ... 기존 코드 ...
' 웹 서버 정리
If webServer IsNot Nothing Then
webServer.Stop()
webServer.Dispose()
End If
End Sub
End Class
```
### HTML 리포트 생성 및 표시
```vb
' HTML 리포트 빌더 사용
Dim builder As New HtmlReportBuilder("건물 에너지 분석 리포트")
builder.AddSection("1차 에너지 소요량")
builder.StartTable("항목", "값", "단위")
builder.AddRow("난방", "123.45", "kWh/m²·year")
builder.AddRow("냉방", "67.89", "kWh/m²·year")
builder.EndTable()
builder.EndSection()
Dim html As String = builder.Build()
' 파일 저장
Dim reportPath As String = Path.Combine(webServer.RootPath, "report.html")
File.WriteAllText(reportPath, html, System.Text.Encoding.UTF8)
' 브라우저에서 열기
webServer.OpenFileInBrowser("report.html")
```
## 폴더 구조
```
C:\eco2\debug_2016\
├─ Eco2Ar.exe
└─ wwwroot\ # 정적 파일 루트 디렉토리
├─ index.html # 기본 페이지
├─ report.html # 생성된 리포트
├─ css\
│ └─ styles.css
├─ js\
│ └─ scripts.js
└─ images\
└─ logo.png
```
## 주요 기능
### StaticFileServer 클래스
- **Start()** - 웹 서버 시작
- **Stop()** - 웹 서버 중지
- **OpenInBrowser()** - 기본 브라우저에서 루트 URL 열기
- **OpenFileInBrowser(relativePath)** - 특정 파일을 브라우저에서 열기
- **GetFileUrl(relativePath)** - 파일의 전체 URL 반환
- **IsRunning** - 서버 실행 상태 확인
- **BaseUrl** - 서버 URL (http://localhost:58123)
- **RootPath** - 정적 파일 루트 경로
### HtmlReportBuilder 클래스
간단한 HTML 리포트를 코드로 생성할 수 있는 헬퍼 클래스입니다.
## 포트 정보
- **기본 포트**: 58123 (일반적으로 사용하지 않는 포트)
- 필요 시 생성자에서 다른 포트 지정 가능: `New StaticFileServer(path, 9999)`
## 보안 주의사항
- 이 웹 서버는 **localhost**에서만 접근 가능합니다 (외부 접근 불가)
- 민감한 정보를 wwwroot에 저장하지 마세요
- 필요한 경우에만 서버를 실행하고 사용 후 중지하세요
## 문제 해결
### "포트가 이미 사용 중입니다" 오류
다른 프로그램이 58123 포트를 사용 중일 수 있습니다. 다른 포트를 사용하세요:
```vb
Dim server As New StaticFileServer(wwwrootPath, 58124)
```
### "관리자 권한이 필요합니다" 오류
일부 환경에서는 HTTP.sys 리스너 등록에 관리자 권한이 필요할 수 있습니다.
다음 명령을 관리자 권한 명령 프롬프트에서 실행:
```cmd
netsh http add urlacl url=http://+:58123/ user=Everyone
```
### 패키지 설치 오류
.NET Framework 4.0 타겟 프로젝트이므로 반드시 2.x 버전의 OWIN 패키지를 사용해야 합니다.
최신 버전(4.x)은 .NET Framework 4.5 이상이 필요합니다.
## 예제 코드 위치
더 자세한 사용 예제는 `Example_WebServer_Usage.vb` 파일을 참고하세요.
## 참고 자료
- [OWIN 공식 문서](http://owin.org/)
- [Microsoft.Owin 문서](https://docs.microsoft.com/en-us/aspnet/aspnet/overview/owin-and-katana/)

View File

@@ -0,0 +1,93 @@
' OWIN Startup 클래스
Imports Owin
Imports Microsoft.Owin.StaticFiles
Imports Microsoft.Owin.FileSystems
Namespace WebServer
''' <summary>
''' OWIN 시작 구성 클래스
''' </summary>
Public Class Startup
' 정적 필드로 RootPath 저장
Public Shared RootPath As String = String.Empty
''' <summary>
''' OWIN 미들웨어 구성
''' </summary>
''' <param name="app">App builder</param>
Public Sub Configuration(app As IAppBuilder)
' 루트 경로 확인
If String.IsNullOrEmpty(RootPath) Then
RootPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "wwwroot")
End If
' 정적 파일 서빙을 위한 파일 시스템 설정
Dim fileSystem = New PhysicalFileSystem(RootPath)
' 정적 파일 옵션 설정
Dim options As New FileServerOptions() With {
.RequestPath = New Microsoft.Owin.PathString(""),
.FileSystem = fileSystem,
.EnableDirectoryBrowsing = False
}
' MIME 타입 매핑 추가 (필요한 경우)
options.StaticFileOptions.ContentTypeProvider = New CustomContentTypeProvider()
' 정적 파일 미들웨어 사용
app.UseFileServer(options)
' 기본 핸들러 (루트 경로 접근 시)
app.Run(Function(context)
' 루트 경로 접근 시 index.html로 리다이렉트
If context.Request.Path.Value = "/" OrElse context.Request.Path.Value = "" Then
Dim indexPath = System.IO.Path.Combine(RootPath, "index.html")
If System.IO.File.Exists(indexPath) Then
context.Response.Redirect("/index.html")
Else
context.Response.StatusCode = 200
context.Response.ContentType = "text/html"
Dim tcs = New System.Threading.Tasks.TaskCompletionSource(Of Integer)()
context.Response.WriteAsync("<html><body><h1>ECO2 Web Server</h1><p>서버가 정상적으로 실행 중입니다.</p><p>루트 경로: " & RootPath & "</p></body></html>")
tcs.SetResult(0)
Return tcs.Task
End If
End If
Dim tcs2 = New System.Threading.Tasks.TaskCompletionSource(Of Integer)()
tcs2.SetResult(0)
Return tcs2.Task
End Function)
End Sub
End Class
''' <summary>
''' 커스텀 Content Type Provider
''' </summary>
Public Class CustomContentTypeProvider
Inherits Microsoft.Owin.StaticFiles.ContentTypes.FileExtensionContentTypeProvider
Public Sub New()
MyBase.New()
' 추가 MIME 타입 매핑 (필요한 경우)
' 기본적으로 일반적인 타입들은 이미 포함되어 있음
If Not Me.Mappings.ContainsKey(".json") Then
Me.Mappings.Add(".json", "application/json")
End If
If Not Me.Mappings.ContainsKey(".svg") Then
Me.Mappings.Add(".svg", "image/svg+xml")
End If
If Not Me.Mappings.ContainsKey(".woff") Then
Me.Mappings.Add(".woff", "font/woff")
End If
If Not Me.Mappings.ContainsKey(".woff2") Then
Me.Mappings.Add(".woff2", "font/woff2")
End If
End Sub
End Class
End Namespace

View File

@@ -0,0 +1,175 @@
' OWIN 기반 정적 파일 호스팅 서버
'
' 사용 방법:
' Dim server As New StaticFileServer("C:\wwwroot", 58123)
' server.Start()
' ... 프로그램 실행 ...
' server.Stop()
Imports System
Imports System.IO
Imports Microsoft.Owin.Hosting
Namespace WebServer
''' <summary>
''' OWIN 기반 정적 파일 호스팅 서버
''' 포트 58123 사용 (일반적으로 사용하지 않는 포트)
''' </summary>
Public Class StaticFileServer
Implements IDisposable
Private _webApp As IDisposable
Private _baseUrl As String
Private _rootPath As String
Private _isRunning As Boolean = False
''' <summary>
''' 서버가 실행 중인지 여부
''' </summary>
Public ReadOnly Property IsRunning As Boolean
Get
Return _isRunning
End Get
End Property
''' <summary>
''' 서버 URL (예: http://localhost:58123)
''' </summary>
Public ReadOnly Property BaseUrl As String
Get
Return _baseUrl
End Get
End Property
''' <summary>
''' 정적 파일 루트 경로
''' </summary>
Public ReadOnly Property RootPath As String
Get
Return _rootPath
End Get
End Property
''' <summary>
''' StaticFileServer 생성자
''' </summary>
''' <param name="rootPath">정적 파일을 서빙할 루트 디렉토리 경로</param>
''' <param name="port">사용할 포트 번호 (기본값: 58123)</param>
Public Sub New(rootPath As String, Optional port As Integer = 58123)
If String.IsNullOrEmpty(rootPath) Then
Throw New ArgumentException("rootPath는 비어있을 수 없습니다.", "rootPath")
End If
If Not Directory.Exists(rootPath) Then
Directory.CreateDirectory(rootPath)
End If
_rootPath = Path.GetFullPath(rootPath)
_baseUrl = String.Format("http://localhost:{0}", port)
End Sub
''' <summary>
''' 웹 서버 시작
''' </summary>
Public Sub Start()
If _isRunning Then
Throw New InvalidOperationException("서버가 이미 실행 중입니다.")
End If
Try
' OWIN 서버 시작
_webApp = WebApp.Start(Of Startup)(_baseUrl)
_isRunning = True
' 루트 경로를 Startup에서 접근할 수 있도록 설정
Startup.RootPath = _rootPath
Console.WriteLine("웹 서버 시작: {0}", _baseUrl)
Console.WriteLine("루트 경로: {0}", _rootPath)
Catch ex As Exception
_isRunning = False
Throw New Exception("웹 서버 시작 실패: " & ex.Message, ex)
End Try
End Sub
''' <summary>
''' 웹 서버 중지
''' </summary>
Public Sub [Stop]()
If Not _isRunning Then
Return
End If
Try
If _webApp IsNot Nothing Then
_webApp.Dispose()
_webApp = Nothing
End If
_isRunning = False
Console.WriteLine("웹 서버 중지됨")
Catch ex As Exception
Throw New Exception("웹 서버 중지 실패: " & ex.Message, ex)
End Try
End Sub
''' <summary>
''' 리소스 해제
''' </summary>
Public Sub Dispose() Implements IDisposable.Dispose
[Stop]()
End Sub
''' <summary>
''' 특정 파일의 전체 URL 반환
''' </summary>
''' <param name="relativePath">상대 경로 (예: "index.html" 또는 "images/logo.png")</param>
''' <returns>전체 URL</returns>
Public Function GetFileUrl(relativePath As String) As String
If String.IsNullOrEmpty(relativePath) Then
Return _baseUrl & "/"
End If
' 경로 정규화
Dim normalizedPath As String = relativePath.Replace("\", "/")
If Not normalizedPath.StartsWith("/") Then
normalizedPath = "/" & normalizedPath
End If
Return _baseUrl & normalizedPath
End Function
''' <summary>
''' 브라우저에서 루트 URL 열기
''' </summary>
Public Sub OpenInBrowser()
If Not _isRunning Then
Throw New InvalidOperationException("서버가 실행 중이 아닙니다.")
End If
Try
System.Diagnostics.Process.Start(_baseUrl)
Catch ex As Exception
Throw New Exception("브라우저 열기 실패: " & ex.Message, ex)
End Try
End Sub
''' <summary>
''' 특정 파일을 브라우저에서 열기
''' </summary>
''' <param name="relativePath">상대 경로</param>
Public Sub OpenFileInBrowser(relativePath As String)
If Not _isRunning Then
Throw New InvalidOperationException("서버가 실행 중이 아닙니다.")
End If
Try
Dim url As String = GetFileUrl(relativePath)
System.Diagnostics.Process.Start(url)
Catch ex As Exception
Throw New Exception("브라우저 열기 실패: " & ex.Message, ex)
End Try
End Sub
End Class
End Namespace

View File

@@ -29,7 +29,7 @@
<!--<add name="EventLog" type="System.Diagnostics.EventLogTraceListener" initializeData="APPLICATION_NAME"/> -->
</sharedListeners>
</system.diagnostics>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup><userSettings>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/></startup><userSettings>
<Eco2Ar.My.MySettings>
<setting name="xmlformat" serializeAs="String">
<value>&lt;?xml version="1.0" standalone="yes"?&gt;

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Owin" version="2.1.0" targetFramework="net40" />
<package id="Microsoft.Owin.Host.HttpListener" version="2.1.0" targetFramework="net40" />
<package id="Microsoft.Owin.Hosting" version="2.1.0" targetFramework="net40" />
<package id="Microsoft.Owin.StaticFiles" version="2.1.0" targetFramework="net40" />
<package id="Microsoft.Web.WebView2" version="1.0.3537.50" targetFramework="net48" />
<package id="Owin" version="1.0" targetFramework="net40" />
</packages>

View File

@@ -36,7 +36,7 @@
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">

View File

@@ -25,4 +25,4 @@
<!--<add name="EventLog" type="System.Diagnostics.EventLogTraceListener" initializeData="APPLICATION_NAME"/> -->
</sharedListeners>
</system.diagnostics>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/></startup></configuration>

381
CLAUDE.md Normal file
View File

@@ -0,0 +1,381 @@
# CLAUDE.md
이 파일은 Claude Code (claude.ai/code)가 이 저장소에서 작업할 때 참고할 가이드를 제공합니다.
## 프로젝트 개요
**ECO2 (Energy Calculation Optimization 2)**는 한국 건축물 에너지효율등급 인증 기준(녹색건축인증)에 따라 건물의 1차 에너지 소요량, CO2 배출량, 신재생에너지 생산량을 계산하는 VB.NET 및 WinForms 기반 응용 프로그램입니다.
**주 언어**: Visual Basic .NET (VB.NET) with .NET Framework 4.0
**추가 언어**: C# (유틸리티 라이브러리만)
**플랫폼**: Windows 데스크톱 응용 프로그램 (x86 타겟)
## 솔루션 구조
솔루션 `ArinWareT4.sln`은 모듈화된 아키텍처로 구성된 6개의 프로젝트를 포함합니다:
### 메인 응용 프로그램
- **ECO2_2025V1** (`ArinWarev1/`) - 주 WinForms 응용 프로그램
- 진입점: `MdiMain.vb` - 메뉴 시스템을 갖춘 MDI 부모 폼
- `Calculator/` 하위 디렉토리의 핵심 계산 엔진
- 기능별 폼 구성: `Forms/`, `Forms_Input/`, `Forms_Report/`, `Forms_Basic/`
- `Data/`의 기상 데이터 (XML 형식)
- 타입 데이터셋: `eco2DataSet.xsd` (데이터 모델링용)
### 지원 라이브러리 (SubProject 폴더 그룹)
- **CEnergy** (`CEnergy/ArinClassV2/`) - 핵심 비즈니스 로직 라이브러리
- 공통 유틸리티, 데이터베이스 액세스, INI 파일 처리
- 여러 프로젝트에서 공유
- **ArinNet** - 네트워크 통신 유틸리티
- **ArinLogin** - 인증 및 사용자 관리
- 라이선스 검증, 암호화/복호화
- **ArinLog** - 로깅 기능
- **Utility** (C#) - 압축 유틸리티
- 데이터 압축을 위한 MiniLZO 구현
### 배포
- **Setup1** - 설치 프로그램 프로젝트 (`.vdproj`)
## 빌드 및 실행
### 솔루션 빌드
```bash
# Visual Studio에서 솔루션 열기
start ArinWareT4.sln
# 명령줄에서 빌드 (Visual Studio 필요)
msbuild ArinWareT4.sln /p:Configuration=Debug /p:Platform="Any CPU"
msbuild ArinWareT4.sln /p:Configuration=Release /p:Platform="Any CPU"
```
### 출력 경로
- **Debug**: `..\..\..\..\..\eco2\debug_2016\` (프로젝트 기준 상대 경로)
- **Release**: `c:\eco2\debug_2016\`
### 플랫폼 설정
- 타겟 플랫폼: **x86** (32비트)
- 프레임워크: **.NET Framework 4.0**
- Option Strict: **Off** (VB.NET 특성)
### 빌드 구성
- Debug / Release (표준)
- CD_ROM / DVD-5 / SingleImage (배포 구성)
## 아키텍처 개요
### 계산 엔진 (`ArinWarev1/Calculator/`)
계산 엔진은 건물 에너지 계산을 수행하는 전문 모듈로 구성됩니다:
**핵심 계산기 클래스**:
- `Calculator.vb` - 모든 계산 모듈을 조율하는 메인 오케스트레이터
- `CZone.vb` - 존 레벨 계산 (열존, 난방/냉방 부하)
- `CAirHandling.vb` - 공조 시스템 계산
- `CHeating.vb` - 난방 시스템 계산 (기기, 분배, 공급)
- `CCooling.vb` - 냉방 시스템 계산 (기기, 분배)
- `CRenewable.vb` - 신재생에너지 생산량 계산
- `CSummary.vb` - 결과 집계 및 요약 생성
- `CShared.vb` - 공유 계산 변수 및 유틸리티
**결과 처리** (`Calculator/Result/`):
- `CResult.vb` - 결과 데이터 구조
- `C1차소요량.vb` - 1차 에너지 소요량 계산
- `CCo2발생량.vb` - CO2 배출량 계산
- `C생산에너지.vb` - 에너지 생산량 계산
- `C사용면적.vb` - 사용 면적 계산
- `CZones.vb` - 존 결과 집계
### 데이터 흐름
```
사용자 입력 폼 (Forms_Input/)
DataSet (eco2DataSet - DS, DSR)
계산 엔진 (Calculator)
결과 클래스 (CResult, DSR)
리포트 폼 (Forms_Report/)
```
### 주요 데이터셋
- `DS` (DSET) - 입력 데이터 (사용자 입력 건물 정보)
- `DSR` (DSETR) - 결과 데이터 (계산된 에너지 값)
- `CResult` - 구조화된 계산 결과
### 폼 구성
**Forms_Input/** - 데이터 입력 폼
- `Frm_Desc.vb` - 건물 개요
- `Frm_kongjo.vb` - 공조 처리 입력
- `Frm_Bunbae.vb` - 분배 시스템 입력
- `Frm_custom_profile.vb` - 커스텀 사용 프로파일
**Forms_Report/** - 출력 및 보고
- `Frm_Upload.vb` - 인증 서버 업로드
- `Frm_Macro.vb`, `Frm_Macro2.vb` - Excel 리포트 생성
- `Frm_Export.vb` - 데이터 내보내기 기능
**Forms_Basic/** - 유틸리티 폼
- `Frm_Calc.vb` - 계산 트리거
- `Frm_Filter.vb` - 데이터 필터링
- `Frm_FileInfo.vb` - 파일 메타데이터
**Forms/** - 일반 응용 프로그램 폼
- `Frm_About.vb` - About 대화상자
- `Frm_Common.vb` - 공통 대화상자
### 메뉴 시스템 (MdiMain.vb)
`E_MenuIdx` 열거형에 정의된 메뉴 인덱스:
- 입력존
- 입력면
- 공조처리
- 난방기기/공급/분배
- 냉방기기/분배
- 신재생및열병합
- 열관류율
- 건물개요
- 월별에너지사용량
### 사용자 권한
`Prj.UserAuthType`을 통해 제어되는 사용자 유형:
- `ADMIN` - 전체 액세스
- `BOTH` - 전문 사용자 (계산 + 인증)
- `BOTH0` - 일반 사용자 (제한된 액세스)
- `BOTH1` - 확장 전문 사용자 액세스
## 외부 종속성
### FarPoint Spread (v5.0.3505.2008)
- 데이터 입력을 위한 Excel 형식의 스프레드시트 컨트롤
- 구성 요소: CalcEngine, Excel, PDF, Win, Chart
- 입력 폼에서 광범위하게 사용
### Microsoft ReportViewer
- `Microsoft.ReportViewer.Common.dll`
- `Microsoft.ReportViewer.WinForms.dll`
- 형식화된 보고서 생성에 사용
### Excel Interop
- `Interop.Excel.dll` - Excel 자동화를 위한 COM interop
- 매크로/내보내기 기능에 사용
### LOV 구성 요소
- `Lov.dll` - 값 목록 컨트롤 라이브러리
## 파일 형식 및 데이터 저장
### 프로젝트 파일 (.tpl 파일)
- LZO 압축 바이너리 형식 (Utility 프로젝트 사용)
- 건물 데이터, 계산 입력값, 결과 포함
- 사용자 지정 위치에 저장
- 최근 파일은 응용 프로그램 설정에서 추적
### 기상 데이터 (Data/*.xml)
- `weather_temp.xml` - 온도 데이터
- `weather_supdo.xml` - 습도 데이터
- `weather_ilsa.xml` - 일사량 데이터
- `weather_group.xml` - 기상 관측소 그룹
- `tbl_weather.xml` - 기상 위치 테이블
### 구성 파일
- `Frm_Setting.ini` - UI 상태 지속성 (창 크기, 위치)
- `login.dat` - 사용자 자격 증명 (암호화됨)
- `app.config` - 응용 프로그램 설정
## 한국 건축물 에너지 기준
이 응용 프로그램은 한국 건축물 에너지효율등급 인증 기준을 구현합니다:
### 주요 용어
- 건물개요
- 1차 에너지 소요량
- CO2 발생량
- 난방 / 냉방
- 급탕
- 조명 / 환기
- 신재생에너지
- 열관류율
- 공조
- 용도지역
### 계산 버전 관리
`StartVersion` 상수를 통한 버전 제어:
- 규제 준수를 위한 계산 엔진 버전 관리
- `Calculator.New()` 생성자에서 버전 확인
- 기준 버전 "2009123100"
## 개발 가이드라인
### VB.NET 규칙
- Option Strict는 OFF - 암시적 형식 변환 허용
- 한글 주석 및 변수명은 표준 관행
- 명명: 클래스, 메서드는 PascalCase; 로컬 변수는 엄격한 규칙 없음
### DataSet 사용
- 항상 타입 데이터셋 (`DS`, `DSR`) 사용
- 모듈 수준 변수 `DSET1`, `DSETR1`을 통해 액세스
- 타입 안전 액세스를 위해 DataRow 객체 사용
### 폼 관리
- `MdiMain`을 통한 MDI 자식 폼 관리
- `OpenedForm` 속성을 통해 열린 폼 추적
- `Prj.Opened`를 사용하여 프로젝트 파일 로드 여부 확인
### 계산 흐름
1. 프로젝트 파일 로드 → `DSET` 채우기
2. 사용자가 입력 폼 수정 → `DSET` 업데이트
3. 계산 트리거 → `Calculator` 클래스가 `DSET` 처리 → `DSETR``CResult` 채우기
4. 리포트 폼에 결과 표시
### 파일 작업
- 항상 MdiMain의 `Save_File()` / `Load_File()` 메서드 사용
- Utility 라이브러리를 통한 파일 압축 처리
- `PrjChanged` 플래그를 통한 파일 변경 추적
## 일반 작업
### 계산 실행
계산은 메뉴 또는 폼 버튼에서 트리거되고 `Calculator` 클래스를 통해 처리됩니다:
```vb
' 데이터셋 및 결과 객체로 계산기 초기화
Dim calc As New Calculator(version, DSET1, DSETR1, Result2, isSimulation)
' 초기화 오류 확인
If calc.IsError Then
' 오류 처리
Return
End If
' DSETR1 및 Result2에서 계산 결과 사용 가능
```
### 새 입력 필드 추가
1. 적절한 테이블에 열을 추가하도록 `eco2DataSet.xsd` 수정
2. 해당 입력 폼(`Forms_Input/*.vb`) 업데이트
3. 관련 `Calculator/*.vb` 클래스의 계산 로직 업데이트
4. 필요한 경우 리포트 폼 업데이트
### 새 계산 모듈 추가
1. `Calculator/` 디렉토리에 새 클래스 생성
2. 기존 모듈의 계산 패턴 상속
3. 생성자에서 `DS`, `DSR`, `CResult` 수락
4. `Calculator.vb` 오케스트레이터에 연결
5. `CSummary.vb`의 요약 집계 업데이트
### FarPoint Spread 컨트롤 작업
FarPoint 컨트롤은 그리드 기반 입력에 광범위하게 사용됩니다:
```vb
' Spread 컨트롤 액세스
Dim spread As FarPoint.Win.Spread.FpSpread = Me.FpSpread1
' 셀 값 설정
spread.ActiveSheet.Cells(row, col).Value = value
' 셀 값 읽기
Dim value = spread.ActiveSheet.Cells(row, col).Value
' 셀 속성 설정
spread.ActiveSheet.Cells(row, col).BackColor = Color.Yellow
```
## 알려진 패턴 및 규칙
### 전역 모듈 변수
- `DSET1` - 전역 입력 데이터셋 (DS 타입)
- `DSETR1` - 전역 결과 데이터셋 (DSR 타입)
- `Result2` - 전역 결과 객체 (CResult 타입)
- `Prj` - 전역 프로젝트 상태 객체
- `CLang` - 언어/지역화 문자열
### 오류 처리
- 계산 클래스의 `IsError` 속성 패턴
- 사용자 대면 오류에 대한 메시지 박스
- `On Error Resume Next`를 사용한 VB.NET 오류 처리 (레거시 패턴)
### 이벤트 처리
- 클래스 수준 이벤트 핸들러를 위한 WithEvents 패턴
- `Handles` 키워드를 통한 폼 이벤트 처리
### INI 파일 액세스
```vb
Dim ini As New MyINI(filePath)
Dim value = ini.Read(section, key, defaultValue)
ini.Write(section, key, value)
```
## 테스트 및 디버깅
### 디버그 모드
- Debug 구성으로 빌드
- 로컬 디버그 폴더로 출력
- 전체 심볼 정보 사용 가능
### 테스트 데이터
사용 가능한 샘플 프로젝트 파일:
- `sample.tpl` - 표준 샘플 건물
- `sample_0307.tpl` - 대체 샘플
- `sample_200.tpl` - 대형 건물 샘플
### 로깅
응용 프로그램 로깅에 ArinLog 라이브러리 사용:
```vb
pLog.Add("이벤트 설명", includeStackTrace)
```
## 언어 관련 참고사항
응용 프로그램은 한국 사용자를 위해 설계되었습니다:
- 모든 UI 텍스트는 한글
- 사용자 문서는 한글
- 한국 건축 기준 및 용어
- 날짜/시간 형식: 한국 표준
- 인코딩: 소스 파일은 UTF-8
주석 및 변수명은 한글과 영어를 혼용합니다 - 이는 의도적이며 이 코드베이스의 표준입니다.
## 배포 참고사항
### 설치
- 설치 프로그램 프로젝트: `Setup1/Setup1.vdproj`
- 메인 프로젝트에 구성된 ClickOnce 배포
- 게시 URL: `ftp://tindevil.com/www/mynetapp/t4/`
- 설치 URL: `http://tindevil.com/mynetapp/t4/`
### 버전 관리
- AssemblyInfo의 버전 정보
- ArinLogin 라이브러리를 통한 버전 확인
- 서버 측 버전 검증
### 업데이트
- 시작 시 업데이트 확인
- Foreground 업데이트 모드 (실행 전 업데이트)
- 7일 업데이트 간격 구성
## 보안 참고사항
### 인증
- ArinLogin 라이브러리를 통한 사용자 인증
- MAC 주소 검증 (상태 표시줄의 `lbl_mac`)
- 라이선스 관리 시스템
- `login.dat`의 암호화된 자격 증명
### 데이터 보호
- 데이터 보호를 위한 파일 압축
- ArinLogin.EnDec 클래스를 통한 암호화/복호화
- 라이선스 준수를 위한 네트워크 검증

File diff suppressed because it is too large Load Diff

View File

@@ -10,7 +10,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Utility</RootNamespace>
<AssemblyName>Utility</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">

View File

@@ -0,0 +1,135 @@
# WebView2 Fixed Version 배포 가이드
## 개요
ECO2 프로그램은 WebView2 Fixed Version 방식을 사용하여 오프라인 환경에서도 매뉴얼 뷰어를 사용할 수 있습니다.
## Fixed Version 다운로드
### 1. 다운로드 위치
https://developer.microsoft.com/microsoft-edge/webview2/#download-section
"Fixed Version" 섹션에서 다운로드합니다.
### 2. 버전 선택
- **플랫폼**: x86 (32-bit) - ECO2는 x86 타겟입니다
- **추천 버전**: 최신 Stable 버전
- 파일 크기: 약 100-150MB
### 3. 다운로드 파일 예시
- `Microsoft.WebView2.FixedVersionRuntime.{version}.x86.cab`
- 또는 압축 해제된 폴더 형태
## 배포 방법
### 1. 폴더 구조
```
{프로그램 설치 폴더}/
├── ECO2_2025V1.exe
├── WebView2Runtime/ ← Fixed Version 런타임 폴더
│ ├── msedge.exe
│ ├── msedgewebview2.exe
│ └── [기타 WebView2 파일들]
└── WebView2Data/ ← 사용자 데이터 폴더 (자동 생성됨)
└── [캐시, 쿠키 등]
```
### 2. 설치 단계
#### 방법 1: 수동 배포 (개발/테스트)
1. Fixed Version CAB 파일 또는 폴더 다운로드
2. CAB 파일인 경우 압축 해제
3. 압축 해제된 내용을 `WebView2Runtime` 폴더로 복사
4. `WebView2Runtime` 폴더를 프로그램 실행 파일과 같은 위치에 배치
#### 방법 2: 설치 프로그램 포함 (프로덕션)
Setup1 프로젝트에 WebView2Runtime 폴더를 포함:
1. Setup1.vdproj 열기
2. WebView2Runtime 폴더를 프로젝트에 추가
3. 설치 시 Application Folder에 복사되도록 설정
## 동작 방식
### 런타임 검색 순서
1. **Fixed Version 우선**: `{실행폴더}\WebView2Runtime` 폴더 검색
2. **시스템 런타임 폴백**: 시스템에 설치된 WebView2 Runtime 사용
3. **없을 경우**: 매뉴얼 기능 사용 시 오류 메시지 표시
### 프로그램 시작 시 검사
- MdiMain 로드 시 `CheckWebView2Runtime()` 메서드가 Fixed Version 존재 여부 확인
- Debug.WriteLine으로 경고 출력 (사용자에게는 미표시)
- 실제 사용 시점(매뉴얼 열기)에만 오류 표시
### 오프라인 환경
- Fixed Version이 배포되어 있으면 인터넷 연결 불필요
- 모든 런타임 파일이 로컬에 포함되어 있음
- 폐쇄망 환경에서도 정상 작동
## 버전 업데이트
### Fixed Version 업데이트 방법
1. 새 Fixed Version 다운로드
2. 기존 `WebView2Runtime` 폴더 백업 (선택사항)
3. 새 버전으로 `WebView2Runtime` 폴더 교체
4. 프로그램 재시작
### 주의사항
- WebView2Runtime 폴더는 약 100-150MB이므로 Git에 커밋하지 않음
- .gitignore에 이미 추가되어 있음
- 설치 프로그램에는 반드시 포함해야 함
## 테스트 방법
### 1. Fixed Version 테스트
```
1. WebView2Runtime 폴더가 있는 상태에서 프로그램 실행
2. "Manual" 메뉴 클릭
3. http://localhost:58123/ 페이지가 정상적으로 로드되는지 확인
```
### 2. 폴백(Fallback) 테스트
```
1. WebView2Runtime 폴더 임시 이름 변경 (예: WebView2Runtime_backup)
2. 프로그램 실행 (시스템 런타임 사용 시도)
3. "Manual" 메뉴 클릭
4. 시스템에 런타임이 있으면 정상 작동, 없으면 오류 메시지
```
### 3. 오프라인 테스트
```
1. 네트워크 연결 끊기
2. Fixed Version 배포된 상태에서 프로그램 실행
3. 매뉴얼 기능이 정상 작동하는지 확인
```
## 문제 해결
### "WebView2 구성 요소를 찾을 수 없습니다" 오류
**원인**: Fixed Version도 없고 시스템 런타임도 설치되지 않음
**해결**:
1. WebView2Runtime 폴더가 실행 파일과 같은 위치에 있는지 확인
2. WebView2Runtime 폴더 내에 msedgewebview2.exe 파일이 있는지 확인
3. 또는 시스템에 WebView2 Runtime 설치: https://go.microsoft.com/fwlink/p/?LinkId=2124703
### 페이지 로딩 실패
**원인**: 로컬 웹서버(http://localhost:58123/)가 실행되지 않음
**해결**:
1. 로컬 웹서버가 실행 중인지 확인
2. 포트 58123이 열려 있는지 확인
3. Frm_WebManual.vb의 Navigate URL 수정 필요 시 수정
### WebView2Data 폴더 문제
**원인**: 캐시 또는 쿠키 문제
**해결**:
1. 프로그램 종료
2. WebView2Data 폴더 삭제
3. 프로그램 재시작 (자동으로 새 폴더 생성됨)
## 참고 자료
- WebView2 공식 문서: https://learn.microsoft.com/microsoft-edge/webview2/
- Fixed Version 배포 가이드: https://learn.microsoft.com/microsoft-edge/webview2/concepts/distribution
- WebView2 다운로드: https://developer.microsoft.com/microsoft-edge/webview2/

View File

@@ -0,0 +1,68 @@
@echo off
chcp 65001 > nul
echo ========================================
echo OWIN NuGet 패키지 다운로드
echo (압축 해제는 수동으로 진행)
echo ========================================
echo.
REM 다운로드 폴더 생성
echo [1/2] 다운로드 폴더 생성 중...
if not exist "owin_packages" mkdir owin_packages
cd owin_packages
echo 완료
echo.
REM NuGet 패키지 다운로드 (.zip으로 저장)
echo [2/2] NuGet 패키지 다운로드 중...
echo.
echo 다운로드: Owin.1.0.0.zip
powershell -Command "Invoke-WebRequest -Uri 'https://www.nuget.org/api/v2/package/Owin/1.0.0' -OutFile 'Owin.1.0.0.zip'"
echo 완료
echo 다운로드: Microsoft.Owin.2.1.0.zip
powershell -Command "Invoke-WebRequest -Uri 'https://www.nuget.org/api/v2/package/Microsoft.Owin/2.1.0' -OutFile 'Microsoft.Owin.2.1.0.zip'"
echo 완료
echo 다운로드: Microsoft.Owin.Host.HttpListener.2.1.0.zip
powershell -Command "Invoke-WebRequest -Uri 'https://www.nuget.org/api/v2/package/Microsoft.Owin.Host.HttpListener/2.1.0' -OutFile 'Microsoft.Owin.Host.HttpListener.2.1.0.zip'"
echo 완료
echo 다운로드: Microsoft.Owin.Hosting.2.1.0.zip
powershell -Command "Invoke-WebRequest -Uri 'https://www.nuget.org/api/v2/package/Microsoft.Owin.Hosting/2.1.0' -OutFile 'Microsoft.Owin.Hosting.2.1.0.zip'"
echo 완료
echo 다운로드: Microsoft.Owin.StaticFiles.2.1.0.zip
powershell -Command "Invoke-WebRequest -Uri 'https://www.nuget.org/api/v2/package/Microsoft.Owin.StaticFiles/2.1.0' -OutFile 'Microsoft.Owin.StaticFiles.2.1.0.zip'"
echo 완료
echo 다운로드: Microsoft.Owin.FileSystems.2.1.0.zip
powershell -Command "Invoke-WebRequest -Uri 'https://www.nuget.org/api/v2/package/Microsoft.Owin.FileSystems/2.1.0' -OutFile 'Microsoft.Owin.FileSystems.2.1.0.zip'"
echo 완료
cd ..
echo.
echo ========================================
echo 다운로드 완료!
echo ========================================
echo.
echo 다운로드된 파일 목록:
dir /b owin_packages\*.zip
echo.
echo 다음 단계:
echo 1. owin_packages 폴더 열기
echo 2. 각 .zip 파일을 압축 해제
echo 3. 각 폴더의 lib\net40\ 경로에서 .dll 파일 찾기
echo 4. 모든 .dll 파일을 lib 폴더로 복사
echo.
echo 필요한 DLL 파일 목록:
echo - Owin.dll
echo - Microsoft.Owin.dll
echo - Microsoft.Owin.Host.HttpListener.dll
echo - Microsoft.Owin.Hosting.dll
echo - Microsoft.Owin.StaticFiles.dll
echo - Microsoft.Owin.FileSystems.dll
echo.
pause

143
host_eco2_guide_fixed.bat Normal file
View File

@@ -0,0 +1,143 @@
@echo off
chcp 65001 > nul
echo ========================================
echo ECO2 Guide Center 로컬 호스팅
echo ========================================
echo.
REM 현재 디렉토리 확인
set CURRENT_DIR=%CD%
echo 현재 디렉토리: %CURRENT_DIR%
echo.
REM eco2_guide_center 저장소 경로 확인
set GUIDE_REPO=eco2_guide_center
if not exist "%GUIDE_REPO%" (
echo [1/4] 저장소 클론 중...
git clone https://github.com/VeryColdplay/eco2_guide_center.git
if errorlevel 1 (
echo 오류: 저장소 클론 실패
echo Git이 설치되어 있는지 확인하세요.
pause
exit /b 1
)
echo 완료
) else (
echo [1/4] 저장소 업데이트 중...
cd %GUIDE_REPO%
git pull
cd ..
echo 완료
)
echo.
REM 필요한 패키지 설치
echo [2/4] Python 패키지 설치 중...
echo (네트워크 연결이 필요합니다. 시간이 걸릴 수 있습니다...)
echo.
REM 방화벽이나 프록시 문제가 있을 수 있으므로 개별 설치 시도
pip install mkdocs-material 2>nul
if errorlevel 1 (
echo 경고: mkdocs-material 설치 실패 - 이미 설치되어 있거나 네트워크 문제일 수 있습니다.
)
pip install mkdocs-macros-plugin 2>nul
pip install mkdocs-mermaid2-plugin 2>nul
pip install mkdocs-table-reader-plugin 2>nul
pip install mkdocs-glightbox 2>nul
pip install mkdocs-git-revision-date-localized-plugin 2>nul
pip install mkdocs-minify-plugin 2>nul
pip install mkdocs-awesome-pages-plugin 2>nul
echo 패키지 설치 시도 완료
echo.
REM MkDocs 빌드
echo [3/4] MkDocs 빌드 중...
cd %GUIDE_REPO%
REM mkdocs.yml에서 awesome-pages 플러그인 제거 (임시)
echo awesome-pages 플러그인 비활성화 중...
powershell -Command "(Get-Content mkdocs.yml) -replace ' - awesome-pages', ' # - awesome-pages' | Set-Content mkdocs_temp.yml"
REM 정적 사이트 빌드
echo MkDocs 빌드 실행...
mkdocs build -f mkdocs_temp.yml
if errorlevel 1 (
echo.
echo 오류: MkDocs 빌드 실패
echo.
echo 해결 방법:
echo 1. Python이 설치되어 있는지 확인
echo 2. 인터넷 연결 확인
echo 3. 방화벽/프록시 설정 확인
echo 4. 관리자 권한으로 실행
echo.
echo 또는 수동 설치:
echo pip install mkdocs-material mkdocs-awesome-pages-plugin
echo.
del mkdocs_temp.yml 2>nul
cd ..
pause
exit /b 1
)
del mkdocs_temp.yml 2>nul
echo 완료
echo.
REM ECO2 wwwroot 폴더로 복사
echo [4/4] ECO2 wwwroot로 복사 중...
cd ..
REM wwwroot 폴더 생성
if not exist "wwwroot" mkdir wwwroot
REM 기존 파일 백업 (선택사항)
if exist "wwwroot\index.html" (
echo 기존 파일 발견 - 백업 생성 중...
if not exist "wwwroot_backup" mkdir wwwroot_backup
xcopy /E /I /Y "wwwroot\*" "wwwroot_backup\" > nul
)
REM site 폴더 내용 복사
echo 빌드된 파일 복사 중...
xcopy /E /I /Y "%GUIDE_REPO%\site\*" "wwwroot\" > nul
if errorlevel 1 (
echo 오류: 파일 복사 실패
pause
exit /b 1
)
echo 완료
echo.
REM 파일 개수 확인
for /f %%A in ('dir /b /s "wwwroot\*.html" ^| find /c ".html"') do set HTML_COUNT=%%A
echo 복사된 HTML 파일: %HTML_COUNT%
echo.
echo ========================================
echo 호스팅 준비 완료!
echo ========================================
echo.
echo wwwroot 폴더: %CURRENT_DIR%\wwwroot
echo.
echo 다음 중 한 가지 방법으로 접속:
echo.
echo [방법 1] ECO2 프로그램의 OWIN 서버 사용
echo 1. ECO2 프로그램 실행
echo 2. OWIN 서버 시작 (포트 58123)
echo 3. 브라우저: http://localhost:58123
echo.
echo [방법 2] MkDocs 개발 서버 사용 (추천 - 자동 새로고침)
echo 1. cd eco2_guide_center
echo 2. mkdocs serve
echo 3. 브라우저: http://127.0.0.1:8000
echo.
echo [방법 3] Python 간단 서버 사용
echo 1. cd wwwroot
echo 2. python -m http.server 8080
echo 3. 브라우저: http://localhost:8080
echo.
pause

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
lib/Microsoft.Owin.dll Normal file

Binary file not shown.

BIN
lib/Owin.dll Normal file

Binary file not shown.

BIN
nuget.exe Normal file

Binary file not shown.

1
run_claude.bat Normal file
View File

@@ -0,0 +1 @@
claude --dangerously-skip-permissions