Application.xaml.vb 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. Imports System.Net
  2. Imports System.Reflection
  3. Imports System.Windows.Threading
  4. Public Class Application
  5. #If DEBUG Then
  6. ''' <summary>
  7. ''' 用于开始程序时的一些测试。
  8. ''' </summary>
  9. Private Sub Test()
  10. Try
  11. ModDevelop.Start()
  12. Catch ex As Exception
  13. Log(ex, "开发者模式测试出错", LogLevel.Feedback)
  14. End Try
  15. End Sub
  16. #End If
  17. '开始
  18. Private Sub Application_Startup(sender As Object, e As StartupEventArgs) Handles Me.Startup
  19. ApplicationStartTick = GetTimeTick()
  20. SecretOnApplicationStart()
  21. Try
  22. '检查参数调用
  23. If e.Args.Length > 0 Then
  24. If e.Args(0) = "--update" Then
  25. '自动更新
  26. UpdateReplace(e.Args(1), e.Args(2).Trim(""""), e.Args(3).Trim(""""), e.Args(4))
  27. Environment.Exit(Result.Cancel)
  28. 'ElseIf e.Args(0).StartsWith("--link") Then
  29. ' '稍作等待后切换到联机页面
  30. ' Thread.Sleep(1000)
  31. ' FormMain.IsLinkRestart = True
  32. ElseIf e.Args(0).StartsWith("--memory") Then
  33. '内存优化
  34. Dim Ram = My.Computer.Info.AvailablePhysicalMemory
  35. Try
  36. PageOtherTest.MemoryOptimizeInternal()
  37. Catch ex As Exception
  38. MsgBox(ex.Message, MsgBoxStyle.Critical, "内存优化失败")
  39. Environment.Exit(-1)
  40. End Try
  41. Ram = My.Computer.Info.AvailablePhysicalMemory - Ram
  42. Environment.Exit(Math.Max(0, Ram / 1024)) '返回清理的内存量(K)
  43. #If DEBUG Then
  44. ElseIf e.Args(0) = "--make" Then
  45. '制作更新包
  46. UpdateMake(e.Args(1))
  47. Environment.Exit(Result.Cancel)
  48. #End If
  49. End If
  50. End If
  51. '初始化文件结构
  52. Directory.CreateDirectory(Path & "PCL\Pictures")
  53. Directory.CreateDirectory(Path & "PCL\Musics")
  54. Try
  55. Directory.CreateDirectory(PathTemp)
  56. If Not CheckPermission(PathTemp) Then Throw New Exception("PCL 没有对 " & PathTemp & " 的访问权限")
  57. Catch ex As Exception
  58. If PathTemp = IO.Path.GetTempPath() & "PCL\" Then
  59. MyMsgBox("PCL 无法访问缓存文件夹,可能导致程序出错或无法正常使用!" & vbCrLf & "错误原因:" & GetExceptionDetail(ex), "缓存文件夹不可用")
  60. Else
  61. MyMsgBox("手动设置的缓存文件夹不可用,PCL 将使用默认缓存文件夹。" & vbCrLf & "错误原因:" & GetExceptionDetail(ex), "缓存文件夹不可用")
  62. Setup.Set("SystemSystemCache", "")
  63. PathTemp = IO.Path.GetTempPath() & "PCL\"
  64. End If
  65. End Try
  66. Directory.CreateDirectory(PathTemp & "Cache")
  67. Directory.CreateDirectory(PathTemp & "Download")
  68. Directory.CreateDirectory(PathAppdata)
  69. '检测单例
  70. #If Not DEBUG Then
  71. Dim WindowHwnd As IntPtr = FindWindow(Nothing, "Plain Craft Launcher 2 ")
  72. If WindowHwnd <> IntPtr.Zero Then
  73. '将已有的 PCL 窗口拖出来
  74. ShowWindowToTop(WindowHwnd)
  75. '播放提示音并退出
  76. Beep()
  77. Environment.[Exit](Result.Cancel)
  78. End If
  79. #End If
  80. '设置 ToolTipService 默认值
  81. ToolTipService.InitialShowDelayProperty.OverrideMetadata(GetType(DependencyObject), New FrameworkPropertyMetadata(300))
  82. ToolTipService.BetweenShowDelayProperty.OverrideMetadata(GetType(DependencyObject), New FrameworkPropertyMetadata(400))
  83. ToolTipService.ShowDurationProperty.OverrideMetadata(GetType(DependencyObject), New FrameworkPropertyMetadata(9999999))
  84. ToolTipService.PlacementProperty.OverrideMetadata(GetType(DependencyObject), New FrameworkPropertyMetadata(Primitives.PlacementMode.Bottom))
  85. ToolTipService.HorizontalOffsetProperty.OverrideMetadata(GetType(DependencyObject), New FrameworkPropertyMetadata(8.0))
  86. ToolTipService.VerticalOffsetProperty.OverrideMetadata(GetType(DependencyObject), New FrameworkPropertyMetadata(4.0))
  87. '设置初始窗口
  88. If Setup.Get("UiLauncherLogo") AndAlso Not FormMain.IsLinkRestart Then
  89. FrmStart = New SplashScreen("Images\icon.ico")
  90. FrmStart.Show(False, True)
  91. End If
  92. '动态 DLL 调用
  93. AddHandler AppDomain.CurrentDomain.AssemblyResolve, AddressOf AssemblyResolve
  94. '日志初始化
  95. LogStart()
  96. '添加日志
  97. Log("[Start] 程序版本:" & VersionDisplayName & "(" & VersionCode & ")")
  98. Log("[Start] 识别码:" & UniqueAddress & If(ThemeCheckOne(9), ",已解锁反馈主题", ""))
  99. Log("[Start] 程序路径:" & PathWithName)
  100. '检测压缩包运行
  101. If Path.Contains(IO.Path.GetTempPath()) OrElse Path.Contains("AppData\Local\Temp\") Then
  102. MyMsgBox("PCL 正在临时文件夹运行,设置、游戏存档等很可能无法保存,且部分功能会无法使用或出错。" & vbCrLf & "请将 PCL 从压缩文件中解压,或是更换文件夹后再继续使用!", "环境警告", "我知道了", IsWarn:=True)
  103. End If
  104. '设置初始化
  105. Setup.Load("SystemDebugMode")
  106. Setup.Load("SystemDebugAnim")
  107. Setup.Load("ToolDownloadThread")
  108. '网络配置初始化
  109. ServicePointManager.Expect100Continue = True
  110. ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 Or SecurityProtocolType.Tls Or SecurityProtocolType.Tls11 Or SecurityProtocolType.Tls12
  111. ServicePointManager.DefaultConnectionLimit = 1024
  112. ServicePointManager.ServerCertificateValidationCallback = New Security.RemoteCertificateValidationCallback(Function() As Boolean
  113. Return True
  114. End Function)
  115. '计时
  116. Log("[Start] 第一阶段加载用时:" & GetTimeTick() - ApplicationStartTick & " ms")
  117. ApplicationStartTick = GetTimeTick()
  118. '执行测试
  119. #If DEBUG Then
  120. Test()
  121. #End If
  122. AniControlEnabled += 1
  123. Catch ex As Exception
  124. MsgBox(GetExceptionDetail(ex, True), MsgBoxStyle.Critical, "PCL 初始化错误")
  125. FormMain.EndProgramForce(Result.Exception)
  126. End Try
  127. End Sub
  128. '结束
  129. Private Sub Application_SessionEnding(sender As Object, e As SessionEndingCancelEventArgs) Handles Me.SessionEnding
  130. FrmMain.EndProgram(False)
  131. End Sub
  132. '异常
  133. Private IsCritErrored As Boolean = False
  134. Private Sub Application_DispatcherUnhandledException(sender As Object, e As DispatcherUnhandledExceptionEventArgs) Handles Me.DispatcherUnhandledException
  135. On Error Resume Next
  136. e.Handled = True
  137. If IsProgramEnded Then Exit Sub
  138. If IsCritErrored Then
  139. '在汇报错误后继续引发错误,知道这次压不住了
  140. FormMain.EndProgramForce(Result.Exception)
  141. Exit Sub
  142. End If
  143. IsCritErrored = True
  144. Dim ExceptionString As String = GetExceptionDetail(e.Exception, True)
  145. If ExceptionString.Contains("System.Windows.Threading.Dispatcher.Invoke") OrElse
  146. ExceptionString.Contains("MS.Internal.AppModel.ITaskbarList.HrInit") OrElse
  147. ExceptionString.Contains(".NET Framework") OrElse ' “自动错误判断” 的结果分析
  148. ExceptionString.Contains("未能加载文件或程序集") Then
  149. OpenWebsite("https://dotnet.microsoft.com/zh-cn/download/dotnet-framework/thank-you/net462-offline-installer")
  150. MsgBox("你的 .NET Framework 版本过低或损坏,请在打开的网页中重新下载并安装 .NET Framework 4.6.2 后重试!", MsgBoxStyle.Information, "运行环境错误")
  151. FormMain.EndProgramForce(Result.Cancel)
  152. Else
  153. FeedbackInfo()
  154. Log(e.Exception, "程序出现未知错误", LogLevel.Assert, "锟斤拷烫烫烫")
  155. End If
  156. End Sub
  157. '动态 DLL 调用
  158. Private Shared AssemblyNAudio As Assembly
  159. Private Shared AssemblyJson As Assembly
  160. Private Shared AssemblyDialog As Assembly
  161. Private Shared ReadOnly AssemblyNAudioLock As New Object
  162. Private Shared ReadOnly AssemblyJsonLock As New Object
  163. Private Shared ReadOnly AssemblyDialogLock As New Object
  164. Public Shared Function AssemblyResolve(sender As Object, args As ResolveEventArgs) As Assembly
  165. If args.Name.StartsWith("NAudio") Then
  166. SyncLock AssemblyNAudioLock
  167. If AssemblyNAudio Is Nothing Then
  168. Log("[Start] 加载 DLL:NAudio")
  169. AssemblyNAudio = Assembly.Load(GetResources("NAudio"))
  170. End If
  171. Return AssemblyNAudio
  172. End SyncLock
  173. ElseIf args.Name.StartsWith("Newtonsoft.Json") Then
  174. SyncLock AssemblyJsonLock
  175. If AssemblyJson Is Nothing Then
  176. Log("[Start] 加载 DLL:Json")
  177. AssemblyJson = Assembly.Load(GetResources("Json"))
  178. End If
  179. Return AssemblyJson
  180. End SyncLock
  181. ElseIf args.Name.StartsWith("Ookii.Dialogs.Wpf") Then
  182. SyncLock AssemblyDialogLock
  183. If AssemblyDialog Is Nothing Then
  184. Log("[Start] 加载 DLL:Dialogs")
  185. AssemblyDialog = Assembly.Load(GetResources("Dialogs"))
  186. End If
  187. Return AssemblyDialog
  188. End SyncLock
  189. Else
  190. Return Nothing
  191. End If
  192. End Function
  193. '切换窗口
  194. '控件模板事件
  195. Private Sub MyIconButton_Click(sender As Object, e As EventArgs)
  196. Select Case Setup.Get("LoginType")
  197. Case McLoginType.Ms
  198. '微软
  199. Dim MsJson As JObject = GetJson(Setup.Get("LoginMsJson"))
  200. MsJson.Remove(sender.Tag)
  201. Setup.Set("LoginMsJson", MsJson.ToString(Newtonsoft.Json.Formatting.None))
  202. FrmLoginMs.ComboAccounts.Items.Remove(sender.Parent)
  203. Case McLoginType.Legacy
  204. '离线
  205. Dim Names As New List(Of String)
  206. Names.AddRange(Setup.Get("LoginLegacyName").ToString.Split("¨"))
  207. Names.Remove(sender.Tag)
  208. Setup.Set("LoginLegacyName", Join(Names, "¨"))
  209. FrmLoginLegacy.ComboName.ItemsSource = Names
  210. FrmLoginLegacy.ComboName.Text = If(Names.Count > 0, Names(0), "")
  211. Case Else
  212. '第三方
  213. Dim Token As String = GetStringFromEnum(Setup.Get("LoginType"))
  214. Dim Dict As New Dictionary(Of String, String)
  215. Dim Names As New List(Of String)
  216. Dim Passs As New List(Of String)
  217. If Not Setup.Get("Login" & Token & "Email") = "" Then Names.AddRange(Setup.Get("Login" & Token & "Email").ToString.Split("¨"))
  218. If Not Setup.Get("Login" & Token & "Pass") = "" Then Passs.AddRange(Setup.Get("Login" & Token & "Pass").ToString.Split("¨"))
  219. For i = 0 To Names.Count - 1
  220. Dict.Add(Names(i), Passs(i))
  221. Next
  222. Dict.Remove(sender.Tag)
  223. Setup.Set("Login" & Token & "Email", Join(Dict.Keys, "¨"))
  224. Setup.Set("Login" & Token & "Pass", Join(Dict.Values, "¨"))
  225. Select Case Token
  226. Case "Nide"
  227. FrmLoginNide.ComboName.ItemsSource = Dict.Keys
  228. FrmLoginNide.ComboName.Text = If(Dict.Keys.Count > 0, Dict.Keys(0), "")
  229. FrmLoginNide.TextPass.Password = If(Dict.Values.Count > 0, Dict.Values(0), "")
  230. Case "Auth"
  231. FrmLoginAuth.ComboName.ItemsSource = Dict.Keys
  232. FrmLoginAuth.ComboName.Text = If(Dict.Keys.Count > 0, Dict.Keys(0), "")
  233. FrmLoginAuth.TextPass.Password = If(Dict.Values.Count > 0, Dict.Values(0), "")
  234. End Select
  235. End Select
  236. End Sub
  237. End Class