Compare commits

...

4 Commits

Author SHA1 Message Date
d0ca1c8813 html업데이트 2025-12-13 02:11:50 +09:00
6fbfa52a00 template 폴더에 압축파일을 두고 그것을 자동 압축 해제하도록 함 , webview2 runtime 을 추가 2025-12-11 22:41:51 +09:00
1fd7c25c8d 메뉴얼 파일 압축 해제 관련 기능 추가 2025-12-11 00:50:51 +09:00
132ddc6495 "Replace OWIN self-hosting with WebView2 virtual hosting" -m "-
Remove OWIN server implementation (StaticFileServer, Startup)" -m "- Implement
    WebView2 SetVirtualHostNameToFolderMapping in Frm_WebManual" -m "- Remove all
   OWIN NuGet packages from packages.config and .vbproj" -m "- Add comprehensive
   guide document (WEBVIEW2_VIRTUAL_HOSTING.md)" -m "- Mark legacy OWIN files as
   deprecated
2025-12-01 20:55:42 +09:00
25 changed files with 1223 additions and 5502 deletions

4
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,4 @@
{
"dotnet.preferCSharpExtension": true,
"dotnet.defaultSolution": "ArinWareT4.sln"
}

View File

@@ -1,6 +1,6 @@
 
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2010 # Visual Studio 2022
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SubProject", "SubProject", "{4D184935-DE50-4DBA-9EBF-8C66C579B7DC}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SubProject", "SubProject", "{4D184935-DE50-4DBA-9EBF-8C66C579B7DC}"
EndProject EndProject
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "ECO2_2025V1", "ArinWarev1\ECO2_2025V1.vbproj", "{D5C51BDE-68E5-42BC-B648-DB9CCF044703}" Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "ECO2_2025V1", "ArinWarev1\ECO2_2025V1.vbproj", "{D5C51BDE-68E5-42BC-B648-DB9CCF044703}"

View File

@@ -31,6 +31,8 @@
<ApplicationIcon>002.ico</ApplicationIcon> <ApplicationIcon>002.ico</ApplicationIcon>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion> <TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<TargetFrameworkProfile /> <TargetFrameworkProfile />
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
<PublishUrl>ftp://tindevil.com/www/mynetapp/t4/</PublishUrl> <PublishUrl>ftp://tindevil.com/www/mynetapp/t4/</PublishUrl>
<Install>true</Install> <Install>true</Install>
<InstallFrom>Web</InstallFrom> <InstallFrom>Web</InstallFrom>
@@ -51,15 +53,13 @@
<ApplicationVersion>1.0.0.%2a</ApplicationVersion> <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust> <UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled> <BootstrapperEnabled>true</BootstrapperEnabled>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType> <DebugType>full</DebugType>
<DefineDebug>true</DefineDebug> <DefineDebug>true</DefineDebug>
<DefineTrace>true</DefineTrace> <DefineTrace>true</DefineTrace>
<OutputPath>..\..\..\..\..\eco2\debug_2016\</OutputPath> <OutputPath>c:\eco2\debug_2016\</OutputPath>
<DocumentationFile> <DocumentationFile>
</DocumentationFile> </DocumentationFile>
<NoWarn>41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42353,42354,42355</NoWarn> <NoWarn>41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42353,42354,42355</NoWarn>
@@ -113,26 +113,6 @@
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\Interop.VBIDE.dll</HintPath> <HintPath>..\Interop.VBIDE.dll</HintPath>
</Reference> </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.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.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"> <Reference Include="Microsoft.Web.WebView2.Core, Version=1.0.3537.50, Culture=neutral, PublicKeyToken=2a8ab48044d2601e, processorArchitecture=MSIL">
@@ -144,14 +124,12 @@
<Reference Include="Microsoft.Web.WebView2.Wpf, Version=1.0.3537.50, Culture=neutral, PublicKeyToken=2a8ab48044d2601e, processorArchitecture=MSIL"> <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> <HintPath>..\packages\Microsoft.Web.WebView2.1.0.3537.50\lib\net462\Microsoft.Web.WebView2.Wpf.dll</HintPath>
</Reference> </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" />
<Reference Include="System.Data" /> <Reference Include="System.Data" />
<Reference Include="System.Data.DataSetExtensions" /> <Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Drawing" /> <Reference Include="System.Drawing" />
<Reference Include="System.IO.Compression" />
<Reference Include="System.IO.Compression.FileSystem" />
<Reference Include="System.Windows.Forms" /> <Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
@@ -214,6 +192,12 @@
<Compile Include="Forms_Basic\Frm_WebManual.vb"> <Compile Include="Forms_Basic\Frm_WebManual.vb">
<SubType>Form</SubType> <SubType>Form</SubType>
</Compile> </Compile>
<Compile Include="Forms_Basic\Frm_WwwrootExtract.Designer.vb">
<DependentUpon>Frm_WwwrootExtract.vb</DependentUpon>
</Compile>
<Compile Include="Forms_Basic\Frm_WwwrootExtract.vb">
<SubType>Form</SubType>
</Compile>
<Compile Include="Forms_Basic\fSelectWeatherGroup.Designer.vb"> <Compile Include="Forms_Basic\fSelectWeatherGroup.Designer.vb">
<DependentUpon>fSelectWeatherGroup.vb</DependentUpon> <DependentUpon>fSelectWeatherGroup.vb</DependentUpon>
</Compile> </Compile>
@@ -524,9 +508,6 @@
<Compile Include="Forms_Basic\Frm_FileInfo.vb"> <Compile Include="Forms_Basic\Frm_FileInfo.vb">
<SubType>Form</SubType> <SubType>Form</SubType>
</Compile> </Compile>
<Compile Include="WebServer\Example_WebServer_Usage.vb" />
<Compile Include="WebServer\Startup.vb" />
<Compile Include="WebServer\StaticFileServer.vb" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="Forms_Basic\Frm_DisplayGubun.resx"> <EmbeddedResource Include="Forms_Basic\Frm_DisplayGubun.resx">
@@ -544,6 +525,9 @@
<EmbeddedResource Include="Forms_Basic\Frm_WebManual.resx"> <EmbeddedResource Include="Forms_Basic\Frm_WebManual.resx">
<DependentUpon>Frm_WebManual.vb</DependentUpon> <DependentUpon>Frm_WebManual.vb</DependentUpon>
</EmbeddedResource> </EmbeddedResource>
<EmbeddedResource Include="Forms_Basic\Frm_WwwrootExtract.resx">
<DependentUpon>Frm_WwwrootExtract.vb</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms_Basic\Frm_Work.resx"> <EmbeddedResource Include="Forms_Basic\Frm_Work.resx">
<DependentUpon>Frm_Work.vb</DependentUpon> <DependentUpon>Frm_Work.vb</DependentUpon>
<SubType>Designer</SubType> <SubType>Designer</SubType>
@@ -735,6 +719,9 @@
<None Include="DataSet\DS2.xss"> <None Include="DataSet\DS2.xss">
<DependentUpon>DS2.xsd</DependentUpon> <DependentUpon>DS2.xsd</DependentUpon>
</None> </None>
<None Include="Template\EBWebView.zip">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="login.dat"> <None Include="login.dat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
@@ -804,7 +791,7 @@
<ItemGroup> <ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5"> <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible> <Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName> <ProductName>.NET Framework Client Profile</ProductName>
<Install>false</Install> <Install>false</Install>
</BootstrapperPackage> </BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.2.0"> <BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
@@ -837,7 +824,9 @@
<Content Include="icon5.ico" /> <Content Include="icon5.ico" />
<None Include="Resources\select_by_difference.png" /> <None Include="Resources\select_by_difference.png" />
<None Include="Resources\page_copy.png" /> <None Include="Resources\page_copy.png" />
<Content Include="WebServer\INSTALL.txt" /> <Content Include="WebView2Loader.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="단축키.txt"> <Content Include="단축키.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
@@ -856,7 +845,12 @@
<Content Include="Forms_Input\ReadMe.txt"> <Content Include="Forms_Input\ReadMe.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
<None Include="WebServer\README.md" /> <None Include="Template\WebView2Runtime.zip">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="Template\wwwroot.zip">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="방위2.png" /> <None Include="방위2.png" />
<None Include="방위.png" /> <None Include="방위.png" />
<None Include="방위.jpg" /> <None Include="방위.jpg" />

View File

@@ -22,6 +22,7 @@ Partial Class Frm_WebManual
'코드 편집기에서는 수정하지 마세요. '코드 편집기에서는 수정하지 마세요.
<System.Diagnostics.DebuggerStepThrough()> _ <System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent() Private Sub InitializeComponent()
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(Frm_WebManual))
Me.WebView21 = New Microsoft.Web.WebView2.WinForms.WebView2() Me.WebView21 = New Microsoft.Web.WebView2.WinForms.WebView2()
CType(Me.WebView21, System.ComponentModel.ISupportInitialize).BeginInit() CType(Me.WebView21, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SuspendLayout() Me.SuspendLayout()
@@ -44,6 +45,7 @@ Partial Class Frm_WebManual
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(1350, 700) Me.ClientSize = New System.Drawing.Size(1350, 700)
Me.Controls.Add(Me.WebView21) Me.Controls.Add(Me.WebView21)
Me.Icon = CType(resources.GetObject("$this.Icon"), System.Drawing.Icon)
Me.Name = "Frm_WebManual" Me.Name = "Frm_WebManual"
Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen
Me.Text = "사용자 매뉴얼" Me.Text = "사용자 매뉴얼"

View File

@@ -117,4 +117,24 @@
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAABAAEAEBAAAAAAIABsAwAAFgAAAIlQTkcNChoKAAAADUlIRFIAAAAQAAAAEAgGAAAAH/P/YQAAAzNJ
REFUeJxVk99PHHUUxT8zO7OzC7vsLrsgQtYSaySxoUWk9oFSY1Otxvhg/J0YTXnwwUSJiX+AL/wDRquJ
0fbBVPvSaGJsQ7WKlMYallBMoA0oQmAJS9lld2WYme/3O1+zpjX0Pt6ce+7JPfcYWmv21sjk8BDwLnAY
aAMsoApc16E+/dHQmUt78cZdgpHJ4QbwLPDS8/kTTibeRs1txg1AKg/JBj+tX5RKqstSqle+ePabf/4n
GJkctoGfB3IHBp/OP0nNc/AJWKwZRLXDlhuiZUAcl3V/gqni1KwU8ti5l7+tmneUnO3PPjx4tHOAsgoQ
poGUJrsyikuUsu9Q8uKsVm0eSDzOQEfPwcAXX/+n4L2rp44CVz449JY9K3fwDGhWCXCzrO3Y+MLg5kod
woD7Osq055Z4LNbFh99/qqSQLzYUvH+y84hd8naoI1FhjlaVZu62QaUON5brBE4Fa/8fVLIF5lWRuY0V
Xu09Hgl88U7jcIfzLV3MuEU2YyaPRPYTIlkuBXjeLqkOTa11jMVwG3xNWjosbPqc6O5H+LK3QZBtsppZ
douUfJdk04NsB0kqlZBUm0d7xmVT9VHzb+DoOvXbW5S3m0jEk4hApi2ttWFoCPwamjyWrbj4m8CIJ1hf
lJi6hc62XZL1IWprAo8pRLAEWiOlNCwlw3ItqHVlI2mSsUOsblp4wiYac4i1x/nzry2839MQeqTabdLN
XaQiJSo7VZQMq6YUcvrv8goPNeUpliYJ7TWiER/huQhhEU1kcFpjWDET21BEgk0678+xVFxquDhvikB+
fOHmuNyXaMNy16huXSOT8bGkj21oHDOCFQRk8quk2n/F3L1FX76X0z9eaLzw5+aXz50fC3zxw9jcOE90
9ZGKNJNJhKSiipaoR9L2SccFrdYEZnGZ/gM9XC6MN7aPF0ZnzjVcQPjijV8WZq76u8HBk48e41bJIlLV
SKOOCE1IKPL7uunp7ebK9DUuzV5fAF6/J0zPfHI8KYU8L4V66s3BUxaqA62bMEyDXKrGRnmaz8a+U8AE
8FphdGbjHoK7NTh65AUl1dtKhb2hCjN32o04zwNnCqMzX+0d+BfEDZRfNsnANgAAAABJRU5ErkJggg==
</value>
</data>
</root> </root>

View File

@@ -4,27 +4,50 @@ Imports Microsoft.Web.WebView2.Core
Public Class Frm_WebManual Public Class Frm_WebManual
Public Sub Navigate(url As String) Private Async Sub Frm_WebManual_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Try Try
' WebView2 초기화
Await InitializeWebView2Async()
Try
' 가상 호스팅 설정
If WebView21.CoreWebView2 Is Nothing Then
Return
End If
' wwwroot 경로 확인
Dim _wwwrootPath As String = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "wwwroot")
If String.IsNullOrEmpty(_wwwrootPath) Then
_wwwrootPath = Path.Combine(Application.StartupPath, "wwwroot")
End If
' 디렉토리가 없으면 생성
If Not Directory.Exists(_wwwrootPath) Then
Directory.CreateDirectory(_wwwrootPath)
End If
' 가상 호스트 매핑 설정
' https://eco2.local/ -> 로컬 폴더 매핑
WebView21.CoreWebView2.SetVirtualHostNameToFolderMapping(
"eco2.local",
_wwwrootPath,
CoreWebView2HostResourceAccessKind.Allow)
If WebView21 IsNot Nothing AndAlso WebView21.CoreWebView2 IsNot Nothing Then If WebView21 IsNot Nothing AndAlso WebView21.CoreWebView2 IsNot Nothing Then
' 가상 호스트 URL 사용
Dim url As String = "https://eco2.local/index.html"
WebView21.CoreWebView2.Navigate(url) WebView21.CoreWebView2.Navigate(url)
End If End If
Catch ex As Exception Catch ex As Exception
MessageBox.Show("웹페이지 이동 중 오류가 발생했습니다: " & ex.Message, MessageBox.Show("웹페이지 이동 중 오류가 발생했습니다: " & ex.Message,
"오류", MessageBoxButtons.OK, MessageBoxIcon.Error) "오류", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try 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 Catch ex As Exception
MessageBox.Show("웹페이지 로드 중 오류가 발생했습니다: " & ex.Message, MessageBox.Show("웹페이지 로드 중 오류가 발생했습니다: " & ex.Message,
@@ -62,4 +85,5 @@ Public Class Frm_WebManual
End Try End Try
End Function End Function
End Class End Class

View File

@@ -0,0 +1,94 @@
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class Frm_WwwrootExtract
Inherits System.Windows.Forms.Form
'Form overrides dispose to clean up the component list.
<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
'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer
'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
Me.lblStatus = New System.Windows.Forms.Label()
Me.progressBar = New System.Windows.Forms.ProgressBar()
Me.lblPercentage = New System.Windows.Forms.Label()
Me.lblTitle = New System.Windows.Forms.Label()
Me.SuspendLayout()
'
'lblStatus
'
Me.lblStatus.AutoSize = True
Me.lblStatus.Location = New System.Drawing.Point(34, 112)
Me.lblStatus.Name = "lblStatus"
Me.lblStatus.Size = New System.Drawing.Size(142, 15)
Me.lblStatus.TabIndex = 0
Me.lblStatus.Text = "압축 해제 준비 중..."
'
'progressBar
'
Me.progressBar.Location = New System.Drawing.Point(34, 138)
Me.progressBar.Margin = New System.Windows.Forms.Padding(3, 4, 3, 4)
Me.progressBar.Name = "progressBar"
Me.progressBar.Size = New System.Drawing.Size(503, 38)
Me.progressBar.TabIndex = 1
'
'lblPercentage
'
Me.lblPercentage.AutoSize = True
Me.lblPercentage.Font = New System.Drawing.Font("굴림", 9.0!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(129, Byte))
Me.lblPercentage.Location = New System.Drawing.Point(34, 188)
Me.lblPercentage.Name = "lblPercentage"
Me.lblPercentage.Size = New System.Drawing.Size(28, 15)
Me.lblPercentage.TabIndex = 2
Me.lblPercentage.Text = "0%"
'
'lblTitle
'
Me.lblTitle.AutoSize = True
Me.lblTitle.Font = New System.Drawing.Font("굴림", 11.25!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(129, Byte))
Me.lblTitle.Location = New System.Drawing.Point(34, 38)
Me.lblTitle.Name = "lblTitle"
Me.lblTitle.Size = New System.Drawing.Size(297, 19)
Me.lblTitle.TabIndex = 3
Me.lblTitle.Text = "런타임 파일 압축 해제 중입니다"
'
'Frm_WwwrootExtract
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(8.0!, 15.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(571, 250)
Me.Controls.Add(Me.lblTitle)
Me.Controls.Add(Me.lblPercentage)
Me.Controls.Add(Me.progressBar)
Me.Controls.Add(Me.lblStatus)
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog
Me.Margin = New System.Windows.Forms.Padding(3, 4, 3, 4)
Me.MaximizeBox = False
Me.MinimizeBox = False
Me.Name = "Frm_WwwrootExtract"
Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen
Me.Text = "압축 해제 중"
Me.TopMost = True
Me.ResumeLayout(False)
Me.PerformLayout()
End Sub
Friend WithEvents lblStatus As Label
Friend WithEvents progressBar As ProgressBar
Friend WithEvents lblPercentage As Label
Friend WithEvents lblTitle As Label
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,109 @@
Imports System.IO
Imports System.IO.Compression
Imports System.Threading.Tasks
Public Class Frm_WwwrootExtract
Dim extractPath As String
Dim zipPath As String
Public Sub New(targetpath As String, zipfile As String)
InitializeComponent()
Me.extractPath = targetpath
Me.zipPath = zipfile
End Sub
Private Sub Frm_WwwrootExtract_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.Show()
Application.DoEvents()
' 폼이 로드될 때 자동으로 압축 해제 시작
ExtractTemplateFiles()
End Sub
Private Async Sub ExtractTemplateFiles()
Try
' Dim extractPath As String = TargetPath ' Path.Combine(Application.StartupPath, "wwwroot")
' Dim zipPath As String = Path.Combine(extractPath, "wwwroot.zip")
' ZIP 파일 존재 여부 확인
If Not File.Exists(zipPath) Then
lblStatus.Text = "wwwroot.zip 파일을 찾을 수 없습니다."
MessageBox.Show("wwwroot.zip 파일이 존재하지 않습니다.", "오류", MessageBoxButtons.OK, MessageBoxIcon.Error)
Me.DialogResult = DialogResult.Cancel
Me.Close()
Return
End If
' 압축 해제 작업을 별도 Task로 실행
Await Task.Run(Sub()
ExtractZipWithProgress(zipPath, extractPath)
End Sub)
' 완료
lblStatus.Text = "압축 해제 완료!"
lblPercentage.Text = "100%"
progressBar.Value = 100
Application.DoEvents()
' 잠시 대기 후 폼 닫기
Await Task.Delay(500)
Me.DialogResult = DialogResult.OK
Me.Close()
Catch ex As Exception
lblStatus.Text = "오류 발생: " & ex.Message
MessageBox.Show("압축 해제 중 오류가 발생했습니다: " & ex.Message, "오류", MessageBoxButtons.OK, MessageBoxIcon.Error)
Me.DialogResult = DialogResult.Cancel
Me.Close()
End Try
End Sub
Private Sub ExtractZipWithProgress(zipPath As String, extractPath As String)
Using archive As ZipArchive = ZipFile.OpenRead(zipPath)
Dim totalEntries As Integer = archive.Entries.Count
Dim currentEntry As Integer = 0
For Each entry As ZipArchiveEntry In archive.Entries
currentEntry += 1
' UI 업데이트 (UI 스레드에서 실행)
Me.Invoke(Sub()
Dim percentage As Integer = CInt((currentEntry / totalEntries) * 100)
progressBar.Value = percentage
lblPercentage.Text = percentage.ToString() & "%"
lblStatus.Text = $"압축 해제 중... ({currentEntry}/{totalEntries}) {entry.Name}"
Application.DoEvents()
End Sub)
' 전체 경로 생성
Dim destinationPath As String = Path.Combine(extractPath, entry.FullName)
' 디렉토리 항목인 경우
If entry.FullName.EndsWith("/") OrElse entry.FullName.EndsWith("\") Then
Directory.CreateDirectory(destinationPath)
Continue For
End If
' 파일의 디렉토리가 없으면 생성
Dim directoryPath As String = Path.GetDirectoryName(destinationPath)
If Not Directory.Exists(directoryPath) Then
Directory.CreateDirectory(directoryPath)
End If
' 파일 추출
entry.ExtractToFile(destinationPath, True)
Next
End Using
End Sub
Private Sub Frm_WwwrootExtract_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
' 압축 해제가 진행 중일 때는 폼을 닫을 수 없도록 설정 (사용자가 X 버튼을 누른 경우)
If e.CloseReason = CloseReason.UserClosing AndAlso progressBar.Value < 100 Then
e.Cancel = True
MessageBox.Show("압축 해제가 진행 중입니다. 잠시만 기다려 주세요.", "알림", MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
End Sub
End Class

View File

@@ -91,6 +91,7 @@ Partial Class MdiMain
Me.CloseAllToolStripMenuItem = New System.Windows.Forms.ToolStripMenuItem() Me.CloseAllToolStripMenuItem = New System.Windows.Forms.ToolStripMenuItem()
Me.ArrangeIconsToolStripMenuItem = New System.Windows.Forms.ToolStripMenuItem() Me.ArrangeIconsToolStripMenuItem = New System.Windows.Forms.ToolStripMenuItem()
Me.btcustomprofile = New System.Windows.Forms.ToolStripMenuItem() Me.btcustomprofile = New System.Windows.Forms.ToolStripMenuItem()
Me.btManual = New System.Windows.Forms.ToolStripMenuItem()
Me.TreeView1 = New System.Windows.Forms.TreeView() Me.TreeView1 = New System.Windows.Forms.TreeView()
Me.ContextMenuStrip1 = New System.Windows.Forms.ContextMenuStrip(Me.components) Me.ContextMenuStrip1 = New System.Windows.Forms.ContextMenuStrip(Me.components)
Me.그룹추가ToolStripMenuItem = New System.Windows.Forms.ToolStripMenuItem() Me.그룹추가ToolStripMenuItem = New System.Windows.Forms.ToolStripMenuItem()
@@ -109,7 +110,6 @@ 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.데이터비교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.StatusStrip1.SuspendLayout()
Me.MenuStrip1.SuspendLayout() Me.MenuStrip1.SuspendLayout()
Me.ContextMenuStrip1.SuspendLayout() Me.ContextMenuStrip1.SuspendLayout()
@@ -179,7 +179,7 @@ Partial Class MdiMain
'MenuStrip1 'MenuStrip1
' '
Me.MenuStrip1.Font = New System.Drawing.Font("돋움", 9.0!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(129, Byte)) 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.ManualToolStripMenuItem}) 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.btManual})
Me.MenuStrip1.Location = New System.Drawing.Point(0, 0) Me.MenuStrip1.Location = New System.Drawing.Point(0, 0)
Me.MenuStrip1.MdiWindowListItem = Me.WindowsMenu Me.MenuStrip1.MdiWindowListItem = Me.WindowsMenu
Me.MenuStrip1.Name = "MenuStrip1" Me.MenuStrip1.Name = "MenuStrip1"
@@ -555,6 +555,14 @@ Partial Class MdiMain
Me.btcustomprofile.Text = "커스텀프로필" Me.btcustomprofile.Text = "커스텀프로필"
Me.btcustomprofile.Visible = False Me.btcustomprofile.Visible = False
' '
'btManual
'
Me.btManual.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right
Me.btManual.Image = CType(resources.GetObject("btManual.Image"), System.Drawing.Image)
Me.btManual.Name = "btManual"
Me.btManual.Size = New System.Drawing.Size(69, 20)
Me.btManual.Text = "설명서"
'
'TreeView1 'TreeView1
' '
Me.TreeView1.ContextMenuStrip = Me.ContextMenuStrip1 Me.TreeView1.ContextMenuStrip = Me.ContextMenuStrip1
@@ -697,13 +705,6 @@ Partial Class MdiMain
Me.순실체적ToolStripMenuItem.Size = New System.Drawing.Size(170, 22) Me.순실체적ToolStripMenuItem.Size = New System.Drawing.Size(170, 22)
Me.순실체적ToolStripMenuItem.Text = "3.순실체적" 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 'MdiMain
' '
Me.AutoScaleDimensions = New System.Drawing.SizeF(7.0!, 12.0!) Me.AutoScaleDimensions = New System.Drawing.SizeF(7.0!, 12.0!)
@@ -829,5 +830,5 @@ Partial Class MdiMain
Friend WithEvents BatchUpdateProfileToolStripMenuItem As System.Windows.Forms.ToolStripMenuItem Friend WithEvents BatchUpdateProfileToolStripMenuItem As System.Windows.Forms.ToolStripMenuItem
Friend WithEvents btcustomprofile As System.Windows.Forms.ToolStripMenuItem Friend WithEvents btcustomprofile As System.Windows.Forms.ToolStripMenuItem
Friend WithEvents btMacro2 As System.Windows.Forms.ToolStripMenuItem Friend WithEvents btMacro2 As System.Windows.Forms.ToolStripMenuItem
Friend WithEvents ManualToolStripMenuItem As ToolStripMenuItem Friend WithEvents btManual As ToolStripMenuItem
End Class End Class

View File

@@ -127,6 +127,31 @@
<value>235, 17</value> <value>235, 17</value>
</metadata> </metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> <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"> <data name="ReportToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value> <value>
R0lGODlhEAAQAIQfAOvGUf7ztuvPMf/78/fkl/Pbg+u8Rvjqteu2Pf3zxPz36Pz0z+vTmPzurPvuw/np R0lGODlhEAAQAIQfAOvGUf7ztuvPMf/78/fkl/Pbg+u8Rvjqteu2Pf3zxPz36Pz0z+vTmPzurPvuw/np
@@ -225,29 +250,25 @@
h+wQKpVKnLQN/mV+AQV66PCS6TFTAAAAAElFTkSuQmCC h+wQKpVKnLQN/mV+AQV66PCS6TFTAAAAAElFTkSuQmCC
</value> </value>
</data> </data>
<data name="bt_filesave.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> <data name="btManual.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> <value>
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
AElFTkSuQmCC
</value> </value>
</data> </data>
<metadata name="ContextMenuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> <metadata name="ContextMenuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
@@ -330,73 +351,73 @@
<data name="ToolStripButton2.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> <data name="ToolStripButton2.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value> <value>
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
k1iG/rMj4QAAAABJRU5ErkJggg== WG90MeopAAAAAElFTkSuQmCC
</value> </value>
</data> </data>
<data name="ToolStripButton3.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> <data name="ToolStripButton3.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">

View File

@@ -1,5 +1,4 @@
Imports System.IO Imports System.IO
Imports Eco2Ar.WebServer
Public Class MdiMain Public Class MdiMain
@@ -21,17 +20,9 @@ Public Class MdiMain
'''현재열려있는폼의 이름을 변경한다. '''현재열려있는폼의 이름을 변경한다.
Public OpenedForm As E_MenuIdx = E_MenuIdx.NONE 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 Private Sub MdiMain_FormClosed(sender As Object, e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
pLog.Add("FormClosed", True) pLog.Add("FormClosed", True)
' 웹 서버 정리
If webServer IsNot Nothing Then
webServer.Stop()
webServer.Dispose()
End If
End Sub End Sub
Private Sub MdiMain_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing Private Sub MdiMain_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
@@ -95,7 +86,8 @@ Public Class MdiMain
Refresh_info() Refresh_info()
'// wwwroot 폴더 확인 및 압축 해제
CheckAndExtractWwwroot()
Read_SEtting() '//환경설정을 가져온다. Splah를 변경했따. Read_SEtting() '//환경설정을 가져온다. Splah를 변경했따.
Read_FilHistory() '//파일사용내역 Read_FilHistory() '//파일사용내역
@@ -252,19 +244,6 @@ Public Class MdiMain
pLog.Add("Program Start") 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 체크 ' WebView2 Fixed Version 체크
CheckWebView2Runtime() CheckWebView2Runtime()
@@ -313,6 +292,59 @@ Public Class MdiMain
End Sub End Sub
Private Sub CheckAndExtractWwwroot()
Try
' wwwroot 폴더 경로 확인
Dim templatePath As String = Path.Combine(Application.StartupPath, "Template")
If System.IO.Directory.Exists(templatePath) = False Then Return
Dim zipfiles() As String = System.IO.Directory.GetFiles(templatePath, "*.zip")
If zipfiles.Length = 0 Then Return
'압축파일 이름으로 폴더를 생성해서 압축을 해제한다.
For Each zipfilename As String In zipfiles
Dim nameOnly As String = System.IO.Path.GetFileNameWithoutExtension(zipfilename)
Dim zipcheckfile As String = zipfilename + ".complete"
Dim fi As New System.IO.FileInfo(zipfilename)
Dim completefileinfo As String = fi.LastWriteTime.ToString("yyyyMMddHHmmss.fff") + "|" + fi.Length.ToString()
If System.IO.File.Exists(zipcheckfile) Then
'//해당파일의 날짜와 용량이 내부에 기록되어있다 그정보가 틀리다면 진행을한다.
Dim fileinfo As String = System.IO.File.ReadAllText(zipcheckfile, System.Text.Encoding.UTF8).Trim()
If fileinfo.Equals(completefileinfo) Then
Continue For
End If
End If
Dim targetPath As New DirectoryInfo(Path.Combine(Application.StartupPath, nameOnly))
'//폴더가 존재하지 않는경우 생성
If targetPath.Exists = False Then targetPath.Create()
' 압축 해제 폼 표시
Dim extractForm As New Frm_WwwrootExtract(targetPath.FullName, zipfilename)
extractForm.ShowDialog()
' 압축 해제가 실패한 경우
If extractForm.DialogResult <> DialogResult.OK Then
MessageBox.Show("파일 압축 해제에 실패했습니다." & vbCrLf & "일부 기능이 제한될 수 있습니다.",
"경고", MessageBoxButtons.OK, MessageBoxIcon.Warning)
Else
System.IO.File.WriteAllText(zipcheckfile, completefileinfo, System.Text.Encoding.UTF8)
End If
Next
Catch ex As Exception
' 오류가 발생해도 프로그램은 계속 실행
MessageBox.Show("매뉴얼 파일 확인 중 오류가 발생했습니다: " & ex.Message,
"경고", MessageBoxButtons.OK, MessageBoxIcon.Warning)
End Try
End Sub
Private Sub bt_fileopen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Private Sub bt_fileopen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
End Sub End Sub
@@ -3990,15 +4022,23 @@ ENDSTAT: '//오류발생시 강제종료를 위한 분기문
Dim frmManual As Frm_WebManual = Nothing Dim frmManual As Frm_WebManual = Nothing
Private Sub ManualToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ManualToolStripMenuItem.Click Private Sub ManualToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles btManual.Click
Try
If frmManual Is Nothing OrElse frmManual.IsDisposed Then If frmManual Is Nothing OrElse frmManual.IsDisposed Then
frmManual = New Frm_WebManual() frmManual = New Frm_WebManual()
frmManual.Show()
End If End If
If frmManual.WindowState = FormWindowState.Minimized Then If frmManual.WindowState = FormWindowState.Minimized Then
frmManual.WindowState = FormWindowState.Normal frmManual.WindowState = FormWindowState.Normal
End If End If
frmManual.Show()
frmManual.Activate() frmManual.Activate()
Catch ex As Exception
MessageBox.Show("매뉴얼 표시 중 오류가 발생했습니다: " & ex.Message,
"오류", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub End Sub
''' <summary> ''' <summary>

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,244 +0,0 @@
' 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

@@ -1,50 +0,0 @@
=====================================================
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

@@ -1,126 +0,0 @@
# 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

@@ -1,190 +0,0 @@
# 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

@@ -1,93 +0,0 @@
' 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

@@ -1,175 +0,0 @@
' 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

Binary file not shown.

View File

@@ -1,9 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <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="Microsoft.Web.WebView2" version="1.0.3537.50" targetFramework="net48" />
<package id="Owin" version="1.0" targetFramework="net40" />
</packages> </packages>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff