存档

作者存档

Error launching installer 的一种解决方法

2024年6月5日 没有评论

对于电脑上的图片预览工具,看了这么多,还是 Google 家的 Picasa 是最好用的,可惜的是停止开发了。幸运的是,有好心人提供了 Picasa 3.9.136.9 提取版,移除了图片管理等无关的功能,只保留了图片预览。

所以这么多年来,这个工具一直很好用。

最近在一个测试机器上安装时,软件报告 Error launching installer 错误。从提示来看,这个提取版使用的是 NSIS 来打包的。

一开始,以为是语言包的问题,为系统添加了中文语言包后,发现无效。

接着寻思,是不是因为时间过于久远,需要 C++ 运行时,然后吧啦吧啦一顿安装,发现还是无效。

后来在网上无意间发现有个帖子说,出现这个错误,可能需要重启电脑。突然想起来,确实在几天前安装了某个软件,当时提示要重启系统,直接给忽略了。

果然,重启系统后,Picasa 提取版可以顺利安装了。

分类: 一句话, 日常 标签:

C# 切换多屏幕显示模式

2024年5月12日 没有评论

网上搜索了下,有2种方式。

一、直接执行系统自带的程序 DisplaySwitch.exe,它在 windows\system32 目录下。对应的 C# 代码如下:

using (var proc = new Process())
{
proc.StartInfo.FileName = @"DisplaySwitch.exe";
proc.StartInfo.Arguments = "/external";
proc.Start();
}

二、调用系统 API SetDisplayConfig 函数

private const uint SDC_APPLY = 0x00000080;
private const uint SDC_TOPOLOGY_INTERNAL = 0x00000001;
private const uint SDC_TOPOLOGY_CLONE = 0x00000002;
private const uint SDC_TOPOLOGY_EXTERNAL = 0x00000008;
private const uint SDC_TOPOLOGY_EXTEND = 0x00000004;

[DllImport("user32.dll", CharSet = CharSet.Unicode)]
public static extern long SetDisplayConfig(uint numPathArrayElements, IntPtr pathArray, uint numModeArrayElements,IntPtr modeArray, uint flags);

/// /// 设置屏幕的显示模式 ///
/// 模式(0 - 主屏 1 - 双屏复制 2 - 双屏扩展 3 - 第二屏幕
///
public void SetScreenMode(int type)
{
uint mode;

switch (type)
{
    case 0:
        mode = SDC_APPLY | SDC_TOPOLOGY_INTERNAL;
        break;
    case 1:
        mode = SDC_APPLY | SDC_TOPOLOGY_CLONE;
        break;
    case 2:
        mode = SDC_APPLY | SDC_TOPOLOGY_EXTEND;
        break;
    case 3:
        mode = SDC_APPLY | SDC_TOPOLOGY_EXTERNAL;
        break;
    default:
        mode = SDC_APPLY | SDC_TOPOLOGY_INTERNAL;
        break;
}

SetDisplayConfig(0, IntPtr.Zero, 0, IntPtr.Zero, mode);

}

分类: 一句话 标签:

windows 命令行临时使用环境变量

2024年4月1日 没有评论

对于过去的 cmd 命令行,可以使用 set ABC=xxx 来设置环境变量。

然后使用 echo ABC 来打印其值。

对于新的 power shell 命令行,就需要更换写法了,$Env:ABC=xxx

如果要打印,就直接使用 $Env:ABC 就可以了。

需要强调的一句是,这些都是在当前命令行上下文临时使用的,一旦关闭了,这些环境变量就不存在了。有利有弊,看需求。例如我自己就是用来设置代理下载第三方库或者依赖包,非常方便。

分类: 一句话, 日常 标签: ,

如何完整卸载 McAfee

2024年3月15日 没有评论

要说啊还真是只有魔法才可以打败魔法。测试机上的 McAfee 软件要卸载,通过控制面板里的添加删除程序结果自卸载失败,而且是每次都失败,占用着磁盘空间。

经过一番搜索,发现了来自官方的 MCPR 卸载工具,可以完整地卸载。

下载地址是: https://download.mcafee.com/molbin/iss-loc/SupportTools/MCPR/MCPR.exe

运行后会提示输入验证码,以防止误操作。之后就需要耐心等一等了,直到给出提示说卸载成功。老实讲,比我预期的时间还要长一些。

分类: 一句话, 日常 标签: ,

Windows 启用长路径支持

2024年2月20日 没有评论

随着 AI 技术的流行,越来越多的工具被提供了出来,但是众所周知的是,很多是 Python 的,在 windows 平台上就不得不提到长路径。尽管这是一个历史遗留问题,而且很多软件的安装包在安装的时候,也提供选项可以快速启用这个功能。

但是,很多时候,我们还是需要手动来打开。

网上基本上有注册表和组策略这两种方式,相比而言,衣服自己洗这里更偏爱注册表的方式,绿色干净。

  • 打开注册表编辑器
  • 找到如下路径:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSytem
  • 找到如下键值:LongPathsEnabled。将值修改为1即可。默认是0不启用

如果对于有的软件还提示这个,可以重启系统后再试一试。

分类: 一句话, 日常 标签:

减少 windows 系统 Microsoft Defender 对 CPU 的占用

2024年1月3日 没有评论

我的老爷机一直用的是 win10,以前有发现系统经常用着用着,CPU占用就上去了。后面发现是系统自带是杀毒软件在搞鬼,就不能挑个不用电脑的时候来扫描么。

后来,有看到一个方式是使用工具完整地卸载内置的杀毒软件,但是感觉可能会导致系统不稳定,没有采用。

后面实在是困扰的不行,只好把整个硬盘都放到例外文件夹里。

今天,在网上发现了一个新的方法,感觉满足自己的要求:不卸载,但是又对其进行控制。

运行 gpedit.msc,打开组策略,计算机配置-管理模板-Windows 组件-Microsoft Defender 防病毒-扫描,在右边有一个默认未配置的“指定扫描期间 CPU 使用率的最大百分比”,双击打开,启用并设置百分比为 2%,其默认的 50% 实在是吓人。

分类: 一句话, 日常 标签:

Zerotier windows问题汇总

2023年12月1日 没有评论

1、设备加入网络后,设备显示在线但是无法 ping 通
虽然不知道原因,但是实际验证这个方法可以解决:控制面板->系统和安全->Windows Defender防火墙->高级设置->入站规则。把里面的 “文件和打印机共享(回显请求 – ICMPv4-in)”给打开,一般而言会有多个记录,可以全部打开或者逐个打开。

2、远程机器显示无法访问
首先要考虑的就是系统的防火墙是否允许了这些特定的端口,如果没有,需要添加入站规则。

分类: 日常 标签:

疫情放开一年

2023年11月25日 没有评论

去年的这个时候,大家都在床上发烧,小区显得格外安静。现在疫情放开已经差不多将近一年了,在最近的时候呢,发现身边的很多人都和医院杠上了。

看到一个消息是说在医院挂急诊的号,排到了24小时后。很多小朋友都因为高烧在医院里排队,一些家长跑好几个医院没有号。

甲流、支原体、合胞病毒都非常猖獗,加上冬季感冒,大家可得千万小心,出门在外也尽量带上口罩。

对于每一波都没有逃过的人,实在是太痛苦了。

分类: 一句话, 日常 标签:

supervisor

2023年10月12日 没有评论

在前面的文章中,我们使用了PM 2这个软件来做任务管理。今天再给大家推荐supervisor。

supervisor是一个进程管理工具,,同时,它也是一个客户端/服务器系统,允许用户在类unix操作系统上控制多个进程。

supervisor是用 Python 开发的一套通用的进程管理程序,具有下面的特点:
1、能将一个普通的命令行进程变为后台daemon,并监控进程状态,异常退出时能自动重启。
2、当进程中断的时候supervisor能自动重新启动它
3、为supervisord或者每个子进程,设置一个非root的user,这个user就可以管理它对应的进程

安装:

pip install supervisor

默认会生成下面路径

# supervisord 路径
/usr/local/bin/supervisord
# supervisorctl 路径
/usr/local/bin/supervisorctl
# echo_supervisord_conf 路径
/usr/local/bin/echo_supervisord_conf
分类: 一句话 标签:

无头浏览器 PuppeteerSharp

2023年9月3日 没有评论

在研究无头浏览器的时候,发现了一些不错的工具,例如 phantomjs 就可以让你以前端 js 脚本的方式来操作页面,以满足一些自动化测试方面的需求。后来又发现了 puppeteer,有很多开发语言的实现。

而今天提及的 PuppeteerSharp 就是 .Net 的实现。可能我执念太深,总觉得 Net 是相当不错的选择。

PuppeteerSharp 是一个控制无头Chrome 浏览器的库,它允许开发者通过编程方式模拟浏览器行为,执行网页操作,截取网页截图,获取网页内容,可以把网页转换成PDF等等。

截图

using var browserFetcher = new BrowserFetcher();
await browserFetcher.DownloadAsync();
await using var browser = await Puppeteer.LaunchAsync(
new LaunchOptions { Headless = true });
await using var page = await browser.NewPageAsync();
await page.GoToAsync("http://www.google.com");
await page.ScreenshotAsync(outputFile);

也支持设置页面的尺寸

await Page.SetViewportAsync(new ViewPortOptions
{
Width = 500,
Height = 500
});

生成 pdf 文件

using var browserFetcher = new BrowserFetcher();
await browserFetcher.DownloadAsync();
await using var browser = await Puppeteer.LaunchAsync(new LaunchOptions {Headless = true});
await using var page = await browser.NewPageAsync();
await page.GoToAsync("http://www.google.com"); // In case of fonts being loaded from a CDN, use WaitUntilNavigation.Networkidle0 as a second param.
await page.EvaluateExpressionHandleAsync("document.fonts.ready"); // Wait for fonts to be loaded. Omitting this might result in no text rendered in pdf.
await page.PdfAsync(outputFile);

动态注入 html 元素

await using var page = await browser.NewPageAsync();
await page.SetContentAsync("My Receipt");
var result = await page.GetContentAsync();

执行脚本

await using var page = await browser.NewPageAsync();
var seven = await page.EvaluateExpressionAsync("4 + 3");
var someObject = await page.EvaluateFunctionAsync("(value) => ({a: value})", 5);
Console.WriteLine(someObject.a);

等待某个选择器

using (var page = await browser.NewPageAsync())
{
await page.GoToAsync("https://www.baidu.com");
await page.WaitForSelectorAsync("div.main-content")
await page.PdfAsync(outputFile));
}

等待函数的执行

using (var page = await browser.NewPageAsync())
{
await page.GoToAsync("https://www.baidu.com");
var watchDog = page.WaitForFunctionAsync("()=> window.innerWidth < 100");
await page.SetViewportAsync(new ViewPortOptions { Width = 50, Height = 50 });
await watchDog;
}


分类: C#, 日常 标签: