Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -339,4 +339,6 @@ ASALocalRun/
# BeatPulse healthcheck temp database
healthchecksdb

uTablePackage/
uTablePackage/*
!uTablePackage/
!uTablePackage/Package.appxmanifest
40 changes: 40 additions & 0 deletions uTablePackage/Package.appxmanifest
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3"
xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
IgnorableNamespaces="uap uap3 desktop rescap">
<Identity Name="49490PBJSoftware.uTable" Publisher="CN=998C84B6-4B4D-482F-B102-3947ACC42DA7" Version="1.9.1.0" ProcessorArchitecture="neutral" />
<Properties>
<DisplayName>uTable</DisplayName>
<PublisherDisplayName>PBJSoftware</PublisherDisplayName>
<Logo>Images\StoreLogo.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.17763.0" MaxVersionTested="10.0.26100.0" />
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.17763.0" MaxVersionTested="10.0.26100.0" />
</Dependencies>
<Resources>
<Resource Language="KO-KR" />
</Resources>
<Applications>
<Application Id="App" Executable="uTable\uTable.exe" EntryPoint="Windows.FullTrustApplication">
<uap:VisualElements DisplayName="uTable" Description="대학생을 위한 PC 시간표 프로그램" BackgroundColor="transparent" Square150x150Logo="Images\Square150x150Logo.png" Square44x44Logo="Images\Square44x44Logo.png">
<uap:DefaultTile Wide310x150Logo="Images\Wide310x150Logo.png" Square71x71Logo="Images\SmallTile.png" Square310x310Logo="Images\LargeTile.png" />
<uap:SplashScreen Image="Images\SplashScreen.png" />
</uap:VisualElements>
<Extensions>
<uap3:Extension Category="windows.appExecutionAlias" Executable="uTable\uTable.exe" EntryPoint="Windows.FullTrustApplication">
<uap3:AppExecutionAlias>
<desktop:ExecutionAlias Alias="uTable.exe" />
</uap3:AppExecutionAlias>
</uap3:Extension>
</Extensions>
</Application>
</Applications>
<Capabilities>
<Capability Name="internetClient" />
<rescap:Capability Name="runFullTrust" />
</Capabilities>
</Package>
4 changes: 4 additions & 0 deletions utable/ApplicationEvents.vb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ Namespace My
' NetworkAvailabilityChanged: 네트워크가 연결되거나 연결이 끊어질 때 발생합니다.
Partial Friend Class MyApplication

Private Sub MyApplication_Startup(sender As Object, e As StartupEventArgs) Handles Me.Startup
MigrateStoreStartupShortcut()
End Sub

Private Sub MyApplication_UnhandledException(sender As Object, e As UnhandledExceptionEventArgs) Handles Me.UnhandledException
e.ExitApplication = False
ErrorForm.RichTextBox1.Text = e.Exception.Message + vbCr + "=====" + vbCr + DateTime.Now.ToString + vbCr + vbCr + e.Exception.ToString
Expand Down
77 changes: 51 additions & 26 deletions utable/Forms/DLLDownloader.vb
Original file line number Diff line number Diff line change
@@ -1,22 +1,16 @@
Imports System.Net

Imports System.IO
Imports System.IO.Compression

Public Class DLLDownloader

Dim colorMode As String = Nothing
Dim WithEvents wc As New Net.WebClient
Dim downComplete As Boolean = False

Dim exeFullpath As String = Application.ExecutablePath
Dim finalDir As String = exeFullpath.Substring(0, exeFullpath.LastIndexOf("\"))

Const repoLink As String = "https://github.com/pdjdev/uTable/raw/master/res/webview2dlls/"

Dim downList As New List(Of String) From
{"Microsoft.Web.WebView2.Core.dll",
"Microsoft.Web.WebView2.WinForms.dll",
"WebView2Loader.dll"}

Dim downCount As Integer = 1
' WebView2 SDK의 공식 NuGet 패키지
Const webView2PackageUrl As String = "https://api.nuget.org/v3-flatcontainer/microsoft.web.webview2/1.0.1774.30/microsoft.web.webview2.1.0.1774.30.nupkg"

#Region "Aero 그림자 효과 (Vista이상)"

Expand Down Expand Up @@ -47,32 +41,63 @@ Public Class DLLDownloader
MainLabel.ForeColor = theme.Text

End Sub
Sub DownloadFiles()
For Each fileName In downList
MainLabel.Text = $"다운로드 중... ({downCount}/{downList.Count}):" + vbCr + fileName
Private Function DownloadFiles() As Boolean
Dim packagePath = Path.Combine(Path.GetTempPath(), "uTable-WebView2-" & Guid.NewGuid().ToString("N") & ".nupkg")
Dim files As New Dictionary(Of String, String) From {
{"lib/net45/Microsoft.Web.WebView2.Core.dll", "Microsoft.Web.WebView2.Core.dll"},
{"lib/net45/Microsoft.Web.WebView2.WinForms.dll", "Microsoft.Web.WebView2.WinForms.dll"},
{"runtimes/win-x86/native/WebView2Loader.dll", "runtimes/win-x86/native/WebView2Loader.dll"},
{"runtimes/win-x64/native/WebView2Loader.dll", "runtimes/win-x64/native/WebView2Loader.dll"},
{"runtimes/win-arm64/native/WebView2Loader.dll", "runtimes/win-arm64/native/WebView2Loader.dll"}
}

Try
MainLabel.Text = "필요 요소 다운로드 중..." + vbCr + "Microsoft.Web.WebView2"
Refresh()
Threading.Thread.Sleep(100)
Try
Dim client As New WebClient()
client.DownloadFile(repoLink & fileName, finalDir & "\" & fileName)
Catch ex As Exception
MainLabel.Text = $"작업 실패... ({downCount}/{downList.Count}):" + vbCr + fileName
End Try
downCount += 1
Next
End Sub
Using client As New WebClient()
client.DownloadFile(webView2PackageUrl, packagePath)
End Using

Using package = ZipFile.OpenRead(packagePath)
Dim count = 1
For Each file In files
MainLabel.Text = $"필요 요소 설치 중... ({count}/{files.Count}):" + vbCr + Path.GetFileName(file.Value)
Refresh()
Dim entry = package.GetEntry(file.Key)
If entry Is Nothing Then Throw New InvalidDataException("WebView2 패키지에 필요한 파일이 없습니다: " & file.Key)

Dim destination = Path.Combine(finalDir, file.Value.Replace("/", "\"))
Directory.CreateDirectory(Path.GetDirectoryName(destination))
entry.ExtractToFile(destination, True)
count += 1
Next
End Using
Return True
Catch ex As Exception
MainLabel.Text = "작업 실패: " + ex.Message
Return False
Finally
If File.Exists(packagePath) Then File.Delete(packagePath)
End Try
End Function

Private Sub DLLDownloader_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Opacity = 0
UpdateColor()
End Sub

Private Sub DLLDownloader_Shown(sender As Object, e As EventArgs) Handles Me.Shown
DownloadFiles()
If Not DownloadFiles() Then
MsgBox("다운로드 실패! 인터넷 연결과 실행 폴더의 쓰기 권한을 확인해 주세요.", vbExclamation)
Close()
Return
End If

If Not (My.Computer.FileSystem.FileExists(finalDir + "\Microsoft.Web.WebView2.Core.dll") And
My.Computer.FileSystem.FileExists(finalDir + "\Microsoft.Web.WebView2.WinForms.dll") And
My.Computer.FileSystem.FileExists(finalDir + "\WebView2Loader.dll")) Then
My.Computer.FileSystem.FileExists(finalDir + "\runtimes\win-x86\native\WebView2Loader.dll") And
My.Computer.FileSystem.FileExists(finalDir + "\runtimes\win-x64\native\WebView2Loader.dll") And
My.Computer.FileSystem.FileExists(finalDir + "\runtimes\win-arm64\native\WebView2Loader.dll")) Then
MsgBox("다운로드 실패!", vbExclamation)
Close()
Else
Expand Down
16 changes: 14 additions & 2 deletions utable/Forms/TableForm.vb
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,16 @@ Public Class TableForm

#Region "Aero 그림자 효과 (Vista이상)"

'테두리는 숨긴 채 WS_MINIMIZEBOX만 다시 추가하여 작업 표시줄 버튼으로 최소화/복원 구현
Protected Overrides ReadOnly Property CreateParams As CreateParams
Get
Const WS_MINIMIZEBOX As Integer = &H20000
Dim nativeParams As CreateParams = MyBase.CreateParams
nativeParams.Style = nativeParams.Style Or WS_MINIMIZEBOX
Return nativeParams
End Get
End Property

Protected Overrides Sub OnHandleCreated(e As EventArgs)
CreateDropShadow(Me)
MyBase.OnHandleCreated(e)
Expand Down Expand Up @@ -824,8 +834,10 @@ Public Class TableForm

If Not (My.Computer.FileSystem.FileExists(finalDir + "\Microsoft.Web.WebView2.Core.dll") And
My.Computer.FileSystem.FileExists(finalDir + "\Microsoft.Web.WebView2.WinForms.dll") And
My.Computer.FileSystem.FileExists(finalDir + "\WebView2Loader.dll")) Then
If MsgBox("에브리타임 시간표를 불러오기 위해서는 추가적인 다운로드(0.6MB)가 필요합니다. 파일은 uTable이 실행된 위치에 저장됩니다." _
My.Computer.FileSystem.FileExists(finalDir + "\runtimes\win-x86\native\WebView2Loader.dll") And
My.Computer.FileSystem.FileExists(finalDir + "\runtimes\win-x64\native\WebView2Loader.dll") And
My.Computer.FileSystem.FileExists(finalDir + "\runtimes\win-arm64\native\WebView2Loader.dll")) Then
If MsgBox("에브리타임 시간표를 불러오기 위해서는 추가적인 다운로드(약 3MB)가 필요합니다. 파일은 uTable이 실행된 위치에 저장됩니다." _
+ vbCr + vbCr + "'확인'을 누르면 다운로드 및 불러오기 작업이 진행되며, '취소'를 누르면 작업이 중단됩니다.", vbOKCancel + vbInformation, "다운로드 필요") = vbOK Then
DLLDownloader.ShowDialog(Me)
End If
Expand Down
101 changes: 77 additions & 24 deletions utable/Modules/WinModule.vb
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ Module WinModule

#Region "시작프로그램설정"

Private Const ShortcutName As String = "\uTable.lnk"
Private Const ShortcutFileName As String = "uTable.lnk"
Private Const AppLaunchCmd As String = "C:\Windows\explorer.exe"
Private Const AppCode As String = "shell:appsFolder\49490PBJSoftware.uTable_fv4zvza0919de!App"
Private Const StoreAliasName As String = "uTable.exe"
Private Const ErrorInsufficientBuffer As Integer = 122

<Runtime.InteropServices.DllImport("kernel32.dll", CharSet:=Runtime.InteropServices.CharSet.Unicode)>
Expand Down Expand Up @@ -33,50 +34,102 @@ Module WinModule
End Get
End Property

Private ReadOnly Property StoreAliasPath As String
Get
Return IO.Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
"Microsoft",
"WindowsApps",
StoreAliasName)
End Get
End Property

Private ReadOnly Property StartupShortcutPath As String
Get
Return IO.Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.Startup),
ShortcutFileName)
End Get
End Property

Public Function checkStartUp() As Boolean
Dim destlnk As String = Environment.GetFolderPath(Environment.SpecialFolder.Startup) & ShortcutName
If Not IO.File.Exists(destlnk) Then Return False
If Not IO.File.Exists(StartupShortcutPath) Then Return False

Dim wsh As Object = CreateObject("WScript.Shell")
Dim shortcut As Object = wsh.CreateShortcut(destlnk)
Dim targetPath As String = CStr(shortcut.TargetPath)
Dim arguments As String = CStr(shortcut.Arguments).Trim()
Dim targetPath As String = Nothing
Dim arguments As String = Nothing
If Not TryReadStartupShortcut(targetPath, arguments) Then Return False

' MSIX 바로가기는 Explorer가 AppsFolder 경로를 실행한다.
If IsStoreApp AndAlso PathsEqual(targetPath, AppLaunchCmd) AndAlso
String.Equals(arguments, AppCode, StringComparison.OrdinalIgnoreCase) Then Return True
If IsStoreApp Then
Return PathsEqual(targetPath, StoreAliasPath) AndAlso String.IsNullOrEmpty(arguments)
End If

' 일반 exe 바로가기 및 이전 버전이 남긴 "exe + shell:appsFolder" 형식도 인정한다.
If Not PathsEqual(targetPath, Application.ExecutablePath) Then Return False
Return String.IsNullOrEmpty(arguments) OrElse arguments.StartsWith("shell:appsFolder\", StringComparison.OrdinalIgnoreCase)
Return String.IsNullOrEmpty(arguments)
End Function

Private Function TryReadStartupShortcut(ByRef targetPath As String, ByRef arguments As String) As Boolean
Try
Dim wsh As Object = CreateObject("WScript.Shell")
Dim shortcut As Object = wsh.CreateShortcut(StartupShortcutPath)
targetPath = CStr(shortcut.TargetPath)
arguments = CStr(shortcut.Arguments).Trim()
Return True
Catch
Return False
End Try
End Function

Private Function PathsEqual(firstPath As String, secondPath As String) As Boolean
Return String.Equals(IO.Path.GetFullPath(firstPath).TrimEnd("\"c),
IO.Path.GetFullPath(secondPath).TrimEnd("\"c),
StringComparison.OrdinalIgnoreCase)
Try
Return String.Equals(IO.Path.GetFullPath(firstPath).TrimEnd("\"c),
IO.Path.GetFullPath(secondPath).TrimEnd("\"c),
StringComparison.OrdinalIgnoreCase)
Catch
Return False
End Try
End Function

Sub SetStartup()
Dim path As String = Environment.GetFolderPath(Environment.SpecialFolder.Startup) & ShortcutName
Dim wsh As Object = CreateObject("WScript.Shell")
Dim myShortcut As Object = wsh.CreateShortcut(path)
Dim targetPath As String

If IsStoreApp Then
myShortcut.TargetPath = wsh.ExpandEnvironmentStrings(AppLaunchCmd)
myShortcut.Arguments = AppCode
targetPath = StoreAliasPath
If Not IO.File.Exists(targetPath) Then
Throw New InvalidOperationException("uTable 앱 실행 별칭을 찾을 수 없습니다: " & targetPath)
End If
Else
myShortcut.TargetPath = wsh.ExpandEnvironmentStrings(Application.ExecutablePath)
myShortcut.Arguments = ""
targetPath = Application.ExecutablePath
End If

Dim wsh As Object = CreateObject("WScript.Shell")
Dim myShortcut As Object = wsh.CreateShortcut(StartupShortcutPath)
myShortcut.TargetPath = targetPath
myShortcut.Arguments = ""
myShortcut.WorkingDirectory = IO.Path.GetDirectoryName(targetPath)
myShortcut.WindowStyle = 4
myShortcut.Save()
End Sub

Public Sub MigrateStoreStartupShortcut()
If Not IsStoreApp Then Return
If Not IO.File.Exists(StartupShortcutPath) Then Return

Dim targetPath As String = Nothing
Dim arguments As String = Nothing
If Not TryReadStartupShortcut(targetPath, arguments) Then Return

If PathsEqual(targetPath, AppLaunchCmd) AndAlso
String.Equals(arguments, AppCode, StringComparison.OrdinalIgnoreCase) Then
Try
SetStartup()
Catch
' 기존 바로가기를 교체하지 못해도 앱 실행은 계속한다.
End Try
End If
End Sub

Sub RemoveStartup()
Dim path As String = Environment.GetFolderPath(Environment.SpecialFolder.Startup) & ShortcutName
If IO.File.Exists(path) Then My.Computer.FileSystem.DeleteFile(path)
If IO.File.Exists(StartupShortcutPath) Then My.Computer.FileSystem.DeleteFile(StartupShortcutPath)
End Sub

#End Region
Expand Down
Loading
Loading