Showing preview only (286K chars total). Download the full file or copy to clipboard to get everything.
Repository: OdysseusYuan/LKY_OfficeTools
Branch: master
Commit: 6f9a1bd47191
Files: 47
Total size: 272.3 KB
Directory structure:
gitextract_16dtn_90/
├── .gitattributes
├── .gitignore
├── LICENSE.txt
├── LKY_OfficeTools/
│ ├── App.config
│ ├── Common/
│ │ ├── Com_ExeOS.cs
│ │ ├── Com_FileOS.cs
│ │ ├── Com_InstallerOS.cs
│ │ ├── Com_NetworkOS.cs
│ │ ├── Com_PrivilegeOS.cs
│ │ ├── Com_ServiceOS.cs
│ │ ├── Com_SystemOS.cs
│ │ ├── Com_TextOS.cs
│ │ ├── Com_Timer.cs
│ │ └── Com_WebOS.cs
│ ├── LKY_OfficeTools.csproj
│ ├── Lib/
│ │ ├── Lib_AppClosing.cs
│ │ ├── Lib_AppCommand.cs
│ │ ├── Lib_AppInfo.cs
│ │ ├── Lib_AppLog.cs
│ │ ├── Lib_AppMessage.cs
│ │ ├── Lib_AppSdk.cs
│ │ ├── Lib_AppServiceConfig.cs
│ │ ├── Lib_AppServiceHub.Designer.cs
│ │ ├── Lib_AppServiceHub.cs
│ │ ├── Lib_AppSignCert.cs
│ │ ├── Lib_AppState.cs
│ │ ├── Lib_AppUpdate.cs
│ │ ├── Lib_Aria2c.cs
│ │ ├── Lib_OfficeActivate.cs
│ │ ├── Lib_OfficeClean.cs
│ │ ├── Lib_OfficeDownload.cs
│ │ ├── Lib_OfficeInfo.cs
│ │ ├── Lib_OfficeInstall.cs
│ │ └── Lib_OfficeProcess.cs
│ ├── OfficeTools.cs
│ ├── Properties/
│ │ ├── AssemblyInfo.cs
│ │ └── app.manifest
│ └── Resource/
│ ├── Json/
│ │ └── OfficeChannels.txt
│ ├── Office_Processes.list
│ ├── PublisherCert.cer
│ └── SDK/
│ ├── Activate.lotp
│ ├── Aria2c.lotp
│ ├── ODT.lotp
│ ├── SDK_Processes.list
│ └── SaRA.lotp
├── LKY_OfficeTools.sln
└── README.md
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitattributes
================================================
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto
###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs diff=csharp
###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln merge=binary
#*.csproj merge=binary
#*.vbproj merge=binary
#*.vcxproj merge=binary
#*.vcproj merge=binary
#*.dbproj merge=binary
#*.fsproj merge=binary
#*.lsproj merge=binary
#*.wixproj merge=binary
#*.modelproj merge=binary
#*.sqlproj merge=binary
#*.wwaproj merge=binary
###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg binary
#*.png binary
#*.gif binary
###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
#*.doc diff=astextplain
#*.DOC diff=astextplain
#*.docx diff=astextplain
#*.DOCX diff=astextplain
#*.dot diff=astextplain
#*.DOT diff=astextplain
#*.pdf diff=astextplain
#*.PDF diff=astextplain
#*.rtf diff=astextplain
#*.RTF diff=astextplain
================================================
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/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Oo]ut/
[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/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# 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
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# 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/
# Fody - auto-generated XML schema
FodyWeavers.xsd
/LKY_OfficeTools/Resource/Json/LKY_OfficeTools_AppInfo.json
================================================
FILE: LICENSE.txt
================================================
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.
================================================
FILE: LKY_OfficeTools/App.config
================================================
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/>
</startup>
</configuration>
================================================
FILE: LKY_OfficeTools/Common/Com_ExeOS.cs
================================================
/*
* [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.
*
* FileName : Com_ExeOS.cs
* Developer: OdysseusYuan@foxmail.com (Odysseus.Yuan)
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using static LKY_OfficeTools.Lib.Lib_AppLog;
namespace LKY_OfficeTools.Common
{
internal class Com_ExeOS
{
internal class Run
{
internal static int Exe(string file_path, string args)
{
try
{
Process p = new Process();
var result = Process(file_path, args, out p, true); //默认等待完成
//是否执行了
if (!result)
{
throw new Exception($"执行 {file_path} 异常!");
}
return p.ExitCode;
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return -920921;
}
}
internal static bool Process(string file_path, string args, out Process ProcessInfo, bool WaitForExit)
{
try
{
Console.ForegroundColor = ConsoleColor.Gray;
ProcessInfo = new Process();
ProcessInfo.StartInfo.FileName = file_path; //需要启动的程序名
ProcessInfo.StartInfo.Arguments = args; //启动参数
//是否使用操作系统shell启动
ProcessInfo.StartInfo.UseShellExecute = false;
//启动
ProcessInfo.Start();
//接收返回值
//p.StandardInput.AutoFlush = true;
//获取输出信息
//string strOuput = p.StandardOutput.ReadToEnd();
//等待程序执行完退出进程
if (WaitForExit)
{
ProcessInfo.WaitForExit();
}
return true;
}
catch (Exception Ex)
{
ProcessInfo = null;
new Log(Ex.ToString());
return false;
}
}
internal static string Cmd(string args)
{
try
{
Console.ForegroundColor = ConsoleColor.Gray;
Process p = new Process();
//设置要启动的应用程序
p.StartInfo.FileName = "cmd.exe";
//是否使用操作系统shell启动
p.StartInfo.UseShellExecute = false;
// 接受来自调用程序的输入信息
p.StartInfo.RedirectStandardInput = true;
//输出信息
p.StartInfo.RedirectStandardOutput = true;
// 输出错误
p.StartInfo.RedirectStandardError = true;
//不显示程序窗口
p.StartInfo.CreateNoWindow = true;
//启动程序
p.Start();
//向cmd窗口发送输入信息
p.StandardInput.WriteLine(args + "&exit");
p.StandardInput.AutoFlush = true;
//获取输出信息
string strOuput = p.StandardOutput.ReadToEnd();
//等待程序执行完退出进程
p.WaitForExit();
p.Close();
return strOuput;
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return null;
}
}
}
internal class KillExe
{
internal enum KillMode
{
Try_Friendly = 1,
Only_Friendly = 2,
Only_Force = 4,
}
internal static bool ByExeName(string exe_name, KillMode kill_mode, bool isWait)
{
try
{
//先判断是否存在进程
if (Info.IsRun(exe_name))
{
Process[] p = Process.GetProcessesByName(exe_name);
foreach (Process now_p in p)
{
ByProcessID(now_p.Id, kill_mode, isWait);
}
return true;
}
else
{
//不存在时,直接返回 true
return true;
}
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return false;
}
}
internal static bool ByProcessID(int exe_id, KillMode kill_mode, bool isWait)
{
try
{
//先判断是否存在进程
if (Info.IsRun(exe_id))
{
//进程存在,获取对象
Process now_p = Process.GetProcessById(exe_id);
switch (kill_mode)
{
case KillMode.Try_Friendly:
{
//先尝试友好关闭
if (!now_p.CloseMainWindow())
{
//有好关闭失败时,启用强制结束
now_p.Kill();
}
break;
}
case KillMode.Only_Friendly:
{
//只友好关闭
now_p.CloseMainWindow();
break;
}
case KillMode.Only_Force:
{
//只强制结束
now_p.Kill();
break;
}
}
//判断是否等待进程结束
if (isWait)
{
//等待进程被结束
now_p.WaitForExit();
}
return true; //如果不是等待结束进程,中途未出现catch时,也返回true
}
else
{
//不存在时,直接返回 true
return true;
}
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return false;
}
}
}
internal class Info
{
internal static bool IsRun(string exe_name)
{
try
{
Process[] p = Process.GetProcesses();
foreach (Process now_p in p)
{
if (now_p.ProcessName.Equals(exe_name, StringComparison.OrdinalIgnoreCase))
{
return true;
}
}
return false;
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return false;
}
}
internal static bool IsRun(int exe_id)
{
try
{
Process[] p = Process.GetProcesses();
foreach (Process now_p in p)
{
if (now_p.Id == exe_id)
{
return true;
}
}
return false;
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return false;
}
}
internal static List<Process> GetProcessByTitle(string window_title, bool need_equal = false)
{
try
{
Process[] process_list = Process.GetProcesses();
List<Process> result = new List<Process>();
foreach (var now_p in process_list)
{
if (need_equal)
{
//严格相等
if (now_p.MainWindowTitle == window_title)
{
result.Add(now_p);
}
}
else
{
//包含即可
if (now_p.MainWindowTitle.Contains(window_title))
{
result.Add(now_p);
}
}
}
return result;
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return null;
}
}
}
}
}
================================================
FILE: LKY_OfficeTools/Common/Com_FileOS.cs
================================================
/*
* [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.
*
* FileName : Com_FileOS.cs
* Developer: OdysseusYuan@foxmail.com (Odysseus.Yuan)
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using static LKY_OfficeTools.Lib.Lib_AppLog;
namespace LKY_OfficeTools.Common
{
internal class Com_FileOS
{
internal class XML
{
internal static bool SetValue(string xml_path, string Key_str, string new_Value)
{
try
{
//读取文件
string xml_content = File.ReadAllText(xml_path, Encoding.UTF8);
//获得当前值
string current_value = Com_TextOS.GetCenterText(xml_content, $"{Key_str}=\"", "\"");
//替换值
string xml_new_content = xml_content.Replace(current_value, new_Value);
//判断是否替换成功
if (string.IsNullOrEmpty(xml_new_content))
{
//new Log("替换失败!");
return false;
}
//写入文件
File.WriteAllText(xml_path, xml_new_content, Encoding.UTF8);
return true;
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return false;
}
}
}
internal class ScanFiles
{
internal List<string> FilesList = new List<string>();
internal void GetFilesByExtension(string dirPath, string fileType = "*", bool isRoot = false)
{
if (Directory.Exists(dirPath)) //目录存在
{
DirectoryInfo folder = new DirectoryInfo(dirPath);
//获取当前目录下的文件名
foreach (FileInfo file in folder.GetFiles())
{
//如果没有限制文件后缀名,或者满足了特定后缀名,开始写入List
if (fileType == "*" || file.Extension == (fileType))
{
//扫描到的文件添加到列表中
FilesList.Add(file.FullName);
}
}
//如果是根目录先排除掉 回收站目录
if (isRoot)
{
foreach (DirectoryInfo dir in folder.GetDirectories())
{
if (dir.FullName.Contains("$RECYCLE.BIN") || dir.FullName.Contains("System Volume Information"))
{
//Console.ForegroundColor = ConsoleColor.Gray;
//new Log("跳过: " + dir.FullName);
}
else
{
//new Log("----->: " + dir.FullName);
GetFilesByExtension(dir.FullName, fileType);
}
}
}
else
{
//遍历下一个子目录
foreach (DirectoryInfo subFolders in folder.GetDirectories())
{
//new Log(subFolders.FullName);
GetFilesByExtension(subFolders.FullName, fileType);
}
}
}
else
{
/*Console.ForegroundColor = ConsoleColor.Gray;
new Log("不存在: " + dirPath);*/
}
}
}
internal class Covert
{
/* - - - - - - - - - - - - - - - - - - - - - - - -
* Stream 和 byte[] 之间的转换
* - - - - - - - - - - - - - - - - - - - - - - - */
internal static byte[] StreamToBytes(Stream stream)
{
byte[] bytes = new byte[stream.Length];
stream.Read(bytes, 0, bytes.Length);
// 设置当前流的位置为流的开始
stream.Seek(0, SeekOrigin.Begin);
return bytes;
}
}
internal class Write
{
internal static bool TextToFile(string file_path, string content, bool is_append = true)
{
try
{
// 创建文件所在目录
Directory.CreateDirectory(new FileInfo(file_path).DirectoryName);
//非追加模式,并且已经存在目标文件,则先删除原有文件
if (!is_append && File.Exists(file_path))
{
File.Delete(file_path);
}
var fs = new FileStream(file_path, FileMode.OpenOrCreate, FileAccess.Write);
var sw = new StreamWriter(fs);
sw.BaseStream.Seek(0, SeekOrigin.End);
sw.WriteLine(content);
sw.Flush();
sw.Close();
fs.Close();
return true;
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return false;
}
}
internal static bool FromStream(Stream stream, string to_path)
{
try
{
byte[] Save = Covert.StreamToBytes(stream);
//创建文件所在目录
Directory.CreateDirectory(new FileInfo(to_path).DirectoryName);
FileStream fsObj = new FileStream(to_path, FileMode.Create);
fsObj.Write(Save, 0, Save.Length);
fsObj.Close();
return true;
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return false;
}
}
}
internal class Info
{
internal static string GetHash(string file_path)
{
try
{
//文件不存在,返回null
if (!File.Exists(file_path))
{
return null;
}
//为了防止文件被占用,无法校验,这里先拷贝一份副本,校验副本的值
string file_copied = DateTime.Now.ToFileTime().ToString() + ".hash";
File.Copy(file_path, file_copied, true);
if (!File.Exists(file_copied))
{
return null; //副本文件拷贝失败,返回null
}
//var hash = SHA256.Create();
//var hash = MD5.Create();
var hash = SHA1.Create();
var stream = new FileStream(file_copied, FileMode.Open);
byte[] hashByte = hash.ComputeHash(stream);
stream.Close();
//校验完成,删除副本
if (File.Exists(file_copied))
{
File.Delete(file_copied);
}
return BitConverter.ToString(hashByte).Replace("-", "");
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return null;
}
}
}
}
}
================================================
FILE: LKY_OfficeTools/Common/Com_InstallerOS.cs
================================================
/*
* [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.
*
* FileName : Com_InstallerOS.cs
* Developer: OdysseusYuan@foxmail.com (Odysseus.Yuan)
*/
using System;
using WindowsInstaller;
using static LKY_OfficeTools.Lib.Lib_AppLog;
namespace LKY_OfficeTools.Common
{
internal class Com_InstallerOS
{
internal enum MsiInfoType
{
ProductName,
ProductCode,
ProductVersion
}
internal static string GetProductInfo(string msi_path, MsiInfoType msi_info)
{
try
{
Type oType = Type.GetTypeFromProgID("WindowsInstaller.Installer");
if (oType == null)
{
return null;
}
Installer inst = Activator.CreateInstance(oType) as Installer;
if (inst == null)
{
return null;
}
Database DB = inst.OpenDatabase(msi_path, MsiOpenDatabaseMode.msiOpenDatabaseModeReadOnly);
if (DB == null)
{
return null;
}
//生成要查询的内容
string str = $" SELECT * FROM Property WHERE Property = '{msi_info}' ";
View thisView = DB.OpenView(str);
if (thisView == null)
{
return null;
}
thisView.Execute();
Record thisRecord = thisView.Fetch();
if (thisRecord == null)
{
return null;
}
string result = thisRecord.get_StringData(2);
return result;
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return null;
}
}
}
}
================================================
FILE: LKY_OfficeTools/Common/Com_NetworkOS.cs
================================================
/*
* [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.
*
* FileName : Com_NetworkOS.cs
* Developer: OdysseusYuan@foxmail.com (Odysseus.Yuan)
*/
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using static LKY_OfficeTools.Lib.Lib_AppInfo;
using static LKY_OfficeTools.Lib.Lib_AppLog;
namespace LKY_OfficeTools.Common
{
internal class Com_NetworkOS
{
internal class Check
{
//导入判断网络是否连接的 .dll
[DllImport("wininet.dll", EntryPoint = "InternetGetConnectedState")]
//判断网络状况的方法,返回值true为连接,false为未连接
private extern static bool InternetGetConnectedState(out int conState, int reder);
internal static bool IsConnected
{
get
{
return InternetGetConnectedState(out int n, 0);
}
}
}
}
}
================================================
FILE: LKY_OfficeTools/Common/Com_PrivilegeOS.cs
================================================
/*
* [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.
*
* FileName : Com_PrivilegeOS.cs
* Developer: OdysseusYuan@foxmail.com (Odysseus.Yuan)
*/
using System;
using System.IO;
using System.Security.Principal;
using static LKY_OfficeTools.Lib.Lib_AppInfo;
using static LKY_OfficeTools.Lib.Lib_AppLog;
using static LKY_OfficeTools.Lib.Lib_AppMessage;
using static LKY_OfficeTools.Lib.Lib_AppState;
namespace LKY_OfficeTools.Common
{
internal class Com_PrivilegeOS
{
internal static bool IsRunByAdmin()
{
WindowsIdentity identity = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(identity);
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
internal static bool CanWriteProgramDataDir()
{
try
{
string time_sn = $"{DateTime.UtcNow.Hour}{DateTime.UtcNow.Minute}{DateTime.UtcNow.Second}{DateTime.UtcNow.Millisecond}";
string test_file_dir = AppPath.Documents.Temp + $"\\{time_sn}";
string test_file_path = test_file_dir + "\\time_sn.tmp";
var isSuccess = Com_FileOS.Write.TextToFile(test_file_path, "test", false);
//删除测试的文件和目录
if (Directory.Exists(test_file_dir))
{
Directory.Delete(test_file_dir, true);
}
return isSuccess;
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return false;
}
}
internal static void PrivilegeAttention()
{
new Log($"\n------> 正在进行 {AppAttribute.AppName} 权限检查 ...", ConsoleColor.DarkCyan);
//提权检验,非提权,激活会出问题
if (!IsRunByAdmin())
{
new Log($" × 权限错误,请以管理员身份运行此文件!", ConsoleColor.DarkRed);
Current_StageType = ProcessStage.Finish_Fail; //设置为失败模式
//退出提示
KeyMsg.Quit(-1);
}
//ProgramData目录权限检查
if (!CanWriteProgramDataDir())
{
//ProgramData目录缺少权限,已改用“我的文档”目录。服务维护流程已伴随关闭!
Must_Use_PersonalDir = true;
new Log($" * 已采用备用权限策略!", ConsoleColor.DarkMagenta);
}
new Log($" √ 已通过 {AppAttribute.AppName} 权限检查。", ConsoleColor.DarkGreen);
}
}
}
================================================
FILE: LKY_OfficeTools/Common/Com_ServiceOS.cs
================================================
/*
* [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.
*
* FileName : Com_ServiceOS.cs
* Developer: OdysseusYuan@foxmail.com (Odysseus.Yuan)
*/
using System;
using System.ServiceProcess;
using System.Threading;
using static LKY_OfficeTools.Lib.Lib_AppLog;
namespace LKY_OfficeTools.Common
{
internal class Com_ServiceOS
{
internal class Query
{
internal static int RunState(string serv_name)
{
try
{
using (var control = new ServiceController(serv_name))
{
return (int)control.Status;
}
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return 0;
}
}
internal static bool IsCreated(string serv_name)
{
try
{
if (GetService(serv_name) != null)
{
//服务不为空,服务存在
return true;
}
else
{
//服务为空,服务不存在
return false;
}
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return false;
}
}
internal static ServiceController GetService(string serv_name)
{
try
{
ServiceController service_info = null; //即将获得的服务对象
ServiceController[] services_list = ServiceController.GetServices(); //获得所有服务
foreach (var now_service in services_list) //遍历搜索服务
{
if (now_service.ServiceName.ToLower() == serv_name.ToLower()) //全部取小写,防止判断麻烦
{
service_info = now_service;
break;
}
}
return service_info;
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return null;
}
}
internal static bool CompareBinPath(string serv_name, string compare_path)
{
try
{
//服务未创建,不相等
if (!IsCreated(serv_name))
{
return false;
}
string cmd_query = $"sc qc {serv_name}";
string query_result = Com_ExeOS.Run.Cmd(cmd_query);
//返回值为空,不相等
if (string.IsNullOrEmpty(query_result))
{
return false;
}
if (query_result.Replace(@"\\", @"\").Contains(compare_path.Replace(@"\\", @"\"))) //替换两个斜杠,为单斜杠之后在比对
{
//包含指定路径(含命令行)
return true;
}
else
{
//不包含指定路径(含命令行)
return false;
}
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return false;
}
}
internal static bool CompareDescription(string serv_name, string compare_description)
{
try
{
//服务未创建,不相等
if (!IsCreated(serv_name))
{
return false;
}
string cmd_query = $"sc qdescription {serv_name}";
string query_result = Com_ExeOS.Run.Cmd(cmd_query);
//返回值为空,不相等
if (string.IsNullOrEmpty(query_result))
{
return false;
}
if (query_result.Contains(compare_description))
{
//包含描述
return true;
}
else
{
//不包含描述
return false;
}
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return false;
}
}
}
internal class Action
{
internal static bool Start(string serv_name)
{
try
{
//未创建服务,不启动!
if (!Query.IsCreated(serv_name))
{
throw new Exception($"启动服务 {serv_name} 时失败。未找到该服务!");
}
//已安装服务,开始启动
using (var control = new ServiceController(serv_name))
{
//没有处于运行状态的服务,才运行。
if (control.Status != ServiceControllerStatus.Running)
{
control.Start();
}
//判断状态,是否是开启了
int wait_time = 0; //等待时间总计
while (wait_time <= (10 * 1000)) //最多等待10秒
{
//获取服务状态
if (Query.RunState(serv_name) == (int)ServiceControllerStatus.Running)
{
//已经处于运行状态
return true;
}
else
{
//不是运行状态
Thread.Sleep(1000); //延迟 1s 后,再度查询
wait_time += 1000; //追加等待时间
continue;
}
}
//如果在轮询期间,没有返回true,那么最终返回false
return false;
}
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return false;
}
}
internal static bool Stop(string serv_name)
{
try
{
//未创建服务,不能停止!
if (!Query.IsCreated(serv_name))
{
throw new Exception($"停止服务 {serv_name} 时失败。未找到该服务!");
}
//已安装服务,开始停止
using (var control = new ServiceController(serv_name))
{
//只要不是停止状态,就发送停止指令
if (control.Status != ServiceControllerStatus.Stopped)
{
control.Stop();
}
//判断状态,是否是停止了
int wait_time = 0; //等待时间总计
while (wait_time <= (10 * 1000)) //最多等待10秒
{
//获取服务状态
if (Query.RunState(serv_name) == (int)ServiceControllerStatus.Stopped)
{
//已经处于停止状态
return true;
}
else
{
//不是停止状态
Thread.Sleep(1000); //延迟 1s 后,再度查询
wait_time += 1000; //追加等待时间
continue;
}
}
//如果在轮询期间,没有返回true,那么最终返回false
return false;
}
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return false;
}
}
internal static bool Restart(string serv_name)
{
try
{
//未创建服务,不能停止!
if (!Query.IsCreated(serv_name))
{
throw new Exception($"重启服务 {serv_name} 时失败。未找到该服务!");
}
//已安装服务,开始重启
if (Stop(serv_name))
{
if (Start(serv_name))
{
return true; //当且仅当停止成功,开启成功,返回true。除此之外,均为false
}
}
return false;
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return false;
}
}
}
internal class Config
{
internal static bool Create(string serv_name, string serv_runpath, string serv_displayname, string serv_description = null)
{
try
{
if (Query.IsCreated(serv_name))
{
//已经创建服务,直接返回真
return true;
}
else
{
//未安装,开始安装
string cmd_install = $"sc create \"{serv_name}\" binPath=\"{serv_runpath}\" start=auto DisplayName=\"{serv_displayname}\"";
var install_result = Com_ExeOS.Run.Cmd(cmd_install);
//非空判断,若返回值为空,则为假
if (string.IsNullOrEmpty(install_result))
{
throw new Exception($"创建服务 {serv_name} 时,返回值为空!");
}
//判断是否安装成功
if (install_result.Contains("成功") || install_result.ToLower().Contains("success"))
{
//描述信息不为空,配置描述信息
if (!string.IsNullOrEmpty(serv_description))
{
Modify.Description(serv_name, serv_description);
}
//无论修改描述信息是否成功,均返回成功
return true;
}
else
{
return false;
}
}
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return false;
}
}
internal static bool Delete(string serv_name)
{
if (Query.IsCreated(serv_name))
{
//已经创建服务,才能删除
//先停止服务
if (!Action.Stop(serv_name))
{
throw new Exception($"服务 {serv_name} 因无法停止,导致卸载失败!");
}
string cmd_del = $"sc delete \"{serv_name}\"";
var del_result = Com_ExeOS.Run.Cmd(cmd_del);
//非空判断,若返回值为空,则为假
if (string.IsNullOrEmpty(del_result))
{
throw new Exception($"删除服务 {serv_name} 时,返回值为空!");
}
//判断是否删除成功
if (del_result.Contains("成功") || del_result.ToLower().Contains("success"))
{
return true;
}
else
{
throw new Exception($"删除服务 {serv_name} 失败!");
}
}
else
{
throw new Exception($"没有找到名称为 {serv_name} 的服务,无法删除该服务!");
}
}
internal class Modify
{
internal static bool BinPath(string serv_name, string serv_binpath)
{
try
{
if (Query.IsCreated(serv_name))
{
//已经创建服务,才进行修改
string cmd_modify_binpath = $"sc config \"{serv_name}\" binPath=\"{serv_binpath}\"";
var modify_result = Com_ExeOS.Run.Cmd(cmd_modify_binpath);
//非空判断,若返回值为空,则为假
if (string.IsNullOrEmpty(modify_result))
{
throw new Exception($"执行修改 {serv_name} binPath 参数时,返回值为空!");
}
//判断是否修改 binPath 成功
if (modify_result.Contains("成功") || modify_result.ToLower().Contains("success"))
{
return true;
}
else
{
throw new Exception($"修改服务 {serv_name} 的 binPath 信息为 {serv_binpath} 失败!");
}
}
else
{
throw new Exception($"尝试修改服务 {serv_name} 的 binPath 信息为 {serv_binpath},但该服务未安装!");
}
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return false;
}
}
internal static bool DisplayName(string serv_name, string serv_displayname)
{
try
{
if (Query.IsCreated(serv_name))
{
//已经创建服务,才进行修改
string cmd_modify_displayname = $"sc config \"{serv_name}\" DisplayName=\"{serv_displayname}\"";
var modify_result = Com_ExeOS.Run.Cmd(cmd_modify_displayname);
//非空判断,若返回值为空,则为假
if (string.IsNullOrEmpty(modify_result))
{
throw new Exception($"执行修改 {serv_name} DisplayName 参数时,返回值为空!");
}
//判断是否修改 DisplayName 成功
if (modify_result.Contains("成功") || modify_result.ToLower().Contains("success"))
{
return true;
}
else
{
throw new Exception($"修改服务 {serv_name} 的 DisplayName 信息为 {serv_displayname} 失败!");
}
}
else
{
throw new Exception($"尝试修改服务 {serv_name} 的 DisplayName 信息为 {serv_displayname},但该服务未安装!");
}
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return false;
}
}
internal static bool Description(string serv_name, string serv_description)
{
try
{
if (Query.IsCreated(serv_name))
{
//已经创建服务,才进行修改
string cmd_modify_desc = $"sc description \"{serv_name}\" \"{serv_description}\"";
var modify_result = Com_ExeOS.Run.Cmd(cmd_modify_desc);
//非空判断,若返回值为空,则为假
if (string.IsNullOrEmpty(modify_result))
{
throw new Exception($"执行修改 {serv_name} 描述信息时,返回值为空!");
}
//判断是否修改描述成功
if (modify_result.Contains("成功") || modify_result.ToLower().Contains("success"))
{
return true;
}
else
{
throw new Exception($"修改服务 {serv_name} 的描述信息为 {serv_description} 失败!");
}
}
else
{
throw new Exception($"尝试修改服务 {serv_name} 的描述信息为 {serv_description},但该服务未安装!");
}
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return false;
}
}
}
}
}
}
================================================
FILE: LKY_OfficeTools/Common/Com_SystemOS.cs
================================================
/*
* [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.
*
* FileName : Com_SystemOS.cs
* Developer: OdysseusYuan@foxmail.com (Odysseus.Yuan)
*/
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using static LKY_OfficeTools.Lib.Lib_AppLog;
namespace LKY_OfficeTools.Common
{
internal class Com_SystemOS
{
internal class OSVersion
{
internal enum OSType
{
LowVersion,
WinXP,
WinVista,
Win7, //支持.NET 4.8
Win8_1, //支持.NET 4.8
Win10, //1607开始,支持.NET 4.8
Win11,
UnKnow
}
internal static readonly IDictionary<string, string> WinPublishType = new Dictionary<string, string>
{
//win10版本号
{ "10240", "1507" },
{ "10586", "1511" },
{ "14393", "1607" }, //.NET 4.8从此版本开始支持
{ "15063", "1703" },
{ "16299", "1709" },
{ "17134", "1803" },
{ "17763", "1809" },
{ "18362", "1903" },
{ "18363", "1909" },
{ "19041", "2004" },
{ "19042", "20H2" },
{ "19043", "21H1" },
{ "19044", "21H2" },
{ "19045", "22H2" },
//win11版本号
{ "22000", "21H2" },
{ "22621", "22H2" },
//{ "1111111111111111", "LTSB" },
//{ "1111111111111111", "LTSC" },
//{ "1111111111111111", "ARM" },
};
internal static OSType GetPublishType()
{
try
{
Version ver = Environment.OSVersion.Version;
if (ver.Major < 5)
{
return OSType.LowVersion;
}
else if (ver.Major == 5 && ver.Minor == 1)
{
return OSType.WinXP;
}
else if (ver.Major == 6 && ver.Minor == 0)
{
return OSType.WinVista;
}
else if (ver.Major == 6 && ver.Minor == 1)
{
return OSType.Win7;
}
else if (ver.Major == 6 && ver.Minor == 2)
{
return OSType.Win8_1;
}
else if (ver.Major == 10 && ver.Minor == 0) //正确获取win10版本号,需要在exe里面加入app.manifest
{
//检查注册表,因为win10和11的主版本号都为10,只能用buildID来判断了
string curr_ver = Register.Read.ValueBySystem(RegistryHive.LocalMachine, @"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentBuild");
if (!string.IsNullOrEmpty(curr_ver) && int.Parse(curr_ver) < 22000) //Win11目前内部版本号
{
return OSType.Win10;
}
else
{
return OSType.Win11;
}
}
else
{
return OSType.UnKnow;
}
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return OSType.UnKnow;
}
}
internal static string GetBuildNumber(bool isCoreVersion = true)
{
try
{
//检查注册表
string curr_mode = Register.Read.ValueBySystem(RegistryHive.LocalMachine, @"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentBuild");
//为空返回未知
if (string.IsNullOrEmpty(curr_mode))
{
return "unknow";
}
//判断返回的内容
if (isCoreVersion) //返回内部版本号
{
return curr_mode;
}
else //返回发行版本
{
return WinPublishType[curr_mode];
}
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return "error!";
}
}
}
internal class Register
{
internal class Read
{
internal static string Value(RegistryHive reg_root, RegistryView reg_view, string path, string key)
{
try
{
RegistryKey HK_Root = RegistryKey.OpenBaseKey(reg_root, reg_view);
RegistryKey path_reg = HK_Root.OpenSubKey(path); //先获取路径
if (path_reg == null)
{
//找不到注册表路径
return null;
}
else
{
object value = path_reg.GetValue(key);
if (value != null) //必须先判断不为null,否则会抛出异常
{
//一切正常
return value.ToString();
}
else
{
//Key不存在或值为空
return null;
}
}
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return null;
}
}
internal static string ValueBySystem(RegistryHive reg_root, string path, string key)
{
try
{
if (Environment.Is64BitOperatingSystem)
{
//x64系统,访问x64注册表
return Value(reg_root, RegistryView.Registry64, path, key);
}
else
{
//x32系统,访问x32注册表
return Value(reg_root, RegistryView.Registry32, path, key);
}
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return null;
}
}
internal static List<string> AllValues(RegistryHive reg_root, string path, string key)
{
try
{
List<string> result = new List<string>();
//获取x32的结构值
string value_x32 = Value(reg_root, RegistryView.Registry32, path, key);
if (!string.IsNullOrWhiteSpace(value_x32))
{
result.Add(value_x32);
}
//获取x64的结构值(仅在当前计算机为 x64 系统时,才获取)
if (Environment.Is64BitOperatingSystem)
{
string value_x64 = Value(reg_root, RegistryView.Registry64, path, key);
if (!string.IsNullOrWhiteSpace(value_x64))
{
result.Add(value_x64);
}
}
return result;
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return null;
}
}
}
internal static bool ExistItem(RegistryHive reg_root, RegistryView reg_view, string item_path)
{
try
{
RegistryKey reg = RegistryKey.OpenBaseKey(reg_root, reg_view);
var result = reg.OpenSubKey(item_path);
if (result != null)
{
return true;
}
result.Close();
return false;
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return false;
}
}
internal static bool DeleteItem(RegistryHive reg_root, RegistryView reg_view, string path, string item)
{
try
{
RegistryKey HK_Root = RegistryKey.OpenBaseKey(reg_root, reg_view);
RegistryKey path_reg = HK_Root.OpenSubKey(path, true); //先获取路径,启动可写模式
//找不到注册表路径,默认已删除,返回true
if (path_reg == null)
{
return true;
}
path_reg.DeleteSubKeyTree(item, false);
return true;
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return false;
}
}
internal static bool ExportReg(string reg_path, string save_to)
{
try
{
//先删除已经存在的文件
if (File.Exists(save_to))
{
File.Delete(save_to);
}
//开始导出
Directory.CreateDirectory(new FileInfo(save_to).DirectoryName); //先创建文件所在目录
Process.Start("regedit", $" /E \"{save_to}\" \"{reg_path}\"").WaitForExit();
if (File.Exists(save_to))
{
return true;
}
else
{
return false;
}
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return false;
}
}
}
}
}
================================================
FILE: LKY_OfficeTools/Common/Com_TextOS.cs
================================================
/*
* [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.
*
* FileName : Com_TextOS.cs
* Developer: OdysseusYuan@foxmail.com (Odysseus.Yuan)
*/
using System;
using static LKY_OfficeTools.Lib.Lib_AppLog;
namespace LKY_OfficeTools.Common
{
internal class Com_TextOS
{
internal static string GetCenterText(string str, string strLeft, string strRight)
{
try
{
if (str == null || str.Length == 0) return "";
if (strLeft != "")
{
int indexLeft = str.IndexOf(strLeft);//左边字符串位置
if (indexLeft < 0) return "";
indexLeft = indexLeft + strLeft.Length;//左边字符串长度
if (strRight != "")
{
int indexRight = str.IndexOf(strRight, indexLeft);//右边字符串位置
if (indexRight < 0) return "";
return str.Substring(indexLeft, indexRight - indexLeft);//indexRight - indexLeft是取中间字符串长度
}
else return str.Substring(indexLeft, str.Length - indexLeft);//取字符串右边
}
else
{
//取字符串左边
int indexRight = str.IndexOf(strRight);
if (indexRight <= 0) return "";
else return str.Substring(0, indexRight);
}
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return null;
}
}
internal static int GetStringTimes(string str, string scan_str)
{
try
{
int index = 0;
int count = 0;
while ((index = str.IndexOf(scan_str, index)) != -1)
{
count++;
index += scan_str.Length;
}
return count;
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return 0;
}
}
}
}
================================================
FILE: LKY_OfficeTools/Common/Com_Timer.cs
================================================
/*
* [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.
*
* FileName : Com_Timer.cs
* Developer: OdysseusYuan@foxmail.com (Odysseus.Yuan)
*/
using System;
using System.Threading;
using static LKY_OfficeTools.Lib.Lib_AppLog;
namespace LKY_OfficeTools.Common
{
internal class Com_Timer
{
internal class Countdown_Timer
{
internal int Remaining_Time
{ get; set; }
internal bool isRun
{ get; set; }
internal void Start(int total_time)
{
try
{
//此处不放入线程,否则使用isRun判断是否在运行时,会导致isRun状态无法判断
Remaining_Time = total_time;
isRun = true;
Thread time_t = new Thread(() =>
{
Update();
//迭代完成后,自动停止运行
isRun = false;
});
//time_t.SetApartmentState(ApartmentState.STA);
time_t.Start();
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return;
}
}
void Update()
{
try
{
//倒计时不为0,且给出运行指令
if (Remaining_Time > 0 & isRun)
{
Thread.Sleep(1000);
Remaining_Time--;
Update(); //轮询继续
}
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return;
}
}
internal void Pause()
{
try
{
isRun = false;
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return;
}
}
internal void Continue()
{
try
{
if (Remaining_Time != 0)
{
isRun = true;
}
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return;
}
}
internal void Stop()
{
try
{
Pause();
Remaining_Time = 0;
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return;
}
}
}
}
}
================================================
FILE: LKY_OfficeTools/Common/Com_WebOS.cs
================================================
/*
* [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.
*
* FileName : Com_WebOS.cs
* Developer: OdysseusYuan@foxmail.com (Odysseus.Yuan)
*/
using System;
using System.Net;
using System.Text;
using static LKY_OfficeTools.Lib.Lib_AppLog;
namespace LKY_OfficeTools.Common
{
internal class Com_WebOS
{
internal static string Visit_WebClient(string url, Encoding encoding = null)
{
try
{
if (encoding == null)
{
encoding = Encoding.UTF8;
}
using (WebClient WC = new WebClient())
{
WC.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.84 Safari/537.36");
WC.Credentials = CredentialCache.DefaultCredentials;//获取或设置用于向Internet资源的请求进行身份验证的网络凭据
Byte[] pageData = WC.DownloadData(url); //从指定网站下载数据
return encoding.GetString(pageData);
}
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return null;
}
}
}
}
================================================
FILE: LKY_OfficeTools/LKY_OfficeTools.csproj
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{6D00F508-106A-42D1-BE0F-048762434E69}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>LKY_OfficeTools</RootNamespace>
<AssemblyName>LKY_OfficeTools</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<PlatformTarget>x86</PlatformTarget>
<OutputPath>bin\x86\Debug\</OutputPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<PlatformTarget>x86</PlatformTarget>
<OutputPath>bin\x86\Release\</OutputPath>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>logo.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup>
<TargetZone>Custom</TargetZone>
</PropertyGroup>
<PropertyGroup>
<GenerateManifests>false</GenerateManifests>
</PropertyGroup>
<PropertyGroup>
<ApplicationManifest>Properties\app.manifest</ApplicationManifest>
</PropertyGroup>
<ItemGroup>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.IO.Compression" />
<Reference Include="System.IO.Compression.FileSystem" />
<Reference Include="System.ServiceProcess" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xaml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
<Compile Include="Common\Com_ExeOS.cs" />
<Compile Include="Common\Com_FileOS.cs" />
<Compile Include="Common\Com_InstallerOS.cs" />
<Compile Include="Common\Com_NetworkOS.cs" />
<Compile Include="Common\Com_PrivilegeOS.cs" />
<Compile Include="Common\Com_ServiceOS.cs" />
<Compile Include="Common\Com_SystemOS.cs" />
<Compile Include="Common\Com_TextOS.cs" />
<Compile Include="Common\Com_Timer.cs" />
<Compile Include="Common\Com_WebOS.cs" />
<Compile Include="Lib\Lib_AppClosing.cs" />
<Compile Include="Lib\Lib_AppCommand.cs" />
<Compile Include="Lib\Lib_AppState.cs" />
<Compile Include="Lib\Lib_AppInfo.cs" />
<Compile Include="Lib\Lib_AppMessage.cs" />
<Compile Include="Lib\Lib_AppSdk.cs" />
<Compile Include="Lib\Lib_AppServiceHub.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Lib\Lib_AppServiceHub.Designer.cs">
<DependentUpon>Lib_AppServiceHub.cs</DependentUpon>
</Compile>
<Compile Include="Lib\Lib_AppServiceConfig.cs" />
<Compile Include="Lib\Lib_AppSignCert.cs" />
<Compile Include="Lib\Lib_OfficeActivate.cs" />
<Compile Include="Lib\Lib_OfficeDownload.cs" />
<Compile Include="Lib\Lib_OfficeInfo.cs" />
<Compile Include="Lib\Lib_OfficeInstall.cs" />
<Compile Include="Lib\Lib_AppLog.cs" />
<Compile Include="Lib\Lib_AppUpdate.cs" />
<Compile Include="Lib\Lib_OfficeClean.cs" />
<Compile Include="Lib\Lib_OfficeProcess.cs" />
<Compile Include="OfficeTools.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Lib\Lib_Aria2c.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="Resource\Json\LKY_OfficeTools_AppInfo.json" />
<None Include="Resource\Json\OfficeChannels.txt" />
<None Include="Properties\app.manifest" />
<EmbeddedResource Include="Resource\Office_Processes.list" />
<EmbeddedResource Include="Resource\SDK\Activate.lotp" />
<EmbeddedResource Include="Resource\SDK\Aria2c.lotp" />
<EmbeddedResource Include="Resource\SDK\ODT.lotp" />
<EmbeddedResource Include="Resource\SDK\SaRA.lotp" />
<EmbeddedResource Include="Resource\PublisherCert.cer" />
</ItemGroup>
<ItemGroup>
<Content Include="logo.ico" />
<EmbeddedResource Include="Resource\SDK\SDK_Processes.list" />
</ItemGroup>
<ItemGroup>
<COMReference Include="WindowsInstaller">
<Guid>{000C1092-0000-0000-C000-000000000046}</Guid>
<VersionMajor>1</VersionMajor>
<VersionMinor>0</VersionMinor>
<Lcid>1033</Lcid>
<WrapperTool>tlbimp</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
================================================
FILE: LKY_OfficeTools/Lib/Lib_AppClosing.cs
================================================
/*
* [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.
*
* FileName : Lib_AppClosing.cs
* Developer: OdysseusYuan@foxmail.com (Odysseus.Yuan)
*/
using System;
using System.Runtime.InteropServices;
using static LKY_OfficeTools.Common.Com_ExeOS.KillExe;
using static LKY_OfficeTools.Lib.Lib_AppLog;
using static LKY_OfficeTools.Lib.Lib_AppState;
namespace LKY_OfficeTools.Lib
{
internal class Lib_AppClosing
{
internal class CloseWindow
{
internal delegate bool ControlCtrlDelegate(int CtrlType);
[DllImport("kernel32.dll")]
internal static extern bool SetConsoleCtrlHandler(ControlCtrlDelegate HandlerRoutine, bool Add);
internal static ControlCtrlDelegate newDelegate = new ControlCtrlDelegate(HandlerRoutine);
internal static bool HandlerRoutine(int CtrlType)
{
//只要程序不是已完成(无论成功与否),手动关闭,就会显示文字并打点
if (Current_StageType != ProcessStage.Finish_Fail && Current_StageType != ProcessStage.Finish_Success)
{
new Log($"\n × 正在尝试 取消部署,请稍候 ...", ConsoleColor.DarkRed);
Current_StageType = ProcessStage.Interrupt; //设置中断状态。非完成情况下,关闭,属于 中断部署 状态,此处用于停止 下载 office 进程
Console.ForegroundColor = ConsoleColor.Gray; //重置颜色,如果第一次失败,颜色还是可以正常的
//结束残存进程
Lib_AppSdk.KillAllSdkProcess(KillMode.Try_Friendly);
/*Pointing(ProcessStage.Interrupt); 暂停中断打点 */ //中断 点位。下载时触发该逻辑,打点会失败。
}
else
{
//完成状态时,清理文件夹
Lib_AppSdk.Clean(); //清理SDK目录
}
return false;
}
}
}
}
================================================
FILE: LKY_OfficeTools/Lib/Lib_AppCommand.cs
================================================
/*
* [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.
*
* FileName : Lib_AppCommand.cs
* Developer: OdysseusYuan@foxmail.com (Odysseus.Yuan)
*/
using System;
using static LKY_OfficeTools.Lib.Lib_AppLog;
using static LKY_OfficeTools.Lib.Lib_AppState;
namespace LKY_OfficeTools.Lib
{
internal class Lib_AppCommand
{
internal static ArgsFlag AppCommandFlag { get; set; }
internal Lib_AppCommand(string[] args)
{
try
{
//非空判断
if (args != null && args.Length > 0)
{
foreach (var now_arg in args)
{
//单独arg非空判断
if (!string.IsNullOrWhiteSpace(now_arg))
{
//对于 /passive 模式,自动跳过所有需要确认的步骤
if (now_arg.Contains("/passive"))
{
SkipAllConfirm();
Current_RunMode = RunMode.Passive; //设置为被动模式
break;
}
//服务模式。该模式 与 passive 是互斥的。
else if (now_arg.Contains("/service"))
{
Current_RunMode = RunMode.Service; //设置为服务模式
//以服务模式运行
Lib_AppServiceConfig.Start(); //在Hub类库设置中,service模式将被添加passive标记。
//找到服务模式,不再执行后续的
Environment.Exit(-100);
}
//非服务、非被动模式
else
{
Current_RunMode = RunMode.Manual; //设置为手动模式
if (now_arg.ToLower().Contains("/none_welcome_confirm"))
{
AppCommandFlag |= ArgsFlag.None_Welcome_Confirm;
}
if (now_arg.ToLower().Contains("/ignore_manual_update_msg"))
{
AppCommandFlag |= ArgsFlag.Ignore_Manual_Update_Msg;
}
if (now_arg.ToLower().Contains("/auto_remove_conflict_office"))
{
AppCommandFlag |= ArgsFlag.Auto_Remove_Conflict_Office;
}
if (now_arg.ToLower().Contains("/none_finish_presskey"))
{
AppCommandFlag |= ArgsFlag.None_Finish_PressKey;
}
continue;
}
}
}
}
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return;
}
}
[Flags]
internal enum ArgsFlag
{
None_Welcome_Confirm = 2,
Ignore_Manual_Update_Msg = 4,
Auto_Remove_Conflict_Office = 8,
None_Finish_PressKey = 16,
}
private static bool SkipAllConfirm()
{
try
{
AppCommandFlag |=
ArgsFlag.None_Welcome_Confirm |
ArgsFlag.Auto_Remove_Conflict_Office |
ArgsFlag.Ignore_Manual_Update_Msg |
ArgsFlag.None_Finish_PressKey;
return true;
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return false;
}
}
}
}
================================================
FILE: LKY_OfficeTools/Lib/Lib_AppInfo.cs
================================================
/*
* [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.
*
* FileName : Lib_AppInfo.cs
* Developer: OdysseusYuan@foxmail.com (Odysseus.Yuan)
*/
using LKY_OfficeTools.Common;
using System;
using System.Diagnostics;
using System.IO;
using static LKY_OfficeTools.Lib.Lib_AppLog;
namespace LKY_OfficeTools.Lib
{
internal class Lib_AppInfo
{
internal class AppAttribute
{
internal const string AppName = "LKY Office Tools";
internal const string AppName_Short = "LOT";
internal static readonly string ServiceName = ServiceDisplayName.Replace(" ", "");
internal const string ServiceDisplayName = AppName + " Service";
internal const string AppFilename = "LKY_OfficeTools.exe";
internal const string AppVersion = "1.3.0.223";
internal const string Developer = "LiuKaiyuan";
}
internal class AppJson
{
private static string AppJsonInfo = null;
internal static string Info
{
get
{
try
{
//内部变量非空时,直接返回其值
if (!string.IsNullOrEmpty(AppJsonInfo))
{
return AppJsonInfo;
}
#if (!DEBUG)
//release模式地址
string json_url = $"https://gitee.com/OdysseusYuan/LKY_OfficeTools/releases/download/AppInfo/LKY_OfficeTools_AppInfo.json";
#else
//debug模式地址
string json_url = $"https://gitee.com/OdysseusYuan/LOT_OnlyTest/releases/download/AppInfo_Test/test.json";
#endif
//获取 Json 信息
string result = Com_WebOS.Visit_WebClient(json_url);
AppJsonInfo = result;
return AppJsonInfo;
}
catch (Exception Ex)
{
new Log(Ex.ToString());
//new Log($" × 获取 AppJson 信息失败!", ConsoleColor.DarkRed);
new Log($"获取 AppJson 信息失败!");
return null;
}
}
}
}
internal class AppDevelop
{
internal const string NameSpace_Top = "LKY_OfficeTools";
}
internal class AppPath
{
internal static string ExecuteDir
{
get
{
//使用 BaseDirectory 获取路径时,结尾会多一个 \ 符号,为了替换之,先在结果处增加一个斜杠,变成 \\ 结尾,然后替换掉这个 双斜杠
return (AppDomain.CurrentDomain.BaseDirectory + @"\").Replace(@"\\", @"");
}
}
internal static string Executer
{
get
{
return new FileInfo(Process.GetCurrentProcess().MainModule.FileName).FullName;
}
}
internal class Documents
{
internal static string Documents_Root
{
get
{
if (Lib_AppState.Must_Use_PersonalDir)
{
return $"{Environment.GetFolderPath(Environment.SpecialFolder.Personal)}\\{AppAttribute.AppName}"; //我的文档
}
else
{
return $"{Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)}\\{AppAttribute.AppName}"; //ProgramData
}
}
}
internal class Update
{
internal static string Update_Root
{
get
{
return $"{Documents_Root}\\Update";
}
}
internal static string UpdateTrash
{
get
{
if (Path.GetPathRoot(Executer) == Path.GetPathRoot(Documents_Root))
{
//相同盘符,使用默认回收站目录
return $"{Update_Root}\\Trash";
}
else
{
//不同盘符,使用子目录
return $"{ExecuteDir}\\Trash";
}
}
}
}
internal class Services
{
internal static string Services_Root
{
get
{
return $"{Documents_Root}\\Services";
}
}
internal static string ServicesTrash
{
get
{
return $"{Services_Root}\\Trash";
}
}
internal static string ServiceAutorun
{
get
{
return $"{Services_Root}\\Autorun";
}
}
internal static string ServiceAutorun_Exe
{
get
{
return $"{ServiceAutorun}\\{AppAttribute.AppFilename}";
}
}
internal static string PassiveProcessInfo
{
get
{
return $"{Services_Root}\\PassiveProcess.info";
}
}
}
internal static string Logs
{
get
{
return $"{Documents_Root}\\Logs";
}
}
internal static string Temp
{
get
{
return $"{Documents_Root}\\Temp";
}
}
internal class SDKs
{
internal static string SDKs_Root
{
get
{
return $"{Documents_Root}\\SDKs";
}
}
internal static string Activate
{
get
{
return $"{SDKs_Root}\\Activate";
}
}
internal static string Activate_OSPP
{
get
{
return $"{Activate}\\OSPP.VBS";
}
}
}
}
}
}
}
================================================
FILE: LKY_OfficeTools/Lib/Lib_AppLog.cs
================================================
/*
* [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.
*
* FileName : Lib_AppLog.cs
* Developer: OdysseusYuan@foxmail.com (Odysseus.Yuan)
*/
using LKY_OfficeTools.Common;
using System;
using System.IO;
using static LKY_OfficeTools.Lib.Lib_AppInfo.AppPath;
using static LKY_OfficeTools.Lib.Lib_OfficeInfo.OfficeLocalInfo;
namespace LKY_OfficeTools.Lib
{
internal class Lib_AppLog
{
internal class Log
{
internal static string log_filepath = null;
internal static string reg_install_error { get; set; }
internal static string log_info { get; set; }
/*
internal static List<string> error_screen_path = new List<string>();
*/
internal enum Output_Type
{
Display,
Write,
Display_Write
}
internal Log(string str, ConsoleColor str_color, Output_Type output_type = Output_Type.Display_Write)
{
try
{
//判断是否需要显示文字
if (output_type == Output_Type.Display || output_type == Output_Type.Display_Write)
{
Console.ForegroundColor = str_color;
Console.WriteLine(str);
//输出后恢复颜色
Console.ForegroundColor = ConsoleColor.Gray;
}
//需要输出日志文件时,进行判断
if (output_type == Output_Type.Write || output_type == Output_Type.Display_Write)
{
string datatime_format = DateTime.Now.ToString("s").Replace("T", "_").Replace(":", "-");
//服务模式,写出到日志文件
if (Lib_AppState.Current_RunMode == Lib_AppState.RunMode.Service)
{
//为空时,创建日志路径
if (string.IsNullOrEmpty(log_filepath))
{
string file_name = "service_" + datatime_format + ".log";
log_filepath = $"{Documents.Logs}\\{file_name}";
}
//目录不存在时创建目录
Directory.CreateDirectory(new FileInfo(log_filepath).DirectoryName);
//文件不存在时创建&写入
File.AppendAllText(log_filepath, $"{datatime_format}, {str}\n");
}
//将日志记录在内存中
string now_log = $"{datatime_format}, {str.Replace("\n", "")}";
if (str.Contains("×"))
{
now_log = $"<font color=red><b>{now_log}</b></font>"; //有错误标红、加粗
}
else if (str.Contains("Exception"))
{
now_log = $"<font color=\"#ff4c00\">{now_log}</font>"; //抛出异常用橙红色
}
log_info += now_log + "<br />";
/*
//出现错误时,增加附加信息
if (str.Contains("×"))
{
string err_filename = datatime_format + ".png";
err_filename = $"{Lib_AppInfo.Path.Dir_Log}\\{err_filename}";
if (Com_SystemOS.Screen.CaptureToSave(err_filename))
{
error_screen_path.Add(err_filename);
}
}
*/
}
}
catch
{
return;
}
}
internal Log(string err_str)
{
try
{
//整合格式
string msg = $"---------- [Error Log: BEGIN] ----------\n{err_str}\n---------- [END] ----------";
//非服务模式,替换换行符
if (Lib_AppState.Current_RunMode != Lib_AppState.RunMode.Service)
{
msg = msg.Replace("\n", "<br />");
}
//输出日志
new Log(msg, ConsoleColor.Gray, Output_Type.Write);
}
catch
{
return;
}
}
internal Log(InstallState install_error)
{
try
{
//安装出错后,会记录系统目前office注册表情况
//导出注册表 Office 信息
string office_reg_path = @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office";
//依据不同的安装错误生成不同的注册表文件名
string reg_filename = "error";
//包含未安装标记
if (install_error == InstallState.None)
{
reg_filename += "_none";
}
//包含不同版本标记
if (install_error == InstallState.Diff)
{
reg_filename += "_diff";
}
//包含多版本标记
if (install_error == InstallState.Multi)
{
reg_filename += "_multi";
}
//包含安装正确标记
if (install_error == InstallState.Correct)
{
reg_filename += "_correct";
}
//合成最终注册表路径
reg_install_error = Documents.Logs + $@"\{reg_filename}.reg";
//生成注册表信息
Com_SystemOS.Register.ExportReg(office_reg_path, reg_install_error);
return;
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return;
}
}
internal static bool Clean()
{
try
{
/*
//清理日志
if (log_filepath != null)
{
try
{
File.Delete(log_filepath);
}
catch (Exception Ex)
{
new Log(Ex.ToString());
}
}
*/
/*
//清理错误截屏
if (error_screen_path != null)
{
foreach (var now_file in error_screen_path)
{
try
{
File.Delete(now_file);
}
catch (Exception Ex)
{
new Log(Ex.ToString());
}
}
}
*/
//清理整个Log文件夹
if (Directory.Exists(Documents.Logs))
{
try
{
Directory.Delete(Documents.Logs, true);
}
catch (Exception Ex)
{
new Log(Ex.ToString());
}
}
return true;
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return false;
}
}
}
}
}
================================================
FILE: LKY_OfficeTools/Lib/Lib_AppMessage.cs
================================================
/*
* [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.
*
* FileName : Lib_AppMessage.cs
* Developer: OdysseusYuan@foxmail.com (Odysseus.Yuan)
*/
using System;
using System.Threading;
using static LKY_OfficeTools.Common.Com_Timer;
using static LKY_OfficeTools.Lib.Lib_AppCommand;
using static LKY_OfficeTools.Lib.Lib_AppLog;
namespace LKY_OfficeTools.Lib
{
internal class Lib_AppMessage
{
internal class KeyMsg
{
internal static void Quit(int exit_code)
{
//清理SDK缓存
Lib_AppSdk.Clean();
//退出机制
if (!AppCommandFlag.HasFlag(ArgsFlag.None_Finish_PressKey))
{
//不包含“结束无需确认”命令行,需要人工按键结束
Console.ForegroundColor = ConsoleColor.Gray;
Console.Write("\n请按 任意键 退出 ...");
Console.ReadKey();
Environment.Exit(exit_code);
}
}
internal static bool Confirm(string msg_str = null)
{
Console.ForegroundColor = ConsoleColor.Gray;
//判断是否为空
if (string.IsNullOrWhiteSpace(msg_str))
{
//msg为空,直接展示回车键继续,并且前面不空格
msg_str = $"\n请按 回车键(Enter)继续 ...";
}
else
{
//msg不为空,一般在运行过程中的确认,有空格,并且增加逗号
msg_str = $" {msg_str},请按 回车键(Enter)继续 ...";
}
Console.Write(msg_str); //提示信息
new Log(msg_str, ConsoleColor.Gray, Log.Output_Type.Write); //写入日志
if (Console.ReadKey().Key == ConsoleKey.Enter)
{
Console.WriteLine(); //增加一个空白行
return true;
}
else
{
Console.WriteLine(); //增加一个空白行
return false;
}
}
internal static void DoByTime(string msg_str, int countdown_time)
{
Console.ForegroundColor = ConsoleColor.Gray;
Console.WriteLine(); //插入一个空白行
//设置一个倒计时组件
Countdown_Timer timer = new Countdown_Timer();
timer.Start(countdown_time);
//循环输出
while (timer.isRun)
{
string msg = $"{msg_str}将在 {timer.Remaining_Time} 秒内开始 ...";
new Log(msg, ConsoleColor.Gray, Log.Output_Type.Write); //写入日志
Thread.Sleep(100);
//输出消息倒计时
Console.Write($"\r{msg}");
}
//倒计时结束后,告知开始
Console.Write($"\r{msg_str}启动 ... ");
//完成等待
Console.WriteLine(); //增加一个空白行
return;
}
internal static bool Choose(string todo_thing)
{
new Log($"\n ★ {todo_thing}", ConsoleColor.Gray);
Console.ForegroundColor = ConsoleColor.Gray;
string msg = $" 按 回车键(Enter)确认执行上述操作,按 其它键 跳过此环节 ...";
Console.Write(msg);
new Log(msg, ConsoleColor.Gray, Log.Output_Type.Write); //写入日志
if (Console.ReadKey().Key == ConsoleKey.Enter)
{
Console.WriteLine(); //增加一个空白行
return true;
}
else
{
Console.WriteLine(); //增加一个空白行
return false;
}
}
}
}
}
================================================
FILE: LKY_OfficeTools/Lib/Lib_AppSdk.cs
================================================
/*
* [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.
*
* FileName : Lib_AppSdk.cs
* Developer: OdysseusYuan@foxmail.com (Odysseus.Yuan)
*/
using LKY_OfficeTools.Common;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Threading;
using static LKY_OfficeTools.Common.Com_ExeOS;
using static LKY_OfficeTools.Lib.Lib_AppInfo;
using static LKY_OfficeTools.Lib.Lib_AppInfo.AppPath;
using static LKY_OfficeTools.Lib.Lib_AppLog;
using static LKY_OfficeTools.Lib.Lib_AppMessage;
using static LKY_OfficeTools.Lib.Lib_AppState;
namespace LKY_OfficeTools.Lib
{
internal class Lib_AppSdk
{
enum SdkPackage
{
Activate,
Aria2c,
ODT,
SaRA,
}
private static Dictionary<SdkPackage, Stream> SdkPackageDic
{
get
{
try
{
//初始字典
Dictionary<SdkPackage, Stream> res_dic = new Dictionary<SdkPackage, Stream>();
var asm = Assembly.GetExecutingAssembly();
res_dic[SdkPackage.Activate] = asm.GetManifestResourceStream(AppDevelop.NameSpace_Top /* 当命名空间发生改变时,此值也需要调整 */
+ $".Resource.SDK.{SdkPackage.Activate}.lotp");
res_dic[SdkPackage.Aria2c] = asm.GetManifestResourceStream(AppDevelop.NameSpace_Top /* 当命名空间发生改变时,此值也需要调整 */
+ $".Resource.SDK.{SdkPackage.Aria2c}.lotp");
res_dic[SdkPackage.ODT] = asm.GetManifestResourceStream(AppDevelop.NameSpace_Top /* 当命名空间发生改变时,此值也需要调整 */
+ $".Resource.SDK.{SdkPackage.ODT}.lotp");
res_dic[SdkPackage.SaRA] = asm.GetManifestResourceStream(AppDevelop.NameSpace_Top /* 当命名空间发生改变时,此值也需要调整 */
+ $".Resource.SDK.{SdkPackage.SaRA}.lotp");
return res_dic;
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return null;
}
}
}
private static Dictionary<SdkPackage, string> SdkPkgPath
{
get
{
try
{
//初始字典
Dictionary<SdkPackage, string> extra_dic = new Dictionary<SdkPackage, string>();
extra_dic[SdkPackage.Activate] = Documents.SDKs.SDKs_Root + $"\\{SdkPackage.Activate}.lotp";
extra_dic[SdkPackage.Aria2c] = Documents.SDKs.SDKs_Root + $"\\{SdkPackage.Aria2c}.lotp";
extra_dic[SdkPackage.ODT] = Documents.SDKs.SDKs_Root + $"\\{SdkPackage.ODT}.lotp";
extra_dic[SdkPackage.SaRA] = Documents.SDKs.SDKs_Root + $"\\{SdkPackage.SaRA}.lotp";
return extra_dic;
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return null;
}
}
}
internal static bool Initial()
{
try
{
new Log($"\n------> 正在配置 {AppAttribute.AppName} 基础组件 ...", ConsoleColor.DarkCyan);
Thread.Sleep(1000); //短暂间隔,提升下体验
new Log($" >> 此过程会持续些许时间,这取决于您的电脑硬件配置,请耐心等待 ...", ConsoleColor.DarkYellow);
//初始化前先清理SDK目录,防止因为文件已经存在,引发解压的catch
Clean();
//释放文件
if (SdkPackageDic == null)
{
throw new Exception("读取 SDK 内存资源失败!");
}
foreach (var now_pkg in SdkPackageDic)
{
string pkg_path = SdkPkgPath[now_pkg.Key];
bool isToDisk = Com_FileOS.Write.FromStream(now_pkg.Value, pkg_path);
if (!isToDisk)
{
//写出异常,抛出
throw new IOException($"无法写出 SDK 文件 {pkg_path} 到硬盘!");
}
//无异常,解压包
ZipFile.ExtractToDirectory(pkg_path, Documents.SDKs.SDKs_Root + $@"\{now_pkg.Key}");
}
new Log($" √ 已完成 {AppAttribute.AppName} 组件配置。", ConsoleColor.DarkGreen);
return true;
}
catch (IOException IO_Ex)
{
new Log(IO_Ex.ToString());
//读写出现意外
new Log($" × 配置 {AppAttribute.AppName} 基础组件失败。请确保您的系统盘具备足够的可写空间!", ConsoleColor.DarkRed);
//清理SDK缓存
Clean();
Current_StageType = ProcessStage.Finish_Fail; //设置为失败模式
//退出提示
KeyMsg.Quit(-2);
return false;
}
catch (UnauthorizedAccessException Au_Ex)
{
new Log(Au_Ex.ToString());
//不具备读写权限
new Log($" × 配置 {AppAttribute.AppName} 基础组件失败。请确保您具备对 {Documents.SDKs.SDKs_Root} 目录的写入权限!", ConsoleColor.DarkRed);
//清理SDK缓存
Clean();
Current_StageType = ProcessStage.Finish_Fail; //设置为失败模式
//退出提示
KeyMsg.Quit(-2);
return false;
}
catch (Exception Ex)
{
new Log(Ex.ToString());
//其它未知问题
new Log($" × 配置 {AppAttribute.AppName} 基础组件失败,无法继续。请重新下载本软件或联系开发者!", ConsoleColor.DarkRed);
//清理SDK缓存
Clean();
Current_StageType = ProcessStage.Finish_Fail; //设置为失败模式
//退出提示
KeyMsg.Quit(-10);
return false;
}
finally
{
//清理 SDK pkg文件
var extra_sdk_list = SdkPkgPath.Values.ToList();
foreach (var now_path in extra_sdk_list)
{
if (File.Exists(now_path))
{
try
{
File.Delete(now_path);
}
catch (Exception Ex)
{
new Log(Ex.ToString());
new Log($"Exception: 清理 SDK 的 {now_path} 文件失败!");
}
}
}
}
}
internal static bool Clean()
{
try
{
//目录不存在时,自动返回为真
if (!Directory.Exists(Documents.SDKs.SDKs_Root))
{
return true;
}
Directory.Delete(Documents.SDKs.SDKs_Root, true);
return true;
}
catch (Exception Ex)
{
new Log(Ex.ToString());
new Log($"清理 SDK 目录失败!");
return false;
}
}
internal static List<string> Process_List
{
get
{
try
{
Stream sdk_processes_res = Assembly.GetExecutingAssembly().
GetManifestResourceStream(AppDevelop.NameSpace_Top /* 当命名空间发生改变时,此值也需要调整 */
+ ".Resource.SDK.SDK_Processes.list");
StreamReader sdk_processes_sr = new StreamReader(sdk_processes_res);
string sdk_processes = sdk_processes_sr.ReadToEnd();
if (!string.IsNullOrWhiteSpace(sdk_processes))
{
List<string> sdk_processes_list = new List<string>();
string[] p_info = sdk_processes.Replace("\r", "").Split('\n'); //分割出进程数组
if (p_info != null && p_info.Length > 0)
{
foreach (var now_process in p_info)
{
sdk_processes_list.Add(now_process);
}
return sdk_processes_list;
}
}
return null;
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return null;
}
}
}
internal static bool KillAllSdkProcess(KillExe.KillMode mode)
{
try
{
//轮询结束每个进程(不等待)
foreach (var now_p in Process_List)
{
KillExe.ByExeName(now_p, mode, false);
}
return true;
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return false;
}
}
}
}
================================================
FILE: LKY_OfficeTools/Lib/Lib_AppServiceConfig.cs
================================================
/*
* [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.
*
* FileName : Lib_AppServiceConfig.cs
* Developer: OdysseusYuan@foxmail.com (Odysseus.Yuan)
*/
using LKY_OfficeTools.Common;
using System;
using System.IO;
using System.ServiceProcess;
using static LKY_OfficeTools.Common.Com_ServiceOS;
using static LKY_OfficeTools.Lib.Lib_AppInfo;
using static LKY_OfficeTools.Lib.Lib_AppLog;
using static LKY_OfficeTools.Lib.Lib_AppMessage;
using static LKY_OfficeTools.Lib.Lib_AppState;
namespace LKY_OfficeTools.Lib
{
internal class Lib_AppServiceConfig
{
internal static void Setup()
{
try
{
//无论手动、被动模式,只要安装了服务,就自动更新之
if (Com_ServiceOS.Query.IsCreated(AppAttribute.ServiceName))
{
AddOrUpdate();
}
else
{
//未安装过。根据模式不同,给出判断
//手动模式,提示添加
if (Current_RunMode == RunMode.Manual)
{
//让用户选择是否添加自检服务
if (KeyMsg.Choose("为保证 Office 始终处于最新正版,即将添加 Office 自动更新/正版激活 服务。"))
{
AddOrUpdate();
}
else
{
new Log($" × 您已拒绝添加 Office 自动更新/正版激活 服务,若要重新添加,请再次运行本软件!", ConsoleColor.DarkRed);
return;
}
}
//被动模式,自动安装服务信息
else if (Current_RunMode == RunMode.Passive)
{
AddOrUpdate();
}
}
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return;
}
}
enum Add_Result
{
Add_Success,
Add_Fail,
Add_Error,
Update_Success,
Update_Fail,
Update_Error,
Unknow,
}
static Add_Result AddOrUpdate()
{
try
{
//构建服务基本信息
string serv_name = AppAttribute.ServiceName;
string serv_execmd = AppPath.Documents.Services.ServiceAutorun_Exe + " /service";
string serv_displayname = AppAttribute.ServiceDisplayName;
string serv_desc = "用于检测、下载、安装和激活正版 Office 的重要服务。如果此服务被禁用,这台计算机的用户将无法获取 Office 更新,也无法使其处于最新正版激活状态。";
//判断是否安装
if (Com_ServiceOS.Query.IsCreated(serv_name))
{
//已安装服务
new Log($"\n------> 正在更新 {AppAttribute.ServiceDisplayName} 服务 ...", ConsoleColor.DarkCyan);
//校验其属性是否一致
//修改 exe 运行信息
if (!Com_ServiceOS.Query.CompareBinPath(serv_name, serv_execmd))
{
Com_ServiceOS.Config.Modify.BinPath(serv_name, serv_execmd);
}
//修改 DisplayName
var service_info = Com_ServiceOS.Query.GetService(serv_name); //无需判断是否为空,IsCreated() 已经判断过
if (service_info.DisplayName != serv_displayname)
{
//DisplayName 不同时,修改之
Com_ServiceOS.Config.Modify.DisplayName(serv_name, serv_displayname);
}
//修改 描述信息
if (!Com_ServiceOS.Query.CompareDescription(serv_name, serv_desc))
{
Com_ServiceOS.Config.Modify.Description(serv_name, serv_desc);
}
//信息修改完成后,需要更新服务对应的文件
string serv_filepath = AppPath.Documents.Services.ServiceAutorun_Exe;
if (File.Exists(serv_filepath))
{
//运行的文件和服务目录下的文件 哈希值 一致时,跳过替换旧版本,否则要升级替换旧版本(常用于更新场景下)
if (Com_FileOS.Info.GetHash(AppPath.Executer) == Com_FileOS.Info.GetHash(serv_filepath))
{
//哈希值一致,说明,服务文件和当前运行的文件是相同的,无需替换
new Log($" √ 无需升级服务,已刷新 {AppAttribute.ServiceDisplayName} 信息。", ConsoleColor.DarkGreen);
return Add_Result.Update_Success;
}
//文件哈希值不一样,开始替换升级
/* 替换逻辑
* 1、如果运行路径 = 服务路径,【因为服务配置发生在更新之后,相等时,文件已经是最新的,达到了预期(更新服务文件)的目的。不做任何操作】
* 2、运行路径 != 服务路径,【移动旧文件到trash目录,拷贝运行路径文件到服务路径】
*/
if (AppPath.Executer != serv_filepath) //用户在非服务目录下运行
{
//move方式,解决服务启动状态中,文件无法被替换的问题。(停止服务会导致自身进程被结束)
string dest_filepath = AppPath.Documents.Services.ServicesTrash + $"\\{DateTime.Now.ToFileTime()}.old";
Directory.CreateDirectory(Path.GetDirectoryName(dest_filepath)); //创建计划移动到的目录
File.Move(serv_filepath, dest_filepath);
//复制自身文件到服务目录下
File.Copy(AppPath.Executer, serv_filepath, true);
}
}
else
{
//如果服务安装了,但文件丢失了,此处将自身文件 copy 到服务专用目录
Directory.CreateDirectory(Path.GetDirectoryName(serv_filepath)); //先创建服务目录,否则copy文件会异常
File.Copy(AppPath.Executer, serv_filepath, true);
}
new Log($" √ 已更新 {AppAttribute.ServiceDisplayName} 服务。", ConsoleColor.DarkGreen);
return Add_Result.Update_Success;
}
else
{
//未安装服务时,添加服务
new Log($"\n------> 正在安装 Office 自动更新/正版激活 服务 ...", ConsoleColor.DarkCyan);
var create_result = Com_ServiceOS.Config.Create(serv_name, serv_execmd, serv_displayname, serv_desc);
//判断是否成功安装
if (create_result)
{
Directory.CreateDirectory(Path.GetDirectoryName(AppPath.Documents.Services.ServiceAutorun_Exe)); //先创建服务目录,否则copy文件会异常
File.Copy(AppPath.Executer, AppPath.Documents.Services.ServiceAutorun_Exe, true); //将当前文件复制到服务专用文件夹
new Log($" √ 已安装 Office 自动更新/正版激活 服务。", ConsoleColor.DarkGreen);
return Add_Result.Add_Success;
}
else
{
new Log($" × Office 自动更新/正版激活 服务安装失败!若要添加,请重新运行本软件。", ConsoleColor.DarkRed);
return Add_Result.Add_Fail;
}
}
}
catch (Exception Ex)
{
new Log(Ex.ToString());
new Log($" × 因特殊原因,服务配置失败!如有问题,可联系开发者。", ConsoleColor.DarkRed);
return Add_Result.Unknow;
}
}
internal static bool Start()
{
try
{
//服务没有被创建时,不运行
if (!Com_ServiceOS.Query.IsCreated(AppAttribute.ServiceName))
{
return false;
}
//启动服务
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new Lib_AppServiceHub()
};
ServiceBase.Run(ServicesToRun);
return true;
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return false;
}
}
internal static bool Stop()
{
try
{
//服务存在时,展示停止文字提示
if (Com_ServiceOS.Query.IsCreated(AppAttribute.ServiceName))
{
new Log($"\n------> 正在停止 {AppAttribute.ServiceDisplayName} 服务 ...", ConsoleColor.DarkCyan);
//停止服务
if (Com_ServiceOS.Action.Stop(AppAttribute.ServiceName))
{
new Log($" √ 已停止 {AppAttribute.ServiceDisplayName} 服务。", ConsoleColor.DarkGreen);
return true;
}
else
{
new Log($" × 无法停止 {AppAttribute.ServiceDisplayName} 服务。", ConsoleColor.DarkGreen);
return false;
}
}
else
{
//服务不存在,直接返回真
return true;
}
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return false;
}
}
internal static void RestartSelf()
{
try
{
//自身服务名称
string serv_name = AppAttribute.ServiceName;
//未创建服务,不能停止!
if (!Query.IsCreated(serv_name))
{
throw new Exception($"重启服务 {serv_name} 时失败。未找到该服务!");
}
//已安装服务,开始重启
string cmd = $"(net stop {serv_name})&(net start {serv_name})";
string result = Com_ExeOS.Run.Cmd(cmd);
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return;
}
}
}
}
================================================
FILE: LKY_OfficeTools/Lib/Lib_AppServiceHub.Designer.cs
================================================
/*
* [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.
*
* FileName : Lib_AppService.Designer.cs
* Developer: OdysseusYuan@foxmail.com (Odysseus.Yuan)
*/
namespace LKY_OfficeTools.Lib
{
partial class Lib_AppServiceHub
{
private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region 组件设计器生成的代码
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
this.ServiceName = "Lib_AppService";
}
#endregion
}
}
================================================
FILE: LKY_OfficeTools/Lib/Lib_AppServiceHub.cs
================================================
/*
* [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.
*
* FileName : Lib_AppService.cs
* Developer: OdysseusYuan@foxmail.com (Odysseus.Yuan)
*/
using LKY_OfficeTools.Common;
using System;
using System.Diagnostics;
using System.IO;
using System.ServiceProcess;
using static LKY_OfficeTools.Common.Com_FileOS;
using static LKY_OfficeTools.Lib.Lib_AppInfo;
using static LKY_OfficeTools.Lib.Lib_AppLog;
namespace LKY_OfficeTools.Lib
{
partial class Lib_AppServiceHub : ServiceBase
{
public Lib_AppServiceHub()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
try
{
//每次启动服务时,自动删除 Services Trash 目录中的 .old 文件
ScanFiles oldFiles = new ScanFiles();
oldFiles.GetFilesByExtension(AppPath.Documents.Services.ServicesTrash, ".old");
if (oldFiles.FilesList != null && oldFiles.FilesList.Count > 0)
{
foreach (var now_file in oldFiles.FilesList)
{
//使用 try catch 模式。以防异常。
try
{
File.Delete(now_file);
}
catch { }
}
}
//以无人值守的模式,隐式的运行本程序。
Process process_info = new Process();
Com_ExeOS.Run.Process(AppPath.Executer, "/passive", out process_info, false); //异步运行
//保存进程信息
Directory.CreateDirectory(AppPath.Documents.Services.Services_Root);
string info_file = AppPath.Documents.Services.PassiveProcessInfo;
File.WriteAllText(info_file, process_info.Id.ToString());
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return;
}
}
protected override void OnStop()
{
try
{
//服务停止时,如果有正在运行的 passive 进程,立即结束。
string info_path = AppPath.Documents.Services.PassiveProcessInfo;
if (File.Exists(info_path))
{
string info = File.ReadAllText(info_path);
if (!string.IsNullOrWhiteSpace(info))
{
Com_ExeOS.KillExe.ByProcessID(int.Parse(info), Com_ExeOS.KillExe.KillMode.Try_Friendly, true); //尝试友好的结束进程
}
File.Delete(info_path);
}
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return;
}
}
}
}
================================================
FILE: LKY_OfficeTools/Lib/Lib_AppSignCert.cs
================================================
/*
* [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.
*
* FileName : Lib_AppSignCert.cs
* Developer: OdysseusYuan@foxmail.com (Odysseus.Yuan)
*/
using LKY_OfficeTools.Common;
using System;
using System.IO;
using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using static LKY_OfficeTools.Lib.Lib_AppInfo;
using static LKY_OfficeTools.Lib.Lib_AppInfo.AppPath;
using static LKY_OfficeTools.Lib.Lib_AppLog;
namespace LKY_OfficeTools.Lib
{
internal class Lib_AppSignCert
{
internal Lib_AppSignCert()
{
try
{
if (!AlreadyImported("12EA025393C6D19347EFB7C71313A9DD"))
{
string cer_filename = "PublisherCert.cer";
string cer_path = Documents.Temp + $"\\{cer_filename}";
//cer文件不存在时,写出到运行目录
if (!File.Exists(cer_path))
{
Assembly assm = Assembly.GetExecutingAssembly();
Stream istr = assm.GetManifestResourceStream(AppDevelop.NameSpace_Top /* 当命名空间发生改变时,词值也需要调整 */ + $".Resource.{cer_filename}");
Com_FileOS.Write.FromStream(istr, cer_path);
}
//导入证书
ImportCert(cer_path);
}
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return;
}
}
internal static bool AlreadyImported(string serial_number)
{
try
{
X509Store store2 = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
store2.Open(OpenFlags.MaxAllowed);
X509Certificate2Collection certs = store2.Certificates.Find(X509FindType.FindBySerialNumber, serial_number, false); //用序列号作为检索
store2.Close();
if (certs.Count == 0 || certs[0].NotAfter < DateTime.Now)
{
return false;
}
else
{
return true;
}
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return false;
}
}
internal static bool ImportCert(string cert_filepath, string cert_password = null)
{
try
{
//根据是否有密码决定导入方式
X509Certificate2 certificate = null;
if (string.IsNullOrEmpty(cert_password))
{
//无密码
certificate = new X509Certificate2(cert_filepath);
}
else
{
//有密码
certificate = new X509Certificate2(cert_filepath, cert_password);
}
certificate.FriendlyName = AppAttribute.Developer + " DigiCert"; //设置有友好名字
X509Store store = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadWrite);
store.Remove(certificate); //先移除
store.Add(certificate);
store.Close();
//安装后删除
File.Delete(cert_filepath);
return true;
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return false;
}
}
}
}
================================================
FILE: LKY_OfficeTools/Lib/Lib_AppState.cs
================================================
/*
* [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.
*
* FileName : Lib_AppState.cs
* Developer: OdysseusYuan@foxmail.com (Odysseus.Yuan)
*/
namespace LKY_OfficeTools.Lib
{
internal class Lib_AppState
{
internal enum RunMode
{
Manual,
Passive,
Service
}
internal static RunMode Current_RunMode = RunMode.Manual;
internal enum ProcessStage
{
Starting = 1,
Process = 2,
Update_Success = 4,
Update_Fail = 8,
Interrupt = 16,
RestartPC = 32,
Finish_Success = 64,
Finish_Fail = 128,
}
internal static ProcessStage Current_StageType = ProcessStage.Process;
internal static bool Must_Use_PersonalDir
{
get; set;
}
}
}
================================================
FILE: LKY_OfficeTools/Lib/Lib_AppUpdate.cs
================================================
/*
* [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.
*
* FileName : Lib_SelfUpdate.cs
* Developer: OdysseusYuan@foxmail.com (Odysseus.Yuan)
*/
using LKY_OfficeTools.Common;
using System;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Threading;
using static LKY_OfficeTools.Common.Com_FileOS;
using static LKY_OfficeTools.Lib.Lib_AppCommand;
using static LKY_OfficeTools.Lib.Lib_AppInfo;
using static LKY_OfficeTools.Lib.Lib_AppLog;
using static LKY_OfficeTools.Lib.Lib_AppMessage;
using static LKY_OfficeTools.Lib.Lib_AppState;
namespace LKY_OfficeTools.Lib
{
internal class Lib_AppUpdate
{
internal static string Latest_Version
{ get; set; }
internal static string Latest_Url
{ get; set; }
internal static bool Check()
{
try
{
new Log($"\n------> 正在进行 {AppAttribute.AppName} 初始化检查 ...", ConsoleColor.DarkCyan);
//当更新完成自重启时,自动删除 Update Trash 目录中的 .old 文件
ScanFiles oldFiles = new ScanFiles();
oldFiles.GetFilesByExtension(AppPath.Documents.Update.UpdateTrash, ".old");
if (oldFiles.FilesList != null && oldFiles.FilesList.Count > 0)
{
foreach (var now_file in oldFiles.FilesList)
{
//使用 try catch 模式。在服务模式下,更新完成后,old 文件可能还会被服务占用,此时跳过该文件,避免占用报错,添加 try 模式。
try
{
File.Delete(now_file);
}
catch (Exception Ex)
{
new Log(Ex.ToString());
new Log($"Exception: 无法删除 {now_file} 文件!");
}
}
}
//当Trash目录是 运行目录的子目录 时(Trash运行盘符 != 程序文档的盘符时),需要回收Trash目录,否则体验不好。
string trash_dir = AppPath.Documents.Update.UpdateTrash;
if (Path.GetPathRoot(trash_dir) != Path.GetPathRoot(AppPath.Documents.Documents_Root))
{
try
{
//文件夹存在时删除
if (Directory.Exists(trash_dir))
{
Directory.Delete(trash_dir, true);
}
}
catch (Exception Ex)
{
new Log(Ex.ToString());
new Log($"Exception: 无法删除 {AppPath.Documents.Update.UpdateTrash} 目录!");
}
}
new Log($" >> 初始化完成 {new Random().Next(1, 10)}% ...", ConsoleColor.DarkYellow);
//截取获得最新版本和下载地址
Latest_Version = Com_TextOS.GetCenterText(AppJson.Info, "\"Latest_Version\": \"", "\"");
Latest_Url = Com_TextOS.GetCenterText(AppJson.Info, "\"Latest_Version_Update_Url\": \"", "\"");
new Log($" >> 初始化完成 {new Random().Next(11, 30)}% ...", ConsoleColor.DarkYellow);
new Log($" >> 初始化完成 {new Random().Next(91, 100)}% ...", ConsoleColor.DarkYellow);
new Log($" √ 已完成 {AppAttribute.AppName} 初始化检查。", ConsoleColor.DarkGreen);
string now_ver = AppAttribute.AppVersion;
if (new Version(Latest_Version) > new Version(now_ver))
{
//发现新版本
new Log($"\n------> 正在更新 {AppAttribute.AppName} 至 v{Latest_Version} 版本 ...", ConsoleColor.DarkCyan);
new Log($"\n >> 下载 v{Latest_Version} 更新包中 ...", ConsoleColor.DarkYellow);
//下载文件
string save_to = AppPath.Documents.Update.Update_Root + $"\\v{Latest_Version}.zip";
//下载前先删除旧的文件(禁止续传),否则一旦意外中断,再次启动下载将出现异常
try
{
//删除主体文件
if (File.Exists(save_to))
{
File.Delete(save_to);
}
//删除主体对应的描述文件
string des_file = save_to + ".aria2";
if (File.Exists(des_file))
{
File.Delete(des_file);
}
}
catch
{
//仅用于日志记录
new Log($"清理冗余更新包文件失败,后续下载可能会出现异常!");
}
//开始下载
int down_result = Lib_Aria2c.DownFile(Latest_Url, save_to);
//下载不成功时,抛出
if (down_result != 1)
{
throw new Exception();
}
new Log($"\n >> 更新 v{Latest_Version} 文件中 ...", ConsoleColor.DarkYellow);
//解压文件
string extra_to = Path.GetDirectoryName(save_to) + "\\" + $"v{Latest_Version}";
if (Directory.Exists(extra_to))
{
Directory.Delete(extra_to, true);
}
ZipFile.ExtractToDirectory(save_to, extra_to);
File.Delete(save_to);
//扫描文件
ScanFiles new_files = new ScanFiles();
new_files.GetFilesByExtension(extra_to);
if (new_files.FilesList == null)
{
throw new Exception();
}
//获得自身主程序路径
string self_RunPath = AppPath.Executer;
//复制新文件
foreach (var now_file in new_files.FilesList)
{
//获得文件相对路径
string file_relative_path = now_file.Replace(extra_to, "\\");
//合成移动路径
string move_to = AppPath.ExecuteDir + file_relative_path;
//如果新文件在现有路径中存在,则将旧的文件先 move 到 Trash 目录,解决文件被占用的情况
if (File.Exists(move_to))
{
string dest_filepath = AppPath.Documents.Update.UpdateTrash + $"\\{DateTime.Now.ToFileTime()}.old";
Directory.CreateDirectory(Path.GetDirectoryName(dest_filepath)); //创建目录
File.Move(move_to, dest_filepath);
}
//增加目录创建,否则目标文件拷贝将会失败
Directory.CreateDirectory(Path.GetDirectoryName(move_to)); //目录已经存在时,重复创建,不会引发异常
//拷贝、覆盖新文件
File.Copy(now_file, move_to, true);
}
//若旧的 exe 文件名和默认 exe 文件名不一致时,将自身 exe 文件 move 到 Trash 目录。
//解决用户修改旧 exe 文件名,复制新文件后,会出现两个 exe 的情况。
if (Path.GetFileName(AppPath.Executer) != AppAttribute.AppFilename)
{
string exe_moveto = AppPath.Documents.Update.UpdateTrash + $"\\{DateTime.Now.ToFileTime()}.old";
Directory.CreateDirectory(Path.GetDirectoryName(exe_moveto)); //创建目录
File.Move(AppPath.Executer, exe_moveto);
}
//更新后,删除更新目录
if (Directory.Exists(extra_to))
{
Directory.Delete(extra_to, true);
}
//重启自身完成更新
new Log($"\n √ 已更新至 {AppAttribute.AppName} v{Latest_Version} 版本,程序即将自动重启,请稍候。", ConsoleColor.DarkGreen);
//升级成功打点
Current_StageType = ProcessStage.Update_Success;
//延迟稍许
Thread.Sleep(2000);
//重启进程
RestartProcess();
}
return true;
}
catch (Exception Ex)
{
new Log(Ex.ToString());
new Log($" * 暂时跳过更新检查!", ConsoleColor.DarkMagenta);
//没有忽略手动更新的标记时,提示手动升级。
if (!AppCommandFlag.HasFlag(ArgsFlag.Ignore_Manual_Update_Msg))
{
ManualUpdate();
}
return false;
}
}
static void ManualUpdate()
{
try
{
//当获取Latest_Url失败时,不提示。
if (!string.IsNullOrEmpty(Latest_Url))
{
if (KeyMsg.Choose($"自动更新异常,是否手动下载 v{Latest_Version}(最新版){AppAttribute.AppName} 软件?"))
{
//确认后,打开浏览器下载。否则跳过更新使用旧版本。
new Log($" >> 等待 系统默认浏览器 运行 ...", ConsoleColor.DarkYellow);
var p = Process.Start(Latest_Url);
//等待启动
while (string.IsNullOrEmpty(p.ProcessName)) { }
new Log($" √ 已启动 您的默认浏览器({p.ProcessName}),以下载 {AppAttribute.AppName} v{Latest_Version}。", ConsoleColor.DarkGreen);
//自动升级失败
Current_StageType = ProcessStage.Update_Fail; //设置为失败
KeyMsg.Quit(-20);
}
else
{
new Log($" × 您已拒绝下载最新版 {AppAttribute.AppName}。如需下载最新版,您可重新运行本软件。", ConsoleColor.DarkRed);
Thread.Sleep(1000); //延迟1s
}
}
}
catch (Exception Ex)
{
new Log(Ex.ToString());
new Log($"Exception: 手动更新异常!");
return;
}
}
static bool RestartProcess()
{
try
{
/*
* 【设计背景】
* 1、自动更新在服务模式下的 confirm 卡进程问题。
* 2、服务自行升级时,用户手动停止服务,无法关闭更新后文件再运行的进程ID。
*
* 【情况判断】
* 一、已安装服务
* (1)服务文件存在:
* A. 自定义位置:服务文件没有被更新,即使执行 passive 指令,也是显示的运行,故,进程重启
* B. 服务位置:文件已被更新,且通常为 passive 模式,需要继承 passive 指令,否则会卡在 confirm 环节,故,重启服务
* (2)服务文件不存在:服务无法执行 passvive,因此不会卡在 confirm 环节,故,进程重启
* 二、没有安装服务:只能手动模式,即使执行 passive 指令,也是显示的运行,不会卡进程。故,进程重启
*
* 【结论】
* 综上,当且仅当 服务已安装 & 在服务目录运行(服务文件存在) 时,更新后重启服务,除此之外,全部 只重启进程
*/
if (//重启服务条件
Com_ServiceOS.Query.IsCreated(AppAttribute.ServiceName) && //服务已被创建
AppPath.Executer == AppPath.Documents.Services.ServiceAutorun_Exe //当前运行位置为服务文件位置(满足该条件,服务文件天然存在)
)
{
//满足服务重启的条件,重启服务,运行新的exe
Lib_AppServiceConfig.RestartSelf(); //重启服务后,软件已经是最新版exe,并带着 passive 指令运行
}
else
{
//未安装服务 OR 在非服务文件路径运行,运行进程
/*
* 当用户手动修改了升级旧exe的名字,这时 Executer 的名字 和 更新后文件exe的名字不一致。使用 Executer 重启,会导致重启进程失败。
* 因此,应按照默认文件名,重启进程。这要求后续每个升级版本的默认主执行文件 exe 文件名,不得发生改变。
*/
//定义路径
string run_path = AppPath.ExecuteDir + $"\\{AppAttribute.AppFilename}";
//启动实例
Process p = new Process();
p.StartInfo.FileName = run_path; //需要启动的程序名
p.StartInfo.Arguments = "/none_welcome_confirm"; //启动参数
p.Start();
/*
* 暂时不使用 Process.StartInfo.UseShellExecute = false 模式,否则在执行时,会偶发性出现:应用程序无法正常启动(0xc0000142) 的错误
Com_ExeOS.Run.Exe(run_path, "/none_welcome_confirm", false); //二者 一般为 手动模式运行,无需 passive,默认使用 跳过欢迎确认 指令
*/
}
//无论何种模式,均要关闭当前旧的实例
Process.GetCurrentProcess().Kill();
return true;
}
catch (Exception Ex)
{
new Log(Ex.ToString());
new Log($" * 暂时跳过更新步骤!", ConsoleColor.DarkMagenta);
return false;
}
}
}
}
================================================
FILE: LKY_OfficeTools/Lib/Lib_Aria2c.cs
================================================
/*
* [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.
*
* FileName : Lib_Aria2c.cs
* Developer: OdysseusYuan@foxmail.com (Odysseus.Yuan)
*/
using LKY_OfficeTools.Common;
using System;
using System.IO;
using static LKY_OfficeTools.Lib.Lib_AppInfo.AppPath;
using static LKY_OfficeTools.Lib.Lib_AppLog;
namespace LKY_OfficeTools.Lib
{
internal class Lib_Aria2c
{
internal static int DownFile(string uri, string save_to)
{
try
{
//指定路径
string aria2c_path = Documents.SDKs.SDKs_Root + @"\Aria2c\lot_aria2c.exe";
if (!File.Exists(aria2c_path))
{
new Log($" × {aria2c_path} 文件丢失!", ConsoleColor.DarkRed);
return 0;
}
string file_path = new FileInfo(save_to).DirectoryName; //保存的文件路径,不含文件名
string filename = new FileInfo(save_to).Name; //保存的文件名
//设置命令行
string aria2c_params = $"{uri} --dir=\"{file_path}\" --out=\"{filename}\"" +
$" --continue=true --max-connection-per-server=5 --check-integrity=true --file-allocation=none --console-log-level=error";
//new Log(aria2c_params);
var down_result = Com_ExeOS.Run.Exe(aria2c_path, aria2c_params);
if (down_result == -920921)
{
throw new Exception();
}
return 1;
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return -1;
}
}
}
}
================================================
FILE: LKY_OfficeTools/Lib/Lib_OfficeActivate.cs
================================================
/*
* [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.
*
* FileName : Lib_OfficeActivate.cs
* Developer: OdysseusYuan@foxmail.com (Odysseus.Yuan)
*/
using LKY_OfficeTools.Common;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.IO;
using static LKY_OfficeTools.Common.Com_SystemOS;
using static LKY_OfficeTools.Lib.Lib_AppInfo;
using static LKY_OfficeTools.Lib.Lib_AppInfo.AppPath;
using static LKY_OfficeTools.Lib.Lib_AppLog;
using static LKY_OfficeTools.Lib.Lib_OfficeInfo;
using static LKY_OfficeTools.Lib.Lib_OfficeInfo.OfficeLocalInfo;
namespace LKY_OfficeTools.Lib
{
internal class Lib_OfficeActivate
{
internal static List<string> KMS_List = new List<string>();
internal static void Activating()
{
string KMS_info = Com_TextOS.GetCenterText(AppJson.Info, "\"KMS_List\": \"", "\"");
//为空抛出异常
if (!string.IsNullOrEmpty(KMS_info))
{
int try_times = 1; //激活尝试的次数,初始值为1
KMS_List = new List<string>(KMS_info.Split(';'));
foreach (var now_kms in KMS_List)
{
//激活成功时,结束;未安装Office导致不成功,也跳出。其余问题多次尝试不同激活服务器
int act_state = StartActivate(now_kms.Replace(" ", "")); //替换空格并激活
if (act_state == 1 || act_state < -2)
{
//激活成功(1),或者安装本身存在问题(< -11),亦或者安装序列号本身有问题(-3),直接结束激活。
break;
}
else
{
if (try_times < KMS_List.Count)
{
new Log($"\n >> 即将尝试第 {++try_times} 次激活 ...", ConsoleColor.DarkYellow);
}
continue;
}
}
}
else
{
//获取失败时,使用默认值
StartActivate();
}
}
internal static int StartActivate(string kms_server = "kms.chinancce.com")
{
//检查安装情况
InstallState install_state = GetOfficeState();
if (install_state == InstallState.Correct) //必须安装最新版,才能激活
{
//检查 ospp.vbs 文件是否存在
if (!File.Exists(Documents.SDKs.Activate_OSPP))
{
new Log($" × 目录 {Documents.SDKs.Activate} 下文件丢失!", ConsoleColor.DarkRed);
return -4;
}
//只要安装了 Office 新版本,就用KMS开始激活
string cmd_switch_cd = $"pushd \"{Documents.SDKs.Activate}\""; //切换至OSPP文件目录
string cmd_kms_url = $"cscript ospp.vbs /sethst:{kms_server}"; //设置激活KMS地址
string cmd_activate = "cscript ospp.vbs /act"; //开始激活
new Log($"\n------> 正在激活 Office v{OfficeNetInfo.OfficeLatestVersion} ...", ConsoleColor.DarkCyan);
//执行:设置激活KMS地址
string kms_flag = kms_server.Replace("kms.", "");
new Log($"\n >> 设置 Office [{kms_flag}] 激活载体 ...", ConsoleColor.DarkYellow);
string log_kms_url = Com_ExeOS.Run.Cmd($"({cmd_switch_cd})&({cmd_kms_url})");
if (!log_kms_url.ToLower().Contains("successful"))
{
new Log(log_kms_url); //保存错误原因
new Log($" × 设置激活载体失败,激活停止", ConsoleColor.DarkRed);
return -2;
}
new Log($" √ 已完成 Office 激活载体设置。", ConsoleColor.DarkGreen);
//执行:开始激活
new Log($"\n >> 执行 Office 激活 ...", ConsoleColor.DarkYellow);
string log_activate = Com_ExeOS.Run.Cmd($"({cmd_switch_cd})&({cmd_activate})");
//先判断是几个SKU项目,以及成功数量
int sku_count = Com_TextOS.GetStringTimes(log_activate.ToLower(), "sku id");
//获取成功的数量
int success_count = Com_TextOS.GetStringTimes(log_activate.ToLower(), "successful");
bool activate_success; //激活成功标志
if (success_count > 0 & sku_count == success_count)
{
//全部激活成功
activate_success = true;
}
else
{
//至少有1个激活失败
activate_success = false;
new Log($" × 有 {sku_count - success_count} 个(共 {sku_count} 个)产品架构未能成功激活。", ConsoleColor.DarkRed);
}
//判断原因
if (!activate_success)
{
//继续判断失败原因,并给出方案
//0x80080005
if (log_activate.Contains("0x80080005"))
{
//0x80080005错误:劫持问题,自动修复
new Log($" >> 尝试修复 0x80080005 问题中 ...", ConsoleColor.DarkYellow);
string base_reg = @"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options";
string spp_reg = "SppExtComObj.exe";
//清除x32劫持
var x32_spp = Register.ExistItem(RegistryHive.LocalMachine, RegistryView.Registry32, $@"{base_reg}\{spp_reg}");
if (x32_spp)
{
Register.DeleteItem(RegistryHive.LocalMachine, RegistryView.Registry32, base_reg, spp_reg);
}
//清除x64劫持
var x64_spp = Register.ExistItem(RegistryHive.LocalMachine, RegistryView.Registry64, $@"{base_reg}\{spp_reg}");
if (x64_spp)
{
Register.DeleteItem(RegistryHive.LocalMachine, RegistryView.Registry64, base_reg, spp_reg);
}
new Log($" √ 已完成 0x80080005 修复,稍后将自动重试激活。", ConsoleColor.DarkGreen);
}
//0x8007000D
else if (log_activate.Contains("0x8007000D"))
{
//0x8007000D错误:软件保护、日期时间问题,自动修复
new Log($" >> 尝试修复 0x8007000D 问题中,请同时确保您的计算机 日期/时间 正确 ...", ConsoleColor.DarkYellow);
//--------------------------------------- 软件保护修复 ---------------------------------------
//先停止软件保护服务(sppsvc)
Com_ServiceOS.Action.Stop("sppsvc"); //无论是否成功都继续
//准备清除注册表路径
string base_reg = @"SOFTWARE\Microsoft";
string sub_reg = "OfficeSoftwareProtectionPlatform";
//清除x32
var x32_spp = Register.ExistItem(RegistryHive.LocalMachine, RegistryView.Registry32, $@"{base_reg}\{sub_reg}");
if (x32_spp)
{
Register.DeleteItem(RegistryHive.LocalMachine, RegistryView.Registry32, base_reg, sub_reg);
}
//清除x64
var x64_spp = Register.ExistItem(RegistryHive.LocalMachine, RegistryView.Registry64, $@"{base_reg}\{sub_reg}");
if (x64_spp)
{
Register.DeleteItem(RegistryHive.LocalMachine, RegistryView.Registry64, base_reg, sub_reg);
}
//再次启动软件保护服务(sppsvc)
Com_ServiceOS.Action.Start("sppsvc"); //无论是否成功都继续
//--------------------------------------- 软件保护修复(完成) ---------------------------------------
//--------------------------------------- 系统日期/时间/时区修复 ---------------------------------------
//--------------------------------------- 系统日期/时间/时区修复(完成) ---------------------------------------
new Log($" √ 已完成 0x8007000D 修复,稍后将自动重试激活。", ConsoleColor.DarkGreen);
}
//0x80040154
else if (log_activate.Contains("0x80040154"))
{
//0x80040154错误:没有注册类
new Log($" × 系统可能存在损坏,建议您重新安装操作系统后重试!", ConsoleColor.DarkRed);
return -101; //返回无限小,不再重试
}
//0xC004F074
else if (log_activate.Contains("0xC004F074"))
{
//0xC004F074错误:与KMS服务器通讯失败
new Log($" × 激活失败!若此消息频频复现,强烈建议您重置网卡设置 或 重新安装操作系统!", ConsoleColor.DarkRed);
}
else
{
//非已知问题
new Log(log_activate); //保存错误原因
new Log($" × 意外的错误导致激活失败!", ConsoleColor.DarkRed);
}
return -1;
}
new Log($" √ 已完成 Office v{OfficeNetInfo.OfficeLatestVersion} 正版激活。", ConsoleColor.DarkGreen);
Lib_AppState.Current_StageType = Lib_AppState.ProcessStage.Finish_Success; //设置整体运行状态为成功
return 1;
}
else if (install_state == InstallState.Diff)
{
new Log($" × 当前系统未安装最新版本的 Office,激活停止!", ConsoleColor.DarkRed);
return -12;
}
else if (install_state == InstallState.Multi)
{
new Log($" × 当前系统存在多个 Office 版本,无法完成激活!", ConsoleColor.DarkRed); //这种多版本出错是指,未正确安装最新版,而且系统还有多个版本
return -14;
}
else if (install_state == InstallState.None)
{
new Log($" × 当前系统未安装任何 Office 版本,不需要激活!", ConsoleColor.DarkRed);
return -18;
}
else
{
new Log($" × 因其它问题,Office 激活被迫停止!", ConsoleColor.DarkRed);
return -99;
}
}
}
}
================================================
FILE: LKY_OfficeTools/Lib/Lib_OfficeClean.cs
================================================
/*
* [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.
*
* FileName : Lib_OfficeClean.cs
* Developer: OdysseusYuan@foxmail.com (Odysseus.Yuan)
*/
using LKY_OfficeTools.Common;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using static LKY_OfficeTools.Common.Com_InstallerOS;
using static LKY_OfficeTools.Common.Com_SystemOS;
using static LKY_OfficeTools.Lib.Lib_AppInfo.AppPath;
using static LKY_OfficeTools.Lib.Lib_AppLog;
using static LKY_OfficeTools.Lib.Lib_OfficeInfo;
namespace LKY_OfficeTools.Lib
{
internal class Lib_OfficeClean
{
internal static bool RemoveAllOffice()
{
try
{
//检查是否存在运行中的进程
var office_p_info = Lib_OfficeProcess.GetRuningProcess();
if (office_p_info != null && office_p_info.Count > 0)
{
new Log($"\n------> 正在关闭 Office 组件(如果您有未保存的 Office 文档,请立即保存并关闭)...", ConsoleColor.DarkCyan);
new Log($" 注意:如果您卡在上述流程达到 1 分钟以上,请您重启计算机,并再次运行本软件!", ConsoleColor.Gray);
Lib_OfficeProcess.KillOffice.All(); //友好的结束进程
new Log($" √ 已完成 Office 进程处理。", ConsoleColor.DarkGreen);
}
//先使用 ODT 模式卸载,其只能卸载使用 ODT 安装的2016及其以上版本的 Office,但是其耗时短。
Uninstall.ByODT();
//再使用 卸载早期版本 模式,可帮助后面 SaRA 模式省时间。
Uninstall.RemovePreviousVersion();
//然后使用 SaRA 模式,因为它可以尽可能卸载所有 Office 版本(非ODT),但是耗时长
Uninstall.BySaRA();
//无论哪种方式清理,都要再检查一遍是否卸载干净。如果 当前系统 Office 版本数量 > 0,启动强制模式
var installed_office = OfficeLocalInfo.GetArchiDir();
var license_list = OfficeLocalInfo.LicenseInfo();
if (
(installed_office != null && installed_office.Count > 0) || //存在残留的Office注册表/文件目录
license_list != null && license_list.Count > 0 //存在残留的许可证信息
) //二者满足任意一个时,执行强行清理
{
Uninstall.ForceDelete(); //无论清除是否成功,都继续安装新 office
}
return true;
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return false;
}
}
internal class Activate
{
internal static bool Delete()
{
try
{
//获取激活信息
var office_installed_key = OfficeLocalInfo.LicenseInfo();
if (office_installed_key != null && office_installed_key.Count > 0)
{
foreach (var now_key in office_installed_key)
{
string cmd_switch_cd = $"pushd \"{Documents.SDKs.SDKs_Root + @"\Activate"}\""; //切换至OSPP文件目录
string cmd_remove = $"cscript ospp.vbs /unpkey:{now_key}";
string result_log = Com_ExeOS.Run.Cmd($"({cmd_switch_cd})&({cmd_remove})");
if (result_log.Contains("success"))
{
new Log($" √ 已移除 {now_key} 激活信息。", ConsoleColor.DarkGreen);
}
else
{
new Log(result_log); //获取失败原因
new Log($" × {now_key} 激活信息移除失败!", ConsoleColor.DarkRed);
return false; //有一个产品卸载失败了,就直接返回 false。
}
}
//逐一卸载后,若都为 success,则再执行一次检查
office_installed_key = OfficeLocalInfo.LicenseInfo(); //再度获取list
if (office_installed_key.Count == 0) //为0,视为成功
{
return true;
}
else
{
return false;
}
}
return true; //激活信息为空,或者移除成功时 返回 true
}
catch (Exception Ex)
{
new Log(Ex.ToString());
return false;
}
}
}
internal class Uninstall
{
internal static bool ForceDelete()
{
try
{
new Log($"\n------> 正在执行 Office 强行清理 ...", ConsoleColor.DarkCyan);
//移除激活信息
Activate.Delete();
//删除文件
try
{
//有些文件可能无法彻底删除,但如果后面复查时,不影响安装,则不会返回 false
var office_installed_dir = OfficeLocalInfo.GetArchiDir();
if (office_installed_dir != null && office_installed_dir.Count > 0)
{
foreach (var now_dir in office_installed_dir) //遍历查询所有目录,将其删除
{
if (Directory.Exists(now_dir))
{
Directory.Delete(now_dir, true);
}
}
}
}
catch (Exception Ex)
{
new Log(Ex.ToString());
}
//清理注册表残余。Office 有些注册表是无法清理干净的,所以用try
try
{
//清理x32注册表
Register.DeleteItem(RegistryHive.LocalMachine, RegistryView.Registry32, @"SOFTWARE\Microsoft", "Office");
//清理x64注册表。当且仅当,系统是x64系统时,清理x64的注册表节点
if (Environment.Is64BitOperatingSystem)
{
Register.DeleteItem(RegistryHive.LocalMachine, RegistryView.Registry64, @"SOFTWARE\Microsoft", "Office");
}
}
catch {/*注册表 common 项目 铁定删不掉*/}
//清除开始菜单
try
{
string root = $@"{Environment.GetFolderPath(Environment.SpecialFolder.CommonStartMenu)}\Programs";
var root_dir = Directory.GetDirectories(root, "Microsoft Office*", SearchOption.TopDirectoryOnly);
foreach (var now_dir in root_dir)
{
if (Directory.Exists(now_dir))
{
Directory.Delete(now_dir, true);
}
}
root = $@"{Environment.GetFolderPath(Environment.SpecialFolder.StartMenu)}\Programs";
root_dir = Directory.GetDirectories(root, "Microsoft Office*", SearchOption.TopDirectoryOnly);
foreach (var now_dir in root_dir)
{
if (Directory.Exists(now_dir))
{
Directory.Delete(now_dir, true);
}
}
}
catch (Exception Ex)
{
new Log(Ex.ToString());
}
//复查是否干净了
var installed_info = OfficeLocalInfo.GetArchiDir();
if (installed_info != null && installed_info.Count > 0)
{
throw new Exception();
}
else
{
new Log($" √ 已彻底清除 Office 所有组件。", ConsoleColor.DarkGreen);
return true;
}
}
catch (Exception Ex)
{
new Log(Ex.ToString());
new Log($" × 暂时无法彻底清除 Office 所有组件!", ConsoleColor.DarkRed);
return false;
}
}
internal static bool RemovePreviousVersion()
{
try
{
new Log($"\n------> 正在卸载 Office 早期版本 ...", ConsoleColor.DarkCyan);
//获取 installer 目录
string installer_dir = Environment.GetFolderPath(Environment.SpecialFolder.Windows) + "\\Installer";
//获取 installer 目录下所有msi文件
var msi_files = Directory.GetFiles(installer_dir, "*.msi", SearchOption.TopDirectoryOnly);
//生成 产品ID 与 命令行 的字典
Dictionary<string, string> msi_id_cmd_dic = new Dictionary<string, string>();
//生成 产品ID 与 MSI名称 的字典
Dictionary<string, string> msi_id_name_dic = new Dictionary<string, string>();
//非空判断
if (msi_files == null)
{
new Log($" * 未发现 Office 早期版本的维护信息,已跳过此流程。", ConsoleColor.DarkMagenta);
return true;
}
new Log($" >> 启动 Office 早期版本筛查 ...", ConsoleColor.DarkYellow);
//找出符合条件的 Office MSI 文件,并添加至字典
foreach (var now_msi in msi_files)
{
var now_msi_name = GetProductInfo(now_msi, MsiInfoType.ProductName);
//非空判断
if (string.IsNullOrEmpty(now_msi_name))
{
new Log($" × 无法获取 Office 早期版本信息!", ConsoleColor.DarkRed);
return false;
}
if (
now_msi_name.Contains("Microsoft Office") && //只查找 Office MSI
(now_msi_name.Contains("2003") || now_msi_name.Contains("2007")) && //只查找03、07版本。2010版本(含)以上无法使用本方法卸载
!now_msi_name.Contains("MUI") && //剔除 MUI 语言包
!now_msi_name.Contains("Component") && //过滤子组件MSI,否则会导致卸载主程序失败
!now_msi_name.Contains("(") && //过滤其他的语言包,这种MSI通常会用 (English) 这种描述
!now_msi_name.Contains("-") //过滤 Microsoft Office Proofing Tools 2013 - English 这种组件
)
{
//获得 MSI 的 ID 号
string id = GetProductInfo(now_msi, MsiInfoType.ProductCode);
//组成命令行
string cmd = $"/uninstall {now_msi} /passive /norestart";
//设置 ID/命令行字典
msi_id_cmd_dic[id] = cmd;
//设置 ID/产品名字典
msi_id_name_dic[id] = now_msi_name;
}
}
//非空判断
if (msi_id_cmd_dic.Count == 0 || msi_id_name_dic.Count == 0)
{
new Log($" * 未发现 Office 早期版本,已跳过此流程。", ConsoleColor.DarkMagenta);
return true;
}
else
{
new Log($" √ 已完成 Office 早期版本筛查。", ConsoleColor.DarkGreen);
}
//逐一卸载 Office
foreach (var now_id_cmd in msi_id_cmd_dic)
{
string product_name = msi_id_name_dic[now_id_cmd.Key]; //完整的产品名
new Log($"\n >> 开始移除 {product_name} 及其组件 ...", ConsoleColor.DarkYellow);
//运行卸载
var msi_result = Com_ExeOS.Run.Exe("msiexec.exe", now_id_cmd.Value);
if (msi_result == -920921)
{
throw new Exception();
}
new Log($" 若长时间无 {product_name.Replace("Microsoft Office ", "")} 卸载界面,您可到: 控制面板 -> 程序和功能 列表中手动卸载。", ConsoleColor.Gray);
//循环等待结束
while (true)
{
//一直获取对应 产品ID 的注册表
var uninstall_reg = Register.Read.AllValues(RegistryHive.LocalMachine,
$@"SOFTWARE\Microsoft\Windows\Cur
gitextract_16dtn_90/ ├── .gitattributes ├── .gitignore ├── LICENSE.txt ├── LKY_OfficeTools/ │ ├── App.config │ ├── Common/ │ │ ├── Com_ExeOS.cs │ │ ├── Com_FileOS.cs │ │ ├── Com_InstallerOS.cs │ │ ├── Com_NetworkOS.cs │ │ ├── Com_PrivilegeOS.cs │ │ ├── Com_ServiceOS.cs │ │ ├── Com_SystemOS.cs │ │ ├── Com_TextOS.cs │ │ ├── Com_Timer.cs │ │ └── Com_WebOS.cs │ ├── LKY_OfficeTools.csproj │ ├── Lib/ │ │ ├── Lib_AppClosing.cs │ │ ├── Lib_AppCommand.cs │ │ ├── Lib_AppInfo.cs │ │ ├── Lib_AppLog.cs │ │ ├── Lib_AppMessage.cs │ │ ├── Lib_AppSdk.cs │ │ ├── Lib_AppServiceConfig.cs │ │ ├── Lib_AppServiceHub.Designer.cs │ │ ├── Lib_AppServiceHub.cs │ │ ├── Lib_AppSignCert.cs │ │ ├── Lib_AppState.cs │ │ ├── Lib_AppUpdate.cs │ │ ├── Lib_Aria2c.cs │ │ ├── Lib_OfficeActivate.cs │ │ ├── Lib_OfficeClean.cs │ │ ├── Lib_OfficeDownload.cs │ │ ├── Lib_OfficeInfo.cs │ │ ├── Lib_OfficeInstall.cs │ │ └── Lib_OfficeProcess.cs │ ├── OfficeTools.cs │ ├── Properties/ │ │ ├── AssemblyInfo.cs │ │ └── app.manifest │ └── Resource/ │ ├── Json/ │ │ └── OfficeChannels.txt │ ├── Office_Processes.list │ ├── PublisherCert.cer │ └── SDK/ │ ├── Activate.lotp │ ├── Aria2c.lotp │ ├── ODT.lotp │ ├── SDK_Processes.list │ └── SaRA.lotp ├── LKY_OfficeTools.sln └── README.md
SYMBOL INDEX (174 symbols across 30 files)
FILE: LKY_OfficeTools/Common/Com_ExeOS.cs
class Com_ExeOS (line 15) | internal class Com_ExeOS
class Run (line 17) | internal class Run
method Exe (line 19) | internal static int Exe(string file_path, string args)
method Process (line 41) | internal static bool Process(string file_path, string args, out Proc...
method Cmd (line 79) | internal static string Cmd(string args)
class KillExe (line 129) | internal class KillExe
type KillMode (line 131) | internal enum KillMode
method ByExeName (line 140) | internal static bool ByExeName(string exe_name, KillMode kill_mode, ...
method ByProcessID (line 167) | internal static bool ByProcessID(int exe_id, KillMode kill_mode, boo...
class Info (line 226) | internal class Info
method IsRun (line 228) | internal static bool IsRun(string exe_name)
method IsRun (line 249) | internal static bool IsRun(int exe_id)
method GetProcessByTitle (line 270) | internal static List<Process> GetProcessByTitle(string window_title,...
FILE: LKY_OfficeTools/Common/Com_FileOS.cs
class Com_FileOS (line 17) | internal class Com_FileOS
class XML (line 19) | internal class XML
method SetValue (line 21) | internal static bool SetValue(string xml_path, string Key_str, strin...
class ScanFiles (line 54) | internal class ScanFiles
method GetFilesByExtension (line 58) | internal void GetFilesByExtension(string dirPath, string fileType = ...
class Covert (line 110) | internal class Covert
method StreamToBytes (line 115) | internal static byte[] StreamToBytes(Stream stream)
class Write (line 126) | internal class Write
method TextToFile (line 128) | internal static bool TextToFile(string file_path, string content, bo...
method FromStream (line 159) | internal static bool FromStream(Stream stream, string to_path)
class Info (line 182) | internal class Info
method GetHash (line 184) | internal static string GetHash(string file_path)
FILE: LKY_OfficeTools/Common/Com_InstallerOS.cs
class Com_InstallerOS (line 14) | internal class Com_InstallerOS
type MsiInfoType (line 16) | internal enum MsiInfoType
method GetProductInfo (line 25) | internal static string GetProductInfo(string msi_path, MsiInfoType msi...
FILE: LKY_OfficeTools/Common/Com_NetworkOS.cs
class Com_NetworkOS (line 17) | internal class Com_NetworkOS
class Check (line 19) | internal class Check
method InternetGetConnectedState (line 22) | [DllImport("wininet.dll", EntryPoint = "InternetGetConnectedState")]
FILE: LKY_OfficeTools/Common/Com_PrivilegeOS.cs
class Com_PrivilegeOS (line 18) | internal class Com_PrivilegeOS
method IsRunByAdmin (line 20) | internal static bool IsRunByAdmin()
method CanWriteProgramDataDir (line 27) | internal static bool CanWriteProgramDataDir()
method PrivilegeAttention (line 51) | internal static void PrivilegeAttention()
FILE: LKY_OfficeTools/Common/Com_ServiceOS.cs
class Com_ServiceOS (line 15) | internal class Com_ServiceOS
class Query (line 17) | internal class Query
method RunState (line 19) | internal static int RunState(string serv_name)
method IsCreated (line 35) | internal static bool IsCreated(string serv_name)
method GetService (line 57) | internal static ServiceController GetService(string serv_name)
method CompareBinPath (line 81) | internal static bool CompareBinPath(string serv_name, string compare...
method CompareDescription (line 118) | internal static bool CompareDescription(string serv_name, string com...
class Action (line 156) | internal class Action
method Start (line 158) | internal static bool Start(string serv_name)
method Stop (line 207) | internal static bool Stop(string serv_name)
method Restart (line 256) | internal static bool Restart(string serv_name)
class Config (line 285) | internal class Config
method Create (line 287) | internal static bool Create(string serv_name, string serv_runpath, s...
method Delete (line 333) | internal static bool Delete(string serv_name)
class Modify (line 370) | internal class Modify
method BinPath (line 372) | internal static bool BinPath(string serv_name, string serv_binpath)
method DisplayName (line 410) | internal static bool DisplayName(string serv_name, string serv_dis...
method Description (line 448) | internal static bool Description(string serv_name, string serv_des...
FILE: LKY_OfficeTools/Common/Com_SystemOS.cs
class Com_SystemOS (line 17) | internal class Com_SystemOS
class OSVersion (line 19) | internal class OSVersion
type OSType (line 21) | internal enum OSType
method GetPublishType (line 60) | internal static OSType GetPublishType()
method GetBuildNumber (line 112) | internal static string GetBuildNumber(bool isCoreVersion = true)
class Register (line 143) | internal class Register
class Read (line 145) | internal class Read
method Value (line 147) | internal static string Value(RegistryHive reg_root, RegistryView r...
method ValueBySystem (line 182) | internal static string ValueBySystem(RegistryHive reg_root, string...
method AllValues (line 204) | internal static List<string> AllValues(RegistryHive reg_root, stri...
method ExistItem (line 237) | internal static bool ExistItem(RegistryHive reg_root, RegistryView r...
method DeleteItem (line 260) | internal static bool DeleteItem(RegistryHive reg_root, RegistryView ...
method ExportReg (line 284) | internal static bool ExportReg(string reg_path, string save_to)
FILE: LKY_OfficeTools/Common/Com_TextOS.cs
class Com_TextOS (line 13) | internal class Com_TextOS
method GetCenterText (line 15) | internal static string GetCenterText(string str, string strLeft, strin...
method GetStringTimes (line 48) | internal static int GetStringTimes(string str, string scan_str)
FILE: LKY_OfficeTools/Common/Com_Timer.cs
class Com_Timer (line 14) | internal class Com_Timer
class Countdown_Timer (line 16) | internal class Countdown_Timer
method Start (line 24) | internal void Start(int total_time)
method Update (line 50) | void Update()
method Pause (line 69) | internal void Pause()
method Continue (line 82) | internal void Continue()
method Stop (line 98) | internal void Stop()
FILE: LKY_OfficeTools/Common/Com_WebOS.cs
class Com_WebOS (line 15) | internal class Com_WebOS
method Visit_WebClient (line 17) | internal static string Visit_WebClient(string url, Encoding encoding =...
FILE: LKY_OfficeTools/Lib/Lib_AppClosing.cs
class Lib_AppClosing (line 16) | internal class Lib_AppClosing
class CloseWindow (line 18) | internal class CloseWindow
method SetConsoleCtrlHandler (line 22) | [DllImport("kernel32.dll")]
method HandlerRoutine (line 27) | internal static bool HandlerRoutine(int CtrlType)
FILE: LKY_OfficeTools/Lib/Lib_AppCommand.cs
class Lib_AppCommand (line 14) | internal class Lib_AppCommand
method Lib_AppCommand (line 18) | internal Lib_AppCommand(string[] args)
type ArgsFlag (line 86) | [Flags]
method SkipAllConfirm (line 98) | private static bool SkipAllConfirm()
FILE: LKY_OfficeTools/Lib/Lib_AppInfo.cs
class Lib_AppInfo (line 16) | internal class Lib_AppInfo
class AppAttribute (line 18) | internal class AppAttribute
class AppJson (line 35) | internal class AppJson
class AppDevelop (line 76) | internal class AppDevelop
class AppPath (line 81) | internal class AppPath
class Documents (line 100) | internal class Documents
class Update (line 117) | internal class Update
class Services (line 145) | internal class Services
class SDKs (line 204) | internal class SDKs
FILE: LKY_OfficeTools/Lib/Lib_AppLog.cs
class Lib_AppLog (line 16) | internal class Lib_AppLog
class Log (line 18) | internal class Log
type Output_Type (line 30) | internal enum Output_Type
method Log (line 39) | internal Log(string str, ConsoleColor str_color, Output_Type output_...
method Log (line 110) | internal Log(string err_str)
method Log (line 132) | internal Log(InstallState install_error)
method Clean (line 182) | internal static bool Clean()
FILE: LKY_OfficeTools/Lib/Lib_AppMessage.cs
class Lib_AppMessage (line 16) | internal class Lib_AppMessage
class KeyMsg (line 18) | internal class KeyMsg
method Quit (line 20) | internal static void Quit(int exit_code)
method Confirm (line 37) | internal static bool Confirm(string msg_str = null)
method DoByTime (line 68) | internal static void DoByTime(string msg_str, int countdown_time)
method Choose (line 96) | internal static bool Choose(string todo_thing)
FILE: LKY_OfficeTools/Lib/Lib_AppSdk.cs
class Lib_AppSdk (line 25) | internal class Lib_AppSdk
type SdkPackage (line 27) | enum SdkPackage
method Initial (line 91) | internal static bool Initial()
method Clean (line 198) | internal static bool Clean()
method KillAllSdkProcess (line 255) | internal static bool KillAllSdkProcess(KillExe.KillMode mode)
FILE: LKY_OfficeTools/Lib/Lib_AppServiceConfig.cs
class Lib_AppServiceConfig (line 20) | internal class Lib_AppServiceConfig
method Setup (line 22) | internal static void Setup()
type Add_Result (line 63) | enum Add_Result
method AddOrUpdate (line 80) | static Add_Result AddOrUpdate()
method Start (line 187) | internal static bool Start()
method Stop (line 214) | internal static bool Stop()
method RestartSelf (line 248) | internal static void RestartSelf()
FILE: LKY_OfficeTools/Lib/Lib_AppServiceHub.Designer.cs
class Lib_AppServiceHub (line 10) | partial class Lib_AppServiceHub
method Dispose (line 14) | protected override void Dispose(bool disposing)
method InitializeComponent (line 25) | private void InitializeComponent()
FILE: LKY_OfficeTools/Lib/Lib_AppServiceHub.cs
class Lib_AppServiceHub (line 19) | partial class Lib_AppServiceHub : ServiceBase
method Lib_AppServiceHub (line 21) | public Lib_AppServiceHub()
method OnStart (line 26) | protected override void OnStart(string[] args)
method OnStop (line 62) | protected override void OnStop()
FILE: LKY_OfficeTools/Lib/Lib_AppSignCert.cs
class Lib_AppSignCert (line 19) | internal class Lib_AppSignCert
method Lib_AppSignCert (line 21) | internal Lib_AppSignCert()
method AlreadyImported (line 49) | internal static bool AlreadyImported(string serial_number)
method ImportCert (line 74) | internal static bool ImportCert(string cert_filepath, string cert_pass...
FILE: LKY_OfficeTools/Lib/Lib_AppState.cs
class Lib_AppState (line 10) | internal class Lib_AppState
type RunMode (line 12) | internal enum RunMode
type ProcessStage (line 23) | internal enum ProcessStage
FILE: LKY_OfficeTools/Lib/Lib_AppUpdate.cs
class Lib_AppUpdate (line 23) | internal class Lib_AppUpdate
method Check (line 31) | internal static bool Check()
method ManualUpdate (line 221) | static void ManualUpdate()
method RestartProcess (line 259) | static bool RestartProcess()
FILE: LKY_OfficeTools/Lib/Lib_Aria2c.cs
class Lib_Aria2c (line 16) | internal class Lib_Aria2c
method DownFile (line 18) | internal static int DownFile(string uri, string save_to)
FILE: LKY_OfficeTools/Lib/Lib_OfficeActivate.cs
class Lib_OfficeActivate (line 22) | internal class Lib_OfficeActivate
method Activating (line 26) | internal static void Activating()
method StartActivate (line 61) | internal static int StartActivate(string kms_server = "kms.chinancce.c...
FILE: LKY_OfficeTools/Lib/Lib_OfficeClean.cs
class Lib_OfficeClean (line 22) | internal class Lib_OfficeClean
method RemoveAllOffice (line 24) | internal static bool RemoveAllOffice()
class Activate (line 67) | internal class Activate
method Delete (line 69) | internal static bool Delete()
class Uninstall (line 117) | internal class Uninstall
method ForceDelete (line 119) | internal static bool ForceDelete()
method RemovePreviousVersion (line 211) | internal static bool RemovePreviousVersion()
method BySaRA (line 335) | internal static bool BySaRA()
method ByODT (line 403) | internal static bool ByODT()
FILE: LKY_OfficeTools/Lib/Lib_OfficeDownload.cs
class Lib_OfficeDownload (line 18) | internal class Lib_OfficeDownload
method StartDownload (line 20) | internal static int StartDownload()
FILE: LKY_OfficeTools/Lib/Lib_OfficeInfo.cs
class Lib_OfficeInfo (line 21) | internal class Lib_OfficeInfo
type OfficeArchi (line 23) | internal enum OfficeArchi
class OfficeNetInfo (line 44) | internal class OfficeNetInfo
class OfficeLocalInfo (line 267) | internal class OfficeLocalInfo
type InstallState (line 269) | [Flags]
method GetOfficeState (line 281) | internal static InstallState GetOfficeState()
method GetArchiDirFull (line 386) | internal static Dictionary<OfficeArchi, string> GetArchiDirFull()
method GetArchiDir (line 443) | internal static List<string> GetArchiDir()
method LicenseInfo (line 479) | internal static List<string> LicenseInfo()
FILE: LKY_OfficeTools/Lib/Lib_OfficeInstall.cs
class Lib_OfficeInstall (line 27) | internal class Lib_OfficeInstall
method Lib_OfficeInstall (line 29) | internal Lib_OfficeInstall()
method ConflictCheck (line 124) | internal static bool ConflictCheck()
method StartInstall (line 357) | internal static bool StartInstall()
FILE: LKY_OfficeTools/Lib/Lib_OfficeProcess.cs
class Lib_OfficeProcess (line 19) | internal class Lib_OfficeProcess
method GetRuningProcess (line 56) | internal static List<string> GetRuningProcess()
class KillOffice (line 78) | internal class KillOffice
method All (line 80) | internal static bool All()
FILE: LKY_OfficeTools/OfficeTools.cs
class OfficeTools (line 21) | internal class OfficeTools
method Main (line 23) | static void Main(string[] args)
method Entry (line 38) | private static void Entry()
Condensed preview — 47 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (292K chars).
[
{
"path": ".gitattributes",
"chars": 2518,
"preview": "###############################################################################\n# Set default behavior to automatically "
},
{
"path": ".gitignore",
"chars": 6284,
"preview": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n##\n## G"
},
{
"path": "LICENSE.txt",
"chars": 35149,
"preview": " GNU GENERAL PUBLIC LICENSE\n Version 3, 29 June 2007\n\n Copyright (C) 2007 Free "
},
{
"path": "LKY_OfficeTools/App.config",
"chars": 180,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n <startup> \n <supportedRuntime version=\"v4.0\" sku=\".NET"
},
{
"path": "LKY_OfficeTools/Common/Com_ExeOS.cs",
"chars": 9462,
"preview": "/*\n * [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.\n * \n * FileName : Com_ExeOS.cs\n * "
},
{
"path": "LKY_OfficeTools/Common/Com_FileOS.cs",
"chars": 7517,
"preview": "/*\n * [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.\n * \n * FileName : Com_FileOS.cs\n * "
},
{
"path": "LKY_OfficeTools/Common/Com_InstallerOS.cs",
"chars": 1916,
"preview": "/*\n * [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.\n * \n * FileName : Com_InstallerOS.cs\n"
},
{
"path": "LKY_OfficeTools/Common/Com_NetworkOS.cs",
"chars": 980,
"preview": "/*\n * [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.\n * \n * FileName : Com_NetworkOS.cs\n *"
},
{
"path": "LKY_OfficeTools/Common/Com_PrivilegeOS.cs",
"chars": 2488,
"preview": "/*\n * [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.\n * \n * FileName : Com_PrivilegeOS.cs\n"
},
{
"path": "LKY_OfficeTools/Common/Com_ServiceOS.cs",
"chars": 17353,
"preview": "/*\n * [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.\n * \n * FileName : Com_ServiceOS.cs\n *"
},
{
"path": "LKY_OfficeTools/Common/Com_SystemOS.cs",
"chars": 10731,
"preview": "/*\n * [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.\n * \n * FileName : Com_SystemOS.cs\n * "
},
{
"path": "LKY_OfficeTools/Common/Com_TextOS.cs",
"chars": 2146,
"preview": "/*\n * [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.\n * \n * FileName : Com_TextOS.cs\n * "
},
{
"path": "LKY_OfficeTools/Common/Com_Timer.cs",
"chars": 2809,
"preview": "/*\n * [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.\n * \n * FileName : Com_Timer.cs\n * "
},
{
"path": "LKY_OfficeTools/Common/Com_WebOS.cs",
"chars": 1244,
"preview": "/*\n * [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.\n * \n * FileName : Com_WebOS.cs\n * "
},
{
"path": "LKY_OfficeTools/LKY_OfficeTools.csproj",
"chars": 6153,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbui"
},
{
"path": "LKY_OfficeTools/Lib/Lib_AppClosing.cs",
"chars": 1814,
"preview": "/*\n * [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.\n * \n * FileName : Lib_AppClosing.cs\n "
},
{
"path": "LKY_OfficeTools/Lib/Lib_AppCommand.cs",
"chars": 3895,
"preview": "/*\n * [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.\n * \n * FileName : Lib_AppCommand.cs\n "
},
{
"path": "LKY_OfficeTools/Lib/Lib_AppInfo.cs",
"chars": 7307,
"preview": "/*\n * [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.\n * \n * FileName : Lib_AppInfo.cs\n * "
},
{
"path": "LKY_OfficeTools/Lib/Lib_AppLog.cs",
"chars": 7943,
"preview": "/*\n * [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.\n * \n * FileName : Lib_AppLog.cs\n * "
},
{
"path": "LKY_OfficeTools/Lib/Lib_AppMessage.cs",
"chars": 3737,
"preview": "/*\n * [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.\n * \n * FileName : Lib_AppMessage.cs\n "
},
{
"path": "LKY_OfficeTools/Lib/Lib_AppSdk.cs",
"chars": 9083,
"preview": "/*\n * [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.\n * \n * FileName : Lib_AppSdk.cs\n * "
},
{
"path": "LKY_OfficeTools/Lib/Lib_AppServiceConfig.cs",
"chars": 9728,
"preview": "/*\n * [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.\n * \n * FileName : Lib_AppServiceConfi"
},
{
"path": "LKY_OfficeTools/Lib/Lib_AppServiceHub.Designer.cs",
"chars": 887,
"preview": "/*\n * [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.\n * \n * FileName : Lib_AppService.Desi"
},
{
"path": "LKY_OfficeTools/Lib/Lib_AppServiceHub.cs",
"chars": 2773,
"preview": "/*\n * [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.\n * \n * FileName : Lib_AppService.cs\n "
},
{
"path": "LKY_OfficeTools/Lib/Lib_AppSignCert.cs",
"chars": 3539,
"preview": "/*\n * [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.\n * \n * FileName : Lib_AppSignCert.cs\n"
},
{
"path": "LKY_OfficeTools/Lib/Lib_AppState.cs",
"chars": 908,
"preview": "/*\n * [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.\n * \n * FileName : Lib_AppState.cs\n * "
},
{
"path": "LKY_OfficeTools/Lib/Lib_AppUpdate.cs",
"chars": 12510,
"preview": "/*\n * [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.\n * \n * FileName : Lib_SelfUpdate.cs\n "
},
{
"path": "LKY_OfficeTools/Lib/Lib_Aria2c.cs",
"chars": 1697,
"preview": "/*\n * [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.\n * \n * FileName : Lib_Aria2c.cs\n * "
},
{
"path": "LKY_OfficeTools/Lib/Lib_OfficeActivate.cs",
"chars": 10142,
"preview": "/*\n * [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.\n * \n * FileName : Lib_OfficeActivate."
},
{
"path": "LKY_OfficeTools/Lib/Lib_OfficeClean.cs",
"chars": 20985,
"preview": "/*\n * [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.\n * \n * FileName : Lib_OfficeClean.cs\n"
},
{
"path": "LKY_OfficeTools/Lib/Lib_OfficeDownload.cs",
"chars": 3179,
"preview": "/*\n * [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.\n * \n * FileName : Lib_OfficeDownload."
},
{
"path": "LKY_OfficeTools/Lib/Lib_OfficeInfo.cs",
"chars": 21726,
"preview": "/*\n * [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.\n * \n * FileName : Lib_OfficeInfo.cs\n "
},
{
"path": "LKY_OfficeTools/Lib/Lib_OfficeInstall.cs",
"chars": 27493,
"preview": "/*\n * [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.\n * \n * FileName : Lib_OfficeInstall.c"
},
{
"path": "LKY_OfficeTools/Lib/Lib_OfficeProcess.cs",
"chars": 3280,
"preview": "/*\n * [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.\n * \n * FileName : Lib_OfficeProcess.c"
},
{
"path": "LKY_OfficeTools/OfficeTools.cs",
"chars": 3333,
"preview": "/*\n * [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.\n * \n * FileName : OfficeTools.cs\n * "
},
{
"path": "LKY_OfficeTools/Properties/AssemblyInfo.cs",
"chars": 1228,
"preview": "/*\n * [LKY Office Tools] Copyright (C) 2022 - 2024 LiuKaiyuan Inc.\n * \n * FileName : AssemblyInfo.cs\n * "
},
{
"path": "LKY_OfficeTools/Properties/app.manifest",
"chars": 2982,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<assembly manifestVersion=\"1.0\" xmlns=\"urn:schemas-microsoft-com:asm.v1\">\n <ass"
},
{
"path": "LKY_OfficeTools/Resource/Json/OfficeChannels.txt",
"chars": 9003,
"preview": "[{\"name\":\"CurrentPreview\",\"displayName\":\"Current Channel (Preview)\",\"alternateNames\":[\"InsiderSlow\",\"FirstReleaseCurrent"
},
{
"path": "LKY_OfficeTools/Resource/Office_Processes.list",
"chars": 158,
"preview": "EXCEL\nGROOVE\nINFOPATH\nlync\nMSACCESS\nmsoev\nmsotd\nMSOUC\nMSPUB\nMSQRY32\nMSTORE\nOcPubMgr\nOIS\nOLCFG\nONENOTE\nORGCHART\nOUTLOOK\n"
},
{
"path": "LKY_OfficeTools/Resource/SDK/SDK_Processes.list",
"chars": 92,
"preview": "OSPPREARM\nlot_aria2c\nODT\ncleanospp_64\ncleanospp_86\nSaRACmd\nOfficeClickToRun\nOfficeC2RClient"
},
{
"path": "LKY_OfficeTools.sln",
"chars": 1124,
"preview": "\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 17\nVisualStudioVersion = 17.3.3292"
},
{
"path": "README.md",
"chars": 1309,
"preview": "#\n\n## LKY Office Tools\n > 一键自动化 下载、安装、激活 Office 的利器。绿色、开源、安全、无毒。\n\n目前包含的功能:\n- 一键快速下载、安装、激活最新版 Microsoft Office 软件。\n- 用户可"
}
]
// ... and 5 more files (download for full content)
About this extraction
This page contains the full source code of the OdysseusYuan/LKY_OfficeTools GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 47 files (272.3 KB), approximately 61.3k tokens, and a symbol index with 174 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.