C# .net framework不使用命令行或第三方库实现服务安装、卸载、停用,启用

网上资料通常都通过命令行调用sc.exe进行,这里介绍一种通过微软提供API实现的方法。代码更加简单,可控性更好。

使用方法

static void Main(string[] args)
{
    if (args.Length == 0) {
        // Run your service normally.
        ServiceBase[] ServicesToRun = new ServiceBase[] {new YourService()};
        ServiceBase.Run(ServicesToRun);
    } else if (args.Length == 1) {
        switch (args[0]) {
            case "-install":
                InstallService();
                StartService();
                break;
            case "-uninstall":
                StopService();
                UninstallService();
                break;
            default:
                throw new NotImplementedException();
        }
    }
}

ServiceControl 类

 public class ServiceControl
    {
        const string ServiceName = "MyService";

        public static bool IsInstalled()
        {
            using (ServiceController controller =
                new ServiceController(ServiceName))
            {
                try
                {
                    ServiceControllerStatus status = controller.Status;
                }
                catch
                {
                    return false;
                }
                return true;
            }
        }

        public static bool IsRunning()
        {
            using (ServiceController controller =
                new ServiceController(ServiceName))
            {
                if (!IsInstalled()) return false;
                return (controller.Status == ServiceControllerStatus.Running);
            }
        }

        public static AssemblyInstaller GetInstaller()
        {
            AssemblyInstaller installer = new AssemblyInstaller(
                typeof(MyService).Assembly, null);
            installer.UseNewContext = true;
            return installer;
        }

        public static void InstallService()
        {
            if (IsInstalled()) return;

            try
            {
                using (AssemblyInstaller installer = GetInstaller())
                {
                    IDictionary state = new Hashtable();
                    try
                    {
                        installer.Install(state);
                        installer.Commit(state);
                    }
                    catch
                    {
                        try
                        {
                            installer.Rollback(state);
                        }
                        catch { }
                        throw;
                    }
                }
            }
            catch
            {
                throw;
            }
        }

        public static void UninstallService()
        {
            if (!IsInstalled()) return;
            try
            {
                using (AssemblyInstaller installer = GetInstaller())
                {
                    IDictionary state = new Hashtable();
                    try
                    {
                        installer.Uninstall(state);
                    }
                    catch
                    {
                        throw;
                    }
                }
            }
            catch
            {
                throw;
            }
        }

        public static void StartService()
        {
            if (!IsInstalled()) return;

            using (ServiceController controller =
                new ServiceController(ServiceName))
            {
                try
                {
                    if (controller.Status != ServiceControllerStatus.Running)
                    {
                        controller.Start();
                        controller.WaitForStatus(ServiceControllerStatus.Running,
                            TimeSpan.FromSeconds(10));
                    }
                }
                catch
                {
                    throw;
                }
            }
        }

        public static void StopService()
        {
            if (!IsInstalled()) return;
            using (ServiceController controller =
                new ServiceController(ServiceName))
            {
                try
                {
                    if (controller.Status != ServiceControllerStatus.Stopped)
                    {
                        controller.Stop();
                        controller.WaitForStatus(ServiceControllerStatus.Stopped,
                             TimeSpan.FromSeconds(10));
                    }
                }
                catch
                {
                    throw;
                }
            }
        }
    }

参考

建立了一个独立项目交流群

建立了一个"独立项目交流群",本群主要交流开源项目的运作模式和盈利模式。

大家可以在名字前面加地区,以及熟悉的技能,如“长沙-全栈-ning”,名字建议用昵称。

目前还没有项目启动,大家可以想一想,可以先分享一些开源或者商业案例,慢慢形成讨论氛围。

注意:

  • 群永久免费
  • 卖课永久严禁加入
  • HR暂时严禁加入
  • 以前叫做开源项目交流群,后来发现大家可能不一定选择开源,所以就改一下吧

微信扫码进群

独立项目交流群

Windows下PHP安装Imagick扩展

查看本机PHP版本

php -v

输出

PHP 7.4.14 (cli) (built: Jan  5 2021 15:11:43) ( NTS Visual C++ 2017 x64 )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies

可以看到PHP版本为7.4,NTS(非线程安全),64位

下载扩展DLL

  1. 打开 https://pecl.php.net/package/imagick
  2. 找到最新稳定版本,点击后面的DLL
  3. 再打开的页面中,根据上面的PHP版本,选择要下载的DLL

安装

  1. 将下载的压缩文件下的php_imagick.dll放入PHP目录下的ext子目录下
  2. 将压缩文件下的其他DLL文件放到PHP目录
  3. 修改php目录下的php.ini,添加extension=imagick

解决Win10部分程序搜索不到的问题

知乎高分答案是让大家去重装小冰,通常可能是解决不了问题的。

因为情况实际可能是本地应用是以当前用户身份安装的,安装在用户的appdata目录下,然后Windows索引默认排除了用户的appdata目录,所以就搜索不到了。

解决办法:

  • 搜索任意文字,在搜索结果界面,点索右侧三圆点,打开索引选项窗口;

file

  • 在索引选项设置中找到排除目录,将用户的appdata目录从排除目录删除即可。

file

pyenv — 多版本Python(含镜像设置加速下载以及Windows)

编译python依赖包

sudo apt install libbz2-dev libcurses-ocaml-dev libctypes-ocaml-dev libreadline-dev libssl-ocaml-dev libffi-dev libsqlite3-dev liblzma-dev

安装pyenv

curl https://pyenv.run | bash

显示已安装python版本

pyenv install --list

设置使用镜像

 export PYTHON_BUILD_MIRROR_URL_SKIP_CHECKSUM=1
 export PYTHON_BUILD_MIRROR_URL="https://npm.taobao.org/mirrors/python/"

安装指定版本Python

pyenv install 3.9.9

运行指定版本Python

pyenv global 3.9.9

查看当前已安装和正在运行的Python版本

pyenv versions

查看已安装版本位置

pyenv prefix 3.9.9

windows安装pyenv

管理员身份进入powershell

Invoke-WebRequest -UseBasicParsing -Uri "https://raw.githubusercontent.com/pyenv-win/pyenv-win/master/pyenv-win/install-pyenv-win.ps1" -OutFile "./install-pyenv-win.ps1"; &"./install-pyenv-win.ps1"

C:\Users\Administrator\.pyenv\pyenv-win\.versions_cache.xml中的所有www.python.org/ftp替换为npmmirror.com/mirrors

安装完以后重新管理员打开powershell

pyenv install 3.10.5

其他

  • pyenv的替代工具是asdf, 可以管理多个语言的版本,包含Python,node,Erlang,Ruby,PHP,Mysql,Postgres等

参考

pipx — 在隔离的环境中安装和运行Python应用程序

pipx 介绍

在隔离的环境中安装和运行Python应用程序,安装的程序都在自己隔离的环境,不用考虑依赖冲突,且可以安装多个版本,可以非root身份运行程序。官网:https://github.com/pypa/pipx

安装 pipx

python3 -m pip install --user pipx

配置自动完成

pipx completions

使用 pipx 安装

pipx install pipenv

通过 url 安装

pipx install git+https://github.com/psf/black.git
pipx install git+https://github.com/psf/black.git@branch  # branch of your choice
pipx install git+https://github.com/psf/black.git@ce14fa8b497bae2b50ec48b3bd7022573a59cdb1  # git hash
pipx install https://github.com/psf/black/archive/18.9b0.zip  # install a release

列出已安装应用

pipx list

升级

pipx upgrade pipenv

运行

pipx run pipenv

指定版本运行

pipx run APP==1.0.0

通过 url 运行

pipx run https://gist.githubusercontent.com/cs01/fa721a17a326e551ede048c5088f9e0f/raw/6bdfbb6e9c1132b1c38fdd2f195d4a24c540c324/pipx-demo.py

卸载

pipx  uninstall pipenv

卸载所有

pipx  uninstall-all

显示帮助

pipx  -h

Windows编译pdfium

确定 Visual Studio 和 Windows SDK 版本

  • 需要Visual Studio2017 及以上
  • Windows SDK 10.0.19041 及以上(需要Debugging Tools For Windows)
  • 安装Desktop development with C++
  • 安装MFC/ATL support

设置全局代理

set DEPOT_TOOLS_WIN_TOOLCHAIN=0
set DEPOT_TOOLS_UPDATE=0
set http_proxy=127.0.0.1:1080
set https_proxy=127.0.0.1:1080
set GYP_MSVS_VERSION=2022

安装 depot_tools

  • 下载 depot_tools ,并解压缩到d:\sdk\depot_tools目录
  • 系统path环境变量添加d:\sdk\depot_tools
  • 将然后设置vs2022_install环境变量为D:\Program Files\Microsoft Visual Studio\2022\Community
  • 运行gclient

验证Python安装

命令行输入where python,确保D:\sdk\depot_tools\python.bat在第一条,
如果不是则修改PATH环境变量顺序

下载 pdfium 代码

以管理员身份打开命令提示符,进入D:\cproject\pdfium目录

gclient config --unmanaged https://pdfium.googlesource.com/pdfium.git
gclient sync

生成构建文件

cd pdfium
gn args --ide=vs out\Default

out\Default\args.gn如下

# Set build arguments here. See `gn help buildargs`.

use_goma = false

clang_use_chrome_plugins = false

pdf_is_standalone = true

pdf_use_skia = false
pdf_use_skia_paths = false

is_debug = false

is_component_build = true

pdf_is_complete_lib = false

pdf_enable_xfa = false

pdf_enable_v8 = false

target_cpu = "x86"

is_clang = true

禁用v8可以提高编译性能,使用clang可以提高编译和程序运行性能,如果VS编译不通过,就尝试使用clang试试。

编译测试

编译测试程序

ninja -C out\Default pdfium_test # 编译测试程序
pdfium_test --help # 运行测试程序

编译windows动态库dll

# 首先需要将 is_component_build 改为 true
ninja -C out\Default pdfium # 编译动态库

参考

企业招聘10倍程序员和0.5倍程序员的区别

首先,10倍只能是偶尔某些任务,并不是所有任务类型能10倍效率。

其次,编程是一项需要协作的工作,很多时候是流水线试操作的。且小组的一个10倍程序员可能没法让整个小组效率都能10倍,真正10倍程序员也不太好鉴别,或者不存在(干每项工作都10倍?)。而一个0.5倍程序员,却通常可以让整个小组的效率都变为0.5倍甚至更慢,而这通常非常容易鉴别。当我们在谈论10倍程序员时,通常我们只是想找一个1倍的,是因为大部分都还没有达到1倍;

所以,想招聘10倍程序员,成立10倍团队是不现实的,收益和成功可能性远少于踢掉团队0.x的程序员,木桶定律才是优先需要考虑的,企业不要企图花费太大精力企图去招聘10倍程序员,而是要防止招聘到0.x倍程序员,要时刻警惕0.x倍程序员。

对于个人来说,哪怕你真成为10倍程序员,公司不会给你10倍工资,要想成为10倍效率程序员,可能不太行得通,那么价值上的10倍可行性怎么样呢,可能更值得探讨?

MySQL分段统计函数INTERVAL和ELT

需求

期末考试成绩出来了,结果需要分为不及格(0-59),合格(60-84),优秀(80+)三个段,老师需要统计每个段成绩的分布情况。

分数表score结构如下:

id int
user_id int
score int

使用INTERVAL函数对学生成绩分段

SELECT user_id,score,INTERVAL(score,60,85) as step from score

INTERVAL函数会根据score返回0(少于60),1(60-74),2(85以及以上)

INTERVAL返回的结果进行分组:

SELECT INTERVAL(score,60,85),COUNT(*) AS num as step from score GROUP BY INTERVAL(score,60,85)

得到:

0, 5
1, 80
2, 15

使用ELT函数为阶段命名

ETL方法会建立重命名,将1,2,3分别转化为不及格,合格,优秀,但是etl不能是从0开始的,所以我们可以在INTERVAL分组时加一个0,将0分以下的划分为0,0-59的划为1,依次类推

SELECT INTERVAL(score,0,60,85),COUNT(*) AS num as step from score GROUP BY INTERVAL(score,60,85)

得到:

1, 5
2, 80
3, 15

最终SQL:

SELECT ELT(INTERVAL(score,0,60,85),"不及格","合格","优秀"),COUNT(*) AS num as step from score GROUP BY ELT(INTERVAL(score,0,60,85),"不及格","合格","优秀")

得到:

不及格, 5
合格, 80
优秀, 15

PHP 5/7/8编译安装实例

PHP 5.6

PHP 5只能用openssl 1.0, curl使用7.70.0,freetype 2.6.5

./configure --prefix=/usr/local/php/5.6 \
--enable-fpm \
--enable-bcmath \
--enable-calendar \
--enable-exif \
--with-gd \
--enable-gd-jis-conv \
--enable-mbstring \
--with-pdo-mysql \
--with-pdo-pgsql \
--enable-sockets \
--enable-opcache \
--with-jpeg-dir \
--with-png-dir \
--with-zlib-dir \
--with-xpm-dir \
--enable-gd-native-ttf  \
--enable-gd-jis-conv \
--with-openssl=/usr/local/openssl-1.0

make -j 6

sudo make install

/usr/local/php/5.6/bin/php -m

PHP 7.4

./configure \
--prefix=/usr/local/php/7.4 \
--enable-fpm \
--with-fpm-user=ning \
--with-fpm-group=ning \
--with-pdo-mysql \
--with-pdo-pgsql \
--with-iconv-dir \
--with-freetype \
--with-jpeg \
--with-zlib \
--enable-xml \
--disable-rpath \
--enable-bcmath \
--enable-shmop \
--enable-sysvsem \
--enable-inline-optimization \
--with-curl \
--enable-mbregex \
--enable-mbstring \
--enable-intl \
--enable-ftp \
--enable-gd \
--with-openssl \
--with-mhash \
--enable-pcntl \
--enable-sockets \
--with-xmlrpc \
--enable-soap \
--with-gettext \
--disable-fileinfo \
--enable-opcache \
--with-sodium \
--with-webp

make -j 6

sudo make install

/usr/local/php/7.4/bin/php -m

PHP 8.1

configure \
--prefix=/usr/local/php/8.1 \
--enable-fpm \
--with-fpm-user=ning \
--with-fpm-group=ning \
--with-pdo-mysql \
--with-pdo-pgsql \
--with-freetype \
--with-jpeg \
--with-zlib \
--enable-xml \
--disable-rpath \
--enable-bcmath \
--enable-shmop \
--enable-sysvsem \
--with-curl \
--enable-mbregex \
--enable-mbstring \
--enable-intl \
--enable-ftp \
--enable-gd \
--with-openssl \
--with-mhash \
--enable-pcntl \
--enable-sockets \
--enable-soap \
--with-gettext \
--disable-fileinfo \
--enable-opcache \
--with-sodium \
--with-webp

make -j 6

sudo make install

/usr/local/php/8.1/bin/php -m