博客 (757)

错误 Web 部署任务失败。

在远程计算机上处理请求时出错。

无法执行此操作。请与服务器管理员联系,检查授权和委派设置。

原因:WDeployAdmin 与 WDeployConfigWriter 这两个用户密码过期。

解决方法:

第一步,打开用户管理,重新设置这两个用户的密码

image.png

并在“属性”窗口勾选“密码永不过期”

image.png

第二步,打开 IIS 管理器中的“管理服务委派”

image.png

找到所有与这两个用户有关的项,右键“编辑”

image.png

点击左下角的“设置”按钮,填入与原来一致的用户名与第一步新设置的密码

image.png

全部设置完成后,即可正常发布项目。

xoyozo 2 年前
1 Comments 2,266

错误 TS5055 无法写入文件“***.js”,因为它会覆盖输入文件。

添加 tsconfig.json 文件有助于组织包含 TypeScript 和 JavaScript 文件的项目。有关详细信息,请访问 https://aka.ms/tsconfig。

检查“输出”窗口,找到“error”的行,并修复该错误。

一种可能的情况是,使用了 vue3 的 computed 计算属性。原因未知,尝试又定义了一个变量并使用 watch 侦听原变量来给它赋值,同样报错。

xoyozo 2 年前
2,161

System.ComponentModel.Win32Exception: 拒绝访问。

[ExternalException (0x80004005): 无法执行程序。所执行的命令为 "\bin\roslyn\csc.exe" /shared /keepalive:"10" /noconfig  /fullpaths @"C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\8c8f68eb\880f02b5\alczcu1a.cmdline"。]

解决方法:

web 部署发布时勾选“在发布期间预编译”

image.png

在“配置”中,去掉“允许更新预编辑站点”前的勾,勾选“不合并。为每个页面和控件创建单独的程序集”

image.png

xoyozo 2 年前
1,979

本文以 vue 3 为例,vue 2 同理。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>clipboard.js 在 vue.js 中使用</title>
</head>
<body>
    <div id="app">
        <ul>
            <li v-for="item in list">
                {{item}}
                <button class="btn-cp" :value="item">复制</button>
            </li>
        </ul>
    </div>
    <script src="//xxx/vue/core-3.x.x/vue.global.js"></script>
    <script src="//xxx/clipboard/clipboard.js-2.x.x/dist/clipboard.min.js"></script>
    <script>
        const app = Vue.createApp({
            data: function () {
                return {
                    list: ["aaa", "bbb", "ccc"]
                }
            },
            mounted: function () {
                var clipboard = new ClipboardJS('.btn-cp', {
                    text: function (trigger) {
                        return trigger.getAttribute('value');
                    }
                });
                clipboard.on('success', function (e) {
                    alert('已复制“' + e.text + '”到粘贴板');
                    e.clearSelection();
                });
            }
        });
        const vm = app.mount('#app');
    </script>
</body>
</html>


xoyozo 2 年前
1,443
  • 从朋友圈发布的视频时长限制30秒

  • 从视频号发布的视频时长限制30分钟

视频号助手网址:https://channels.weixin.qq.com/platform,管理视频号创作内容,相当于抖音巨量百应达人工作台。

视频号小店网址:https://channels.weixin.qq.com/shop,管理商品和订单,相当于抖店。


xoyozo 2 年前
4,789

第一步,创建用户和 AccessKey

登录阿里云控制台后,从头像处进入 AccessKey 管理

image.png

“开始使用子用户 AccessKey”

image.png

点击“创建用户”,填写用户名(本文以 oss-bbs 为例),并勾选“Open API 调用访问”

image.png

点击确定创建成功,可以看到 AccessKey ID 和 AccessKey Secret


第二步,创建权限策略

在阿里云控制台左侧菜单“RAM 访问控制”中展开“权限管理”,选择“权限策略”

image.png

点击“创建权限策略”,切换到“脚本编辑”

image.png

输入以下策略文档(JSON 格式)

{
    "Version": "1",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                    "oss:ListBuckets",
                    "oss:GetBucketStat",
                    "oss:GetBucketInfo",
                    "oss:GetBucketAcl" 
                      ],    
            "Resource": "acs:oss:*:*:*"
        },
        {
            "Effect": "Allow",
            "Action": [
                    "oss:Get*",
                    "oss:Put*",
                    "oss:List*",
                    "oss:DeleteObject"
                    ],
            "Resource": "acs:oss:*:*:bbs"
        },
        {
            "Effect": "Allow",
            "Action": [
                    "oss:Get*",
                    "oss:Put*",
                    "oss:List*",
                    "oss:DeleteObject"
            ],
            "Resource": "acs:oss:*:*:bbs/*"
        }
    ]
}

脚本中第一段表示允许用户登录,第二段表示允许操作 Bucket,第三段表示允许操作 Bucket 内的文件对象。

示例中的 bbs 是 Bucket Name,请修改为自己的 Bucket 名称。

点击下一步,填写名称,确定即可。


第三步,添加用户权限

转到“用户”页面,在刚才创建的用户行“添加权限”

image.png

切换到“自定义策略”,将上一步创建的权限策略添加到右侧“已选择”区

image.png

确定。


相关信息:

You have no right to access this object because of bucket acl.

xoyozo 2 年前
1,906

首先,禁止网站下所有 .php 等文件均不允许被访问到。

在 nginx 网站配置文件中,include enable-php-**.conf; 上方插入:

location ~ ^/.*\.(php|php5|py|sh|bash|out)$ { deny all; }

其中,^ 匹配开始,/.* 匹配所有目录和文件名,\.(php|php5|py|sh|bash|out) 匹配文件后缀名,$ 匹配结束。

即便如此,仍然忽略了 nginx 中 .php 文件名后加斜杠仍然能访问到的情况,譬如我们访问这个网址:

https://xoyozo.net/phpinfo.php/abc.html

nginx 仍然运行了 phpinfo.php,给了后门可趁之机,所以改进为:

location ~ ^/.*\.(php|php5|py|sh|bash|out)(/.*)?$ { deny all; }


Discuz! X3.4 需要写入权限的目录:

  • /自研目录/upload/

  • /config/

  • /data/

  • /uc_client/data/

  • /uc_server/data/

  • /source/plugin/

但,这些都不重要,我们已经禁止了所有目录的 .php 访问了。


第二步,解禁需要直接被访问到的文件路径。

Discuz! X3.4 根目录下的 .php 文件都是入口文件,需要能够被访问到:

/admin.php
/api.php
/connect.php
/forum.php
/group.php
/home.php
/index.php
/member.php
/misc.php
/plugin.php
/portal.php
/search.php

其它目录中需要被直接访问到的文件:

/archiver/index.php
/m/index.php
/uc_server/admin.php
/uc_server/avatar.php
/uc_server/index.php

部分插件文件需要能够被直接访问到:

/source/plugin/magmobileapi/magmobileapi.php
/source/plugin/smstong/accountinfo.php
/source/plugin/smstong/checkenv.php

另外如果有自建目录需要有 .php 访问权限,那么也需要在此处加白,本文以 /_/ 目录为例

最终拼成:工具

location ~ ^(?:(?!(/admin\.php|/api\.php|/connect\.php|/forum\.php|/group\.php|/home\.php|/index\.php|/member\.php|/misc\.php|/plugin\.php|/portal\.php|/search\.php|/archiver/index\.php|/m/index\.php|/uc_server/admin\.php|/uc_server/avatar\.php|/uc_server/index\.php|/source/plugin/magmobileapi/magmobileapi\.php|/source/plugin/smstong/accountinfo\.php|/source/plugin/smstong/checkenv\.php|/_/.*\.php))/.*\.(php|php5|py|sh|bash|out)(/.*)?)$ { deny all; }

这里用到正则表达式中的“不捕获”和“负向零宽断言”语法,格式为:

^(?:(?!(允许的目录或文件A|允许的目录或文件B))禁止的目录和文件)$

值得注意的是,此句负向零宽断言中的匹配内容是匹配前缀的,也就是说

https://xoyozo.net/index.php
https://xoyozo.net/index.php/abc.html

都可以访问到,而

https://xoyozo.net/forbidden.php
https://xoyozo.net/forbidden.php/abc.html

都访问不到,这是符合需求的。

如果自建目录 /_/ 下有写入需求,单独禁止即可,以 /_/upload/ 为例:

location ~ ^/_/upload/.*\.(php|php5|py|sh|bash|out)(/.*)?$ { deny all; }


ThinkPHP 网站有统一的访问入口,可按本文方法配置访问权限。


特别注意:上面的代码必须加在 PHP 引用配置(include enable-php-**.conf;)的上方才有效。


附:一键生成 nginx 访问控制 location URI { } 语句工具

xoyozo 2 年前
2,013

外星人笔记本电脑键盘突然失灵,尝试过重启电脑、长按电源键(强制关机、切换电脑性能)、卸载键盘驱动、BIOS 恢复默认设置都没有效果。多次尝试后恢复正常,总结经验:

办法一:关机、拔掉电源、插上电源、再开机,就能恢复正常。

办法二:长按电源键直到关机成功,长按电源键直至开机完成。

若无效,强制关机、插拔电源,多试几次。

总之,这电脑不用的时候尽量关机,直接合上盖子会出现自动苏醒、键盘失灵等一系列问题。


2023年9月补充,最近发现直接合上盖子没有出现自动苏醒,先睡眠再拔电源也没有出现苏醒,可能与我经常在 Alienware Update 和 SupportAssist 中更新驱动和固件有关。

xoyozo 2 年前
6,424

本文使用 ASP.NET 6 版本 Senparc.Weixin.Sample.MP 示例项目改造。


第一步 注册多公众号

方法一:打开 appsettings.json 文件,在 SenparcWeixinSetting 节点内添加数组节点 Items,该对象类型同 SenparcWeixinSetting。

//Senparc.Weixin SDK 设置
"SenparcWeixinSetting": {
  "IsDebug": true,
  "Token": "",
  "EncodingAESKey": "",
  "WeixinAppId": "",
  "WeixinAppSecret": "",
  "Items": [
    {
      "IsDebug": true,
      "Token": "a",
      "EncodingAESKey": "a",
      "WeixinAppId": "a",
      "WeixinAppSecret": "a"
    },
    {
      "IsDebug": true,
      "Token": "b",
      "EncodingAESKey": "b",
      "WeixinAppId": "b",
      "WeixinAppSecret": "b"
    }
  ]
}

方法二:修改 Program.cs 文件,在 UseSenparcWeixin 方法中注册多个公众号信息。

var registerService = app.UseSenparcWeixin(app.Environment,
    null /* 不为 null 则覆盖 appsettings  中的 SenparcSetting 配置*/,
    null /* 不为 null 则覆盖 appsettings  中的 SenparcWeixinSetting 配置*/,
    register => { /* CO2NET 全局配置 */ },
    (register, weixinSetting) =>
    {
        //注册公众号信息(可以执行多次,注册多个公众号)
        //register.RegisterMpAccount(weixinSetting, "【盛派网络小助手】公众号");
        foreach (var mp in 从数据库或配置文件中获取的公众号列表)
        {
            register.RegisterMpAccount(new SenparcWeixinSetting
            {
                //IsDebug = true,
                WeixinAppId = mp.AppId,
                WeixinAppSecret = mp.AppSecret,
                Token = mp.Token,
                EncodingAESKey = mp.EncodingAeskey,
            }, mp.Name);
        }
    });

完成后,我们可以从 Config.SenparcWeixinSetting.Items 获取这些信息。


第二步 接入验证与消息处理

打开 WeixinController 控制器,将构造函数改写为:

public WeixinController(IHttpContextAccessor httpContextAccessor)
{
    AppId = httpContextAccessor.HttpContext!.Request.Query["appId"];
    var MpSetting = Services.MPService.MpSettingByAppId(AppId);
    Token = MpSetting.Token;
    EncodingAESKey = MpSetting.EncodingAESKey;
}

示例中 Services.MPService.MpSettingByAppId() 方法实现从 Config.SenparcWeixinSetting.Items 返回指定 appId 的公众号信息。

为使 IHttpContextAccessor 注入生效,打开 Program.cs,在行

builder.Services.AddControllersWithViews();

下方插入

builder.Services.AddHttpContextAccessor();

这样,我们就可以在构造函数中直接获取地址栏中的 appId 参数,找到对应的公众号进行消息处理。


第三步 消息自动回复中的 AppId

打开 CustomMessageHandler.cs,将 

private string appId = Config.SenparcWeixinSetting.MpSetting.WeixinAppId;
private string appSecret = Config.SenparcWeixinSetting.MpSetting.WeixinAppSecret;

替换为:

private string appId = null!;
private string appSecret = null!;

并在构造函数中插入

appId = postModel.AppId;
appSecret = Services.MPService.MpSettingByAppId(postModel.AppId).WeixinAppSecret;

这样,本页中使用的 appId / appSecret 会从 postModel 中获取,而非默认公众号。postModel 已在 WeixinController 中赋值当前的 appId。

改造后,我们可以在 OnTextRequestAsync() 等处理消息的方法中可以判断 appId 来处理不同的消息。


第四步 其它功能和接口

其它功能和接口均可用指定的 AppId 和对应的 AppSecret 进行调用。

xoyozo 2 年前
1,708

Senparc.Weixin.Sample.MP 盛派微信公众平台示例项目在 VS 中运行正常,当发布到 IIS 后出现应用程序池自动停止的情况,在服务器管理器中找到 .NET Runtime 错误,可以看到错误原因:

\App_Data\SenparcTraceLog 目录需要写入权限。

image.png

以下目录也需要写入权限:

\App_Data\WeChat_OfficialAccount

\App_Data\NeuChar

xoyozo 2 年前
1,017