Repository: Coxxs/LogoDiy
Branch: master
Commit: e80d6cff1d2e
Files: 23
Total size: 62.3 KB
Directory structure:
gitextract_bw9oxuo9/
├── .gitignore
├── Examples/
│ ├── 2560x1600.psd
│ └── Credit.txt
├── LogoDiy/
│ ├── App.config
│ ├── DiyHelper.cs
│ ├── EnumDisplayAttribute.cs
│ ├── EnumExtentions.cs
│ ├── Form1.Designer.cs
│ ├── Form1.cs
│ ├── Form1.resx
│ ├── LogHelper.cs
│ ├── LogoDiy.csproj
│ ├── LogoDiyViewModel.cs
│ ├── Program.cs
│ ├── Properties/
│ │ ├── AssemblyInfo.cs
│ │ ├── Resources.Designer.cs
│ │ ├── Resources.resx
│ │ ├── Settings.Designer.cs
│ │ └── Settings.settings
│ └── app.manifest
├── LogoDiy.sln
├── README.md
└── README.zh.md
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
================================================
FILE: Examples/Credit.txt
================================================
https://www.deviantart.com/ncoll36/art/Ayase-Aragaki-Oreimo-614404759
================================================
FILE: LogoDiy/App.config
================================================
================================================
FILE: LogoDiy/DiyHelper.cs
================================================
using System;
using System.Runtime.InteropServices;
namespace LogoDiy
{
public class DiyHelper
{
[DllImport("User32.dll")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("User32.dll")]
public static extern IntPtr SendMessage(int hWnd, int msg, IntPtr wParam, IntPtr lParam);
[DllImport("AIToolAPI.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int GetLogoDIYInfo(ref byte enable, ref uint format, ref int height, ref int width);
[DllImport("AIToolAPI.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int SetLogoDIYInfo(byte enable);
[DllImport("AIToolAPI.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int SetLogDIYCRC(string filepath);
[DllImport("AIToolAPI.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int IsEditionCircle();
[DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool Wow64DisableWow64FsRedirection(ref IntPtr ptr);
[DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool Wow64RevertWow64FsRedirection(IntPtr ptr);
}
}
================================================
FILE: LogoDiy/EnumDisplayAttribute.cs
================================================
using System;
[AttributeUsage(AttributeTargets.Field)]
public class EnumDisplayAttribute : Attribute
{
public string Display
{
get;
private set;
}
public EnumDisplayAttribute(string displayStr)
{
Display = displayStr;
}
}
================================================
FILE: LogoDiy/EnumExtentions.cs
================================================
using System;
using System.Linq;
public static class EnumExtentions
{
public static string Display(this Enum t)
{
Type type = t.GetType();
string name = Enum.GetName(type, t);
EnumDisplayAttribute enumDisplayAttribute = type.GetField(name).GetCustomAttributes(inherit: false).FirstOrDefault((object p) => p.GetType().Equals(typeof(EnumDisplayAttribute))) as EnumDisplayAttribute;
if (enumDisplayAttribute != null)
{
return enumDisplayAttribute.Display;
}
return name;
}
}
================================================
FILE: LogoDiy/Form1.Designer.cs
================================================
namespace LogoDiy
{
partial class Form1
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.SelectImage = new System.Windows.Forms.Button();
this.Apply = new System.Windows.Forms.Button();
this.Recovery = new System.Windows.Forms.Button();
this.checkBox1 = new System.Windows.Forms.CheckBox();
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// SelectImage
//
this.SelectImage.Location = new System.Drawing.Point(24, 22);
this.SelectImage.Name = "SelectImage";
this.SelectImage.Size = new System.Drawing.Size(199, 69);
this.SelectImage.TabIndex = 0;
this.SelectImage.Text = "Select Image";
this.SelectImage.UseVisualStyleBackColor = true;
this.SelectImage.Click += new System.EventHandler(this.button1_Click);
//
// Apply
//
this.Apply.Enabled = false;
this.Apply.Location = new System.Drawing.Point(244, 22);
this.Apply.Name = "Apply";
this.Apply.Size = new System.Drawing.Size(199, 69);
this.Apply.TabIndex = 1;
this.Apply.Text = "Apply";
this.Apply.UseVisualStyleBackColor = true;
this.Apply.Click += new System.EventHandler(this.button2_Click);
//
// Recovery
//
this.Recovery.Location = new System.Drawing.Point(771, 22);
this.Recovery.Name = "Recovery";
this.Recovery.Size = new System.Drawing.Size(199, 69);
this.Recovery.TabIndex = 2;
this.Recovery.Text = "Reset to default";
this.Recovery.UseVisualStyleBackColor = true;
this.Recovery.Click += new System.EventHandler(this.button1_Click_1);
//
// checkBox1
//
this.checkBox1.AutoSize = true;
this.checkBox1.Enabled = false;
this.checkBox1.Location = new System.Drawing.Point(495, 43);
this.checkBox1.Name = "checkBox1";
this.checkBox1.Size = new System.Drawing.Size(226, 29);
this.checkBox1.TabIndex = 3;
this.checkBox1.Text = "Show Loading Icon";
this.checkBox1.UseVisualStyleBackColor = true;
this.checkBox1.CheckedChanged += new System.EventHandler(this.checkBox1_CheckedChanged);
//
// label1
//
this.label1.AutoSize = true;
this.label1.ForeColor = System.Drawing.Color.DarkRed;
this.label1.Location = new System.Drawing.Point(763, 117);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(207, 25);
this.label1.TabIndex = 4;
this.label1.Text = "Use at your own risk";
//
// label2
//
this.label2.AutoSize = true;
this.label2.ForeColor = System.Drawing.Color.DarkRed;
this.label2.Location = new System.Drawing.Point(19, 117);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(156, 25);
this.label2.TabIndex = 5;
this.label2.Text = "Format: , Max: ";
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(12F, 25F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(997, 169);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.Controls.Add(this.checkBox1);
this.Controls.Add(this.Recovery);
this.Controls.Add(this.Apply);
this.Controls.Add(this.SelectImage);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
this.Name = "Form1";
this.Text = "LogoDiy";
this.Load += new System.EventHandler(this.Form1_Load);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button SelectImage;
private System.Windows.Forms.Button Apply;
private System.Windows.Forms.Button Recovery;
private System.Windows.Forms.CheckBox checkBox1;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
}
}
================================================
FILE: LogoDiy/Form1.cs
================================================
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace LogoDiy
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
LogoDiyViewModel.Instance.CreateViewData();
if (!LogoDiyViewModel.Instance.UIIsEnable)
{
MessageBox.Show("Unsupported BIOS!\nThis application only supports Lenovo computers with newer BIOS versions.");
Application.Exit();
return;
}
if (LogoDiyViewModel.Instance.VidibalyLodingIco)
{
checkBox1.Checked = LogoDiyViewModel.Instance.IsShowLodingIco;
checkBox1.Enabled = true;
}
label2.Text = "Format: " + LogoDiyViewModel.Instance.Filter + " / Max: " + LogoDiyViewModel.Instance.DefaultWidth.ToString() + "x" + LogoDiyViewModel.Instance.DefaultHeight.ToString();
}
private void button1_Click(object sender, EventArgs e)
{
LogoDiyViewModel.Instance.SelectedImageClick();
showTip();
}
private void button2_Click(object sender, EventArgs e)
{
LogoDiyViewModel.Instance.SaveLogoClick();
showTip();
}
private void showTip()
{
if (LogoDiyViewModel.Instance.ShowWarning)
{
MessageBox.Show(LogoDiyViewModel.Instance.ShowWarnInfo);
LogoDiyViewModel.Instance.ShowWarning = false;
}
if (LogoDiyViewModel.Instance.ShowSuccessTip)
{
MessageBox.Show(LogoDiyViewModel.Instance.ShowSuccessText);
LogoDiyViewModel.Instance.ShowSuccessTip = false;
}
Apply.Enabled = LogoDiyViewModel.Instance.FunEnable;
Recovery.Enabled = LogoDiyViewModel.Instance.CanRecovery;
}
private void button1_Click_1(object sender, EventArgs e)
{
LogoDiyViewModel.Instance.ToRecovery();
showTip();
}
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
if (!checkBox1.Enabled)
{
return;
}
if (LogoDiyViewModel.Instance.ChangeLodingIco(checkBox1.Checked))
{
MessageBox.Show("Done!");
} else
{
MessageBox.Show("Failed!");
}
}
}
}
================================================
FILE: LogoDiy/Form1.resx
================================================
text/microsoft-resx
2.0
System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
================================================
FILE: LogoDiy/LogHelper.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
namespace LogoDiy
{
class LogHelper
{
public static void Info(string info)
{
Console.WriteLine(info);
Debug.WriteLine(info);
}
public static void Error(string info)
{
Info(info);
}
public static void Error(Exception ex)
{
Info(ex.ToString());
}
}
}
================================================
FILE: LogoDiy/LogoDiy.csproj
================================================
Debug
AnyCPU
{3DF19333-D9AA-4CFD-8B0F-21DF0916508C}
WinExe
LogoDIY
LogoDIY
v4.7.2
512
true
true
AnyCPU
true
full
false
bin\Debug\
DEBUG;TRACE
prompt
4
AnyCPU
pdbonly
true
bin\Release\
TRACE
prompt
4
app.manifest
Form
Form1.cs
Form1.cs
ResXFileCodeGenerator
Resources.Designer.cs
Designer
True
Resources.resx
True
SettingsSingleFileGenerator
Settings.Designer.cs
True
Settings.settings
True
Always
================================================
FILE: LogoDiy/LogoDiyViewModel.cs
================================================
using System;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using System.Windows.Forms;
namespace LogoDiy
{
public class LogoDiyViewModel
{
public enum FileExtension
{
[EnumDisplay(".jpg")]
JPG = 255216,
[EnumDisplay(".gif")]
GIF = 7173,
[EnumDisplay(".png")]
PNG = 13780,
[EnumDisplay(".bmp")]
BMP = 19778,
[EnumDisplay(".bmp")]
BMP2 = 6677,
[EnumDisplay(".jpeg")]
JPEG = 65496
}
private enum ButtonStyle
{
JPG = 1,
TGA = 2,
PCX = 4,
GIF = 8,
BMP = 0x10,
PNG = 0x20
}
private static LogoDiyViewModel _instance;
private bool _IsShowLodingIco = true;
private bool vidibalyLodingIco;
private string _SupportingFormat = "jpg、jepg、bmp";
private double _ImageHeight = 140.0;
private double _ImageWidth = 224.0;
private bool _ShowWarning;
private string _ShowWarnInfo;
private bool _ShowSuccessTip;
private string showSuccessText = "";
private BitmapImage imageSource;
private bool _UIIsEnable = true;
private bool funEnable = true;
private long diskFreeSpace = 54525952L;
private bool canRecovery;
private string name;
private int defaultHeight = 1080;
private int defaultWidth = 1920;
private string imagePath1;
private string defaultpath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Images/pc.png");
private string fileExtension = "";
private string filter1 = "*.png,*.jpg,*.bmp";
private string filter2 = "*.png;*.jpg;*.bmp";
public static LogoDiyViewModel Instance
{
get
{
if (_instance == null)
{
_instance = new LogoDiyViewModel();
}
return _instance;
}
}
public bool IsShowLodingIco
{
get
{
return _IsShowLodingIco;
}
set
{
_IsShowLodingIco = value;
// RaisePropertyChanged(() => IsShowLodingIco);
}
}
public bool VidibalyLodingIco
{
get
{
return vidibalyLodingIco;
}
set
{
vidibalyLodingIco = value;
// RaisePropertyChanged(() => VidibalyLodingIco);
}
}
public string Filter
{
get
{
return filter1;
}
}
public string SupportingFormat
{
get
{
return _SupportingFormat;
}
set
{
_SupportingFormat = value;
// RaisePropertyChanged(() => SupportingFormat);
}
}
public double ImageHeight
{
get
{
return _ImageHeight;
}
set
{
_ImageHeight = value;
// RaisePropertyChanged(() => ImageHeight);
}
}
public double ImageWidth
{
get
{
return _ImageWidth;
}
set
{
_ImageWidth = value;
// RaisePropertyChanged(() => ImageWidth);
}
}
public bool ShowWarning
{
get
{
return _ShowWarning;
}
set
{
_ShowWarning = value;
// RaisePropertyChanged(() => ShowWarning);
}
}
public string ShowWarnInfo
{
get
{
return _ShowWarnInfo;
}
set
{
_ShowWarnInfo = value;
// RaisePropertyChanged(() => ShowWarnInfo);
}
}
public bool ShowSuccessTip
{
get
{
return _ShowSuccessTip;
}
set
{
_ShowSuccessTip = value;
// RaisePropertyChanged(() => ShowSuccessTip);
}
}
public string ShowSuccessText
{
get
{
return showSuccessText;
}
set
{
showSuccessText = value;
// RaisePropertyChanged(() => ShowSuccessText);
}
}
public BitmapImage ImageSource
{
get
{
return imageSource;
}
set
{
imageSource = value;
// RaisePropertyChanged(() => ImageSource);
}
}
public bool UIIsEnable
{
get
{
return _UIIsEnable;
}
set
{
_UIIsEnable = value;
// RaisePropertyChanged(() => UIIsEnable);
}
}
public bool FunEnable
{
get
{
return funEnable;
}
set
{
funEnable = value;
// RaisePropertyChanged(() => FunEnable);
}
}
public long DiskFreeSpace => diskFreeSpace;
public bool CanRecovery
{
get
{
return canRecovery;
}
set
{
canRecovery = value;
// RaisePropertyChanged(() => CanRecovery);
}
}
public int DefaultHeight
{
get
{
return defaultHeight;
}
set
{
value = defaultHeight;
// RaisePropertyChanged(() => DefaultHeight);
}
}
public int DefaultWidth
{
get
{
return defaultWidth;
}
set
{
defaultWidth = value;
// RaisePropertyChanged(() => DefaultWidth);
}
}
public string ImagePath1
{
get
{
return imagePath1;
}
set
{
imagePath1 = value;
// RaisePropertyChanged(() => ImagePath1);
}
}
private LogoDiyViewModel()
{
}
public void CreateViewData()
{
ImageHeight = 140.0;
ImageWidth = 224.0;
ShowSuccessTip = false;
ShowWarning = false;
GetLogoInfo();
VidibalyLodingIco = GetLoadingCircle();
if (VidibalyLodingIco)
{
GetShowLodingIco();
}
}
private bool GetLoadingCircle()
{
int build = Environment.OSVersion.Version.Build;
LogoDiy.LogHelper.Info($"ostype = {build}");
if (build > 14393)
{
int num = DiyHelper.IsEditionCircle();
LogoDiy.LogHelper.Info($"IsEditionCircle = {num}");
if (num != 0)
{
return true;
}
return false;
}
return false;
}
private void GetShowLodingIco()
{
IntPtr ptr = default(IntPtr);
try
{
DiyHelper.Wow64DisableWow64FsRedirection(ref ptr);
string text = "bcdedit /enum all";
Process process = new Process();
process.StartInfo.FileName = "cmd.exe";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.CreateNoWindow = true;
process.Start();
process.StandardInput.WriteLine(text + "&exit");
process.StandardInput.AutoFlush = true;
StreamReader standardOutput = process.StandardOutput;
string text2 = standardOutput.ReadLine();
bool flag = false;
while (!standardOutput.EndOfStream)
{
text2 = standardOutput.ReadLine();
if ((text2.Contains("标识符") || text2.Contains("identifier")) && text2.Contains("{globalsettings}"))
{
flag = true;
}
if (flag && text2.Contains("bootuxdisabled"))
{
Console.WriteLine("gobalsettings: " + text2);
string text3 = text2.Replace("bootuxdisabled", "").Trim();
IsShowLodingIco = text3.Contains("No");
LogoDiy.LogHelper.Info($"{text2}; 載入系統圖示 = {IsShowLodingIco}");
flag = false;
}
}
process.WaitForExit();
process.Close();
}
catch (Exception)
{
}
finally
{
DiyHelper.Wow64RevertWow64FsRedirection(ptr);
}
}
private long GetHardDiskFreeSpace(string str_HardDiskName)
{
try
{
str_HardDiskName += ":\\";
DriveInfo[] drives = DriveInfo.GetDrives();
foreach (DriveInfo driveInfo in drives)
{
Console.WriteLine($"{driveInfo.Name}");
if (driveInfo.Name == str_HardDiskName)
{
return driveInfo.TotalFreeSpace;
}
}
}
catch (Exception)
{
}
return 0L;
}
private void GetDiskFree(long freeM)
{
try
{
long num = 33554432L;
diskFreeSpace = freeM - num;
LogoDiy.LogHelper.Info($"diskFreeSpace = {diskFreeSpace}; freeTotal = {freeM}; _32M = {num} ");
}
catch (Exception ex)
{
LogoDiy.LogHelper.Error(ex);
}
}
private bool IsSizeExceed(string path)
{
Image image = null;
try
{
Path.GetExtension(path);
image = Image.FromFile(path);
double num = image.Width;
double num2 = image.Height;
if (num > (double)DefaultWidth || num2 > (double)DefaultHeight)
{
return true;
}
return false;
}
catch (Exception)
{
return false;
}
finally
{
image?.Dispose();
}
}
private bool SetImageSize(string path)
{
Image image = null;
try
{
Path.GetExtension(path);
image = Image.FromFile(path);
double num = image.Width;
double num2 = image.Height;
LogoDiy.LogHelper.Info($"img h = {num2}; w = {num}");
ImageHeight = 140.0 * num2 / (double)defaultHeight;
ImageWidth = 224.0 * num / (double)defaultWidth;
return true;
}
catch (Exception)
{
return false;
}
finally
{
image?.Dispose();
}
}
private void SetImagePath(bool defaultImage)
{
string tempPath = Path.GetTempPath();
try
{
string text = ChangeEFIDisk(mount: true);
long hardDiskFreeSpace = GetHardDiskFreeSpace(text);
string path = Path.Combine(text + ":", "EFI\\Lenovo\\Logo");
if (!defaultImage && Directory.Exists(path))
{
string[] files = Directory.GetFiles(path);
if (files.Length != 0)
{
string text2 = files[0];
tempPath = Path.Combine(tempPath, Path.GetFileName(text2));
File.Copy(text2, tempPath, overwrite: true);
SetImageSize(tempPath);
GetBitmapImage(tempPath);
}
}
else
{
GetBitmapImage(defaultpath);
}
GetDiskFree(hardDiskFreeSpace);
}
catch (Exception ex)
{
LogoDiy.LogHelper.Info($"SetImagePath error {ex.Message}");
}
finally
{
ChangeEFIDisk(mount: false);
}
}
public void ToRecovery()
{
try
{
name = ChangeEFIDisk(mount: true);
string text = "";
text = Path.Combine(name + ":\\", "EFI\\Lenovo\\Logo");
DeleteOtherDirectory(text);
}
catch (Exception ex)
{
LogoDiy.LogHelper.Error(ex);
}
finally
{
ChangeEFIDisk(mount: false);
}
int num = DiyHelper.SetLogoDIYInfo(0);
LogoDiy.LogHelper.Info($"set logoinfo ret = {num}");
if (num == 0)
{
LogoDiy.LogHelper.Info($"set logoinfo error: ret = {num}");
return;
}
ShowSuccessText = "Done! Restored to default settings.\n預設設定恢復成功";
ShowSuccessTip = true;
FunEnable = false;
}
private void GetLogoInfo()
{
uint format = 0u;
byte enable = 0;
int logoDIYInfo = DiyHelper.GetLogoDIYInfo(ref enable, ref format, ref defaultHeight, ref defaultWidth);
LogoDiy.LogHelper.Info($"ret1 = {logoDIYInfo}; Height = {defaultHeight}; Width = {defaultWidth}");
if (logoDIYInfo != 0)
{
ChangeSupportingFormat(format);
if (defaultHeight < 0 || defaultWidth < 0)
{
LogoDiy.LogHelper.Info("get height/width error, set default 1920*1080");
DefaultWidth = 1920;
DefaultHeight = 1080;
}
LogoDiy.LogHelper.Info($"get logoinfo -> enable = {enable}; type = {format}; ");
bool flag = enable == 0;
SetImagePath(flag);
CanRecovery = !flag;
FunEnable = !flag;
UIIsEnable = true;
}
else
{
GetBitmapImage(defaultpath);
LogoDiy.LogHelper.Info("get logo_info error:");
UIIsEnable = false;
FunEnable = false;
CanRecovery = false;
}
}
public void SaveLogoClick()
{
try
{
Console.WriteLine("SaveLogoClick");
int num = DiyHelper.SetLogoDIYInfo(1);
LogoDiy.LogHelper.Info($"set logoinfo ret = {num}");
if (num == 0)
{
ShowSuccessTip = false;
LogoDiy.LogHelper.Info($"set logoinfo error: ret = {num}");
return;
}
LogoDiy.LogHelper.Info($"set logoinfo success: ret = {num}");
name = ChangeEFIDisk(mount: true);
string text = "";
try
{
string extension = Path.GetExtension(ImagePath1);
if (!string.IsNullOrWhiteSpace(fileExtension) && extension != fileExtension)
{
extension = fileExtension;
}
text = Path.Combine(name + ":\\", "EFI\\Lenovo\\Logo", $"mylogo_{DefaultWidth}x{DefaultHeight}" + extension);
LogoDiy.LogHelper.Info($"path = {text}");
DeleteOtherFile(text);
LogoDiy.LogHelper.Info($"source path = {ImagePath1}; dest path = {text}");
File.Copy(ImagePath1, text);
}
catch (Exception ex)
{
LogoDiy.LogHelper.Info("copy file error:" + ex.Message);
return;
}
if (DiyHelper.SetLogDIYCRC(text) > 0)
{
LogoDiy.LogHelper.Info("Set CRC success");
ChangeEFIDisk(mount: false);
ShowSuccessText = "Success! You can restart to view the new boot logo now.\n設定成功,請重新啟動電腦檢視效果";
ShowSuccessTip = true;
}
else
{
LogoDiy.LogHelper.Info("Set CRC ERROR");
ShowSuccessTip = false;
}
}
catch (Exception ex2)
{
LogoDiy.LogHelper.Error(ex2);
ShowSuccessTip = false;
}
finally
{
CanRecovery = true;
ChangeEFIDisk(mount: false);
}
}
private void DeleteOtherDirectory(string path)
{
if (Directory.Exists(path))
{
Directory.Delete(path, recursive: true);
}
}
private void DeleteOtherFile(string path)
{
string directoryName = Path.GetDirectoryName(path);
LogoDiy.LogHelper.Info($"delete directory {directoryName}");
if (Directory.Exists(directoryName))
{
LogoDiy.LogHelper.Info("Delete directory error, to delete file");
string[] files = Directory.GetFiles(directoryName);
foreach (string text in files)
{
LogoDiy.LogHelper.Info($"delete other file {text}");
File.Delete(text);
}
}
else
{
LogoDiy.LogHelper.Info($"Create new directory {directoryName}");
Directory.CreateDirectory(directoryName);
}
}
private string GetDiskName()
{
string[] logicalDrives = Directory.GetLogicalDrives();
for (int i = 65; i < 91; i++)
{
ASCIIEncoding aSCIIEncoding = new ASCIIEncoding();
byte[] bytes = new byte[1]
{
(byte)i
};
string @string = aSCIIEncoding.GetString(bytes);
if (!logicalDrives.Contains(@string))
{
return @string;
}
}
return "";
}
private string ChangeEFIDisk(bool mount)
{
string diskName = GetDiskName();
try
{
string arg = (mount ? "/s" : "/d");
string text = $"mountvol {diskName}: {arg}";
LogoDiy.LogHelper.Info(text);
Process process = new Process();
process.StartInfo.FileName = "cmd.exe";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.CreateNoWindow = true;
process.Start();
process.StandardInput.WriteLine(text + "&exit");
process.StandardInput.AutoFlush = true;
process.WaitForExit();
process.Close();
return diskName;
}
catch (Exception ex)
{
LogoDiy.LogHelper.Error(ex);
return diskName;
}
}
public bool ChangeLodingIco(bool isShow)
{
IntPtr ptr = default(IntPtr);
try
{
DiyHelper.Wow64DisableWow64FsRedirection(ref ptr);
string text = "";
text = ((!isShow) ? "bcdedit.exe -set {globalsettings} bootuxdisabled on" : "bcdedit.exe -set {globalsettings} bootuxdisabled off");
Console.WriteLine(text);
LogoDiy.LogHelper.Info(text);
Process process = new Process();
process.StartInfo.FileName = "cmd.exe";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.CreateNoWindow = true;
process.Start();
process.StandardInput.WriteLine(text + "&exit");
process.StandardInput.AutoFlush = true;
process.WaitForExit();
process.Close();
return true;
}
catch (Exception ex)
{
LogoDiy.LogHelper.Error(ex);
return false;
}
finally
{
DiyHelper.Wow64RevertWow64FsRedirection(ptr);
}
}
public bool ImageCheck(string path)
{
FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read);
BinaryReader binaryReader = new BinaryReader(fileStream);
string empty = string.Empty;
bool flag = false;
flag = IsImage(path);
if (!flag)
{
return flag;
}
try
{
Path.GetExtension(path);
empty += binaryReader.ReadByte();
empty += binaryReader.ReadByte();
try
{
FileExtension fileExtension = (FileExtension)Enum.Parse(typeof(FileExtension), empty);
switch (fileExtension)
{
case FileExtension.BMP2:
case FileExtension.PNG:
case FileExtension.BMP:
case FileExtension.JPEG:
case FileExtension.JPG:
this.fileExtension = fileExtension.Display();
flag = true;
return flag;
default:
flag = false;
return flag;
}
}
catch (Exception ex)
{
LogoDiy.LogHelper.Error(ex);
return flag;
}
}
catch (Exception ex2)
{
LogoDiy.LogHelper.Error(ex2);
return flag;
}
finally
{
if (fileStream != null)
{
fileStream.Close();
binaryReader.Close();
}
}
}
private bool IsImage(string path)
{
Image image = null;
try
{
string text = Path.GetExtension(path).ToLower();
if (!(text == ".tga") && !(text == ".pcx"))
{
image = Image.FromFile(path);
image.Dispose();
}
return true;
}
catch (Exception)
{
return false;
}
finally
{
image?.Dispose();
}
}
public void SelectedImageClick()
{
ShowSuccessTip = false;
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Multiselect = false;
openFileDialog.Title = "Please select an image / 請選擇圖片";
openFileDialog.Filter = $"Image({filter1})|{filter2}";
var res = openFileDialog.ShowDialog();
if (res == DialogResult.OK)
{
CanRecovery = false;
FunEnable = false;
string fileName = openFileDialog.FileName;
FileInfo fileInfo = new FileInfo(fileName);
if (!ImageCheck(fileName))
{
ShowWarning = true;
ShowWarnInfo = "The selected file is not an image!\n當前選擇的檔案不是圖片,請重試!";
return;
}
if (fileInfo.Length > DiskFreeSpace)
{
int num = (int)(DiskFreeSpace / 1024 / 1024);
ShowWarnInfo = $"Image must not exceed {num}MB!\n圖片不得超過{num}MB,請重新選擇!";
ShowWarning = true;
return;
}
if (IsSizeExceed(fileName))
{
ShowWarnInfo = "The image exceeds the maximum resolution!\n圖片超出最大解析度,請重新選擇!";
ShowWarning = true;
return;
}
GetBitmapImage(fileName);
SetImageSize(fileName);
FunEnable = true;
ShowWarning = false;
LogoDiy.LogHelper.Info($"介面圖片大小>>height = {ImageHeight}; width = {ImageWidth};");
}
}
public void GetBitmapImage(string imagePath)
{
try
{
imagePath1 = imagePath;
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.UriSource = new Uri(imagePath);
bitmapImage.EndInit();
ImageSource = bitmapImage.Clone();
bitmapImage.Freeze();
}
catch (Exception ex)
{
LogoDiy.LogHelper.Error(ex);
}
}
private void ChangeSupportingFormat(uint format)
{
filter1 = "";
filter2 = "";
if ((1u & format) != 0)
{
filter1 += "*.jpg,";
filter2 += "*.jpg;";
}
if ((0x10u & format) != 0)
{
filter1 += "*.bmp,";
filter2 += "*.bmp;";
}
if ((0x20u & format) != 0)
{
filter1 += "*.png,";
filter2 += "*.png;";
}
filter1 = filter1.Substring(0, filter1.Length - 1);
filter2 = filter2.Substring(0, filter2.Length - 1);
SupportingFormat = filter2;
}
}
}
================================================
FILE: LogoDiy/Program.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace LogoDiy
{
static class Program
{
///
/// The main entry point for the application.
///
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
================================================
FILE: LogoDiy/Properties/AssemblyInfo.cs
================================================
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("LogoDIY")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("LogoDIY")]
[assembly: AssemblyCopyright("Copyright © 2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("3df19333-d9aa-4cfd-8b0f-21df0916508c")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
================================================
FILE: LogoDiy/Properties/Resources.Designer.cs
================================================
//------------------------------------------------------------------------------
//
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
//------------------------------------------------------------------------------
namespace LogoDIY.Properties {
using System;
///
/// A strongly-typed resource class, for looking up localized strings, etc.
///
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
///
/// Returns the cached ResourceManager instance used by this class.
///
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("LogoDIY.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
///
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
///
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}
================================================
FILE: LogoDiy/Properties/Resources.resx
================================================
text/microsoft-resx
2.0
System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
================================================
FILE: LogoDiy/Properties/Settings.Designer.cs
================================================
//------------------------------------------------------------------------------
//
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
//------------------------------------------------------------------------------
namespace LogoDIY.Properties
{
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
{
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default
{
get
{
return defaultInstance;
}
}
}
}
================================================
FILE: LogoDiy/Properties/Settings.settings
================================================
================================================
FILE: LogoDiy/app.manifest
================================================
true
================================================
FILE: LogoDiy.sln
================================================
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30621.155
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LogoDiy", "LogoDiy\LogoDiy.csproj", "{3DF19333-D9AA-4CFD-8B0F-21DF0916508C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{3DF19333-D9AA-4CFD-8B0F-21DF0916508C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3DF19333-D9AA-4CFD-8B0F-21DF0916508C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3DF19333-D9AA-4CFD-8B0F-21DF0916508C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3DF19333-D9AA-4CFD-8B0F-21DF0916508C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {6278FE5B-0A18-4BFF-B6BF-9F6146BDAB45}
EndGlobalSection
EndGlobal
================================================
FILE: README.md
================================================
# Boot Logo Customization
**EN** | [ZH](README.zh.md)
Customize Lenovo PC boot logo (screen) without installing "Lenovo PC Manager".
**This program will modify BIOS settings, use at your own risk.** The copyright of the code and binary files used belongs to the original manufacturer.
## Supported models
***Only Lenovo computers (Ideapad / Xiaoxin, Legion, Yoga, etc.) are supported.***
- Xiaoxin Pro 14 2021 Intel
- Xiaoxin Pro 13 Ryzen
- Xiaoxin Air 14 2020 Intel
- ThinkBook 14 G4+ IAP
- ThinkBook 15 Gen 3
- Legion Y9000P 2022
- Yoga 7 16IAP7
- IdeaPad Gaming 3 15ACH6
- IdeaPad 3 15ITL6
- Feel free to test and add to this list
## FAQ
### New boot logo does not take effect / corrupted logo
This may happen when using `.jpg` format files saved with Photoshop. You can save the image as `.bmp` format, or resave it to `.jpg` format with other software (e.g. Microsoft Paint).
### User interface of this utility is too ugly 🤯
This is actually just something I wanted to use for myself and quickly build ;).
### Any recommendations for boot logo design?
[Here](https://github.com/Coxxs/LogoDiy/tree/master/Examples) are some examples.
================================================
FILE: README.zh.md
================================================
# 開機 Logo 自訂
[EN](README.md) | **ZH**
自訂 Lenovo 電腦開機 Logo(畫面),無需安裝「聯想電腦管家」軟體。
**涉及修改 BIOS 設置,一切風險自負。** 代碼及二進制檔案著作權歸其原開發商所有。
## 測試可用機型
**僅支援 Lenovo 電腦(Ideapad / Xiaoxin、Legion、Yoga 等)。**
- Xiaoxin Pro 14 2021 Intel
- Xiaoxin Pro 13 Ryzen
- Xiaoxin Air 14 2020 Intel
- ThinkBook 14 G4+ IAP
- ThinkBook 15 Gen 3
- Legion Y9000P 2022
- Yoga 7 16IAP7
- IdeaPad Gaming 3 15ACH6
- IdeaPad 3 15ITL6
- 歡迎測試添加
## 常見問題
### 設定成功後,重新啟動未生效 / 顯示錯誤
Photoshop 儲存的 `.jpg` 格式檔案可能會出現這樣的情況。可以儲存為 `.bmp` 格式後直接使用,或用其他軟體(如小畫家)轉換為 `.jpg` 格式。
### 軟體介面太醜了 🤯
這個其實只是我自己要用而快速糊出來的東西 ;)
### 換成什麼圖案好呢
[這裡](https://github.com/Coxxs/LogoDiy/tree/master/Examples) 有一些例子可供參考。