分类 未分类 下的文章

微信开发者社区在18年就有人提出这个问题,当时说是不行.然而提问者说为什么另外一家小温智能可以?
经过自行测试,发现通过微信接口是可以以AP模式进行设置的. 因为微信小程序WIFI有两个能力:获取周围SSID,以及连接SSID.
SDK文档

获取SSID方式

在app.json中获取地理位置能力

  "permission": {
    "scope.userLocation": {
      "desc": "你的位置信息将用于小程序连接WIFI"
    }

在页面js中onGetWifiList->startWifi->getWifiList. 微信小程序比较神奇的地方是,get信息的函数居然不是直接返回信息,而是只返回成功失败, 然后发出一个事件,你得再用另一个专门监听这个事件的函数来得到信息. 感觉脱裤子放屁一样.

  onReady: function () { //启动后先监听获取到WIFILIST的事件
    wx.onGetWifiList(function (res){
      console.log(res)
    })
  },
  startwifi:function(){ //启动WIFI接口,事实上不是开启设备的WIFI,只是开启小程序的WIFI能力
    wx.startWifi({
      success(res) {
        console.log(res.errMsg)
      }
    })
  },
  getwifilist: function () { //获取WIFILIST, 成功后发出事件会被前面的监听捕获
    console.log('getwifilist')
    wx.getWifiList({
      complete(res) {
        console.log(res)
      }
    })
  },

WIFILIST的形式:

{wifiList: []}

Android举例(从console输出COPY来的)

wifiList: Array(24)
0: {SSID: "KK5G", BSSID: "xx:xx:xx:xx:xx:xx", secure: true, signalStrength: 77}
1: {SSID: "DIRECT-5BDESKTOP-0M7QR80msVL", BSSID: "xx:xx:xx:xx:xx:xx", secure: true, signalStrength: 99}
2: {SSID: "ChinaNet-UFsN", BSSID: "xx:xx:xx:xx:xx:xx", secure: true, signalStrength: 44}
3: {SSID: "KK", BSSID: "xx:xx:xx:xx:xx:xx", secure: true, signalStrength: 46}

IOS举例, 居然元素结构和Android不同. signalStrength的定义也不一样,一个是整数一个是纯小数.幸好SSID和BSSID两个字段是一样的.
IOS还有个问题,wx.onGetWifiList在ios中不进入回调,幸好官方有回答,是getWifiList以后会调起微信权限页面,上退一级到设置主页面,再点击WIFI,刷出来列表后才能收到onGetWifiList的回调.

wifiList: Array(18)
0: {SSID: "ROADSUN2", autoJoined: false, signalStrength: 0.26170599460601807, justJoined: false, BSSID: "xx:xx:xx:xx:xx:xx", …}
1: {SSID: "TP-LINK_090C", autoJoined: false, signalStrength: 0.3535159230232239, justJoined: false, BSSID: "xx:xx:xx:xx:xx:xx", …}
2: {SSID: "office1_2.4GHz", autoJoined: false, signalStrength: 0.39624282717704773, justJoined: false, BSSID: "xx:xx:xx:xx:xx:xx", …}
3: {SSID: "408a", autoJoined: false, signalStrength: 0.5117818117141724, justJoined: false, BSSID: "xx:xx:xx:xx:xx:xx", …}
4: {SSID: "ChinaNet-ePMi", autoJoined: false, signalStrength: 0.5352672934532166, justJoined: false, BSSID: "xx:xx:xx:xx:xx:xx", …}

//展开一个元素:
{
BSSID: "xx:xx:xx:xx:xx:xx"
SSID: "ROADSUN2"
autoJoined: false
justJoined: false
secure: true
signalStrength: 0.26170599460601807
}

可以看到返回值里居然没有WIFI类型是2.4G还是5G...

可能的设置方式

设置过程如下:

  1. 智能设备进入Station模式, 扫描周围WIFI SSID,先存下来
  2. 智能设备进入AP模式, 等待小程序连接
  3. 小程序获取周围WIFI SSID, 这儿要区分下IOS和Android,两者体验不同.(此步骤也可省略,以智能设备获取的为准)
  4. 小程序连接智能设备AP
  5. 小程序通过API获取智能设备的SSID
  6. 小程序的SSID和智能设备的SSID取交集, 供用户选择(筛选出2.4G WIFI)
  7. 用户选择并输入密码
  8. 小程序自己先试试能不能连接上,尝试的过程中会断开与智能设备的链接,如果密码错误让用户重新输入
  9. 小程序链接成功后,再次链接智能设备的AP, 正式通知智能设备链接WIFI.
  10. 完成后,小程序自行重新连接WIFI. 结束.

兼容性问题和系统差异

  • 对版本要求: 小程序1.6.0,现在99.99%已经支持.
  • getWifiList这个接口iOS 将跳转到系统的 Wi-Fi 界面,Android 不会跳转。 iOS 11.0 及 iOS 11.1 两个版本因系统问题,该方法失效。但在 iOS 11.2 中已修复。
  • iOS11.0是2017.9.17发布,2017年10月31日发布11.2的首个beta版. 同期2017年9月13日发布的手机是,第十一代iPhone 8,iPhone 8 Plus,iPhone X
  • connectWifi仅 Android 与 iOS 11 以上版本支持. 现在的版本已经是13.3.

国外

github不用说了,只是私有库要收费
gitlab也是极好的, 尤其是自建私服首选

国内

码云gitee是OSCHINA的团队, 虽然是个深圳的不大的公司,但支持私有库嘛,虽然国内对隐私保护都很可疑. 所有私有库协作人数累计不超过5个.
coding.net, 也在深圳,似乎现在要被腾讯收了, 腾讯的托管平台叫腾讯云开发者平台现在注册的话会直接跳转coding. coding号称是以团队方式注册,5人以下团队免费. 里面不止有git仓库,还有整套敏捷管理, 比较像是tapd+github,甚至额外还有些持续集成持续测试.
阿里云托管平台, 登录逻辑很奇怪,使用阿里云账户登陆后, 又要让我另外再建立一个账号.对仓库数目有限制,50个.可以建立私人库. 嗯,这个限制数目的态度感觉会很不待见啊

git地址
文档地址
软件地址,Windows根据目前推荐是4.0最好
识别库地址,要把根目录下的chi_sim.traineddata和chi_sim_vert.traineddata放到安装目录tessdata下,把script里面的HanS.traineddata和HanS_vert.traineddata放到tessdata\script下。还不太明白script和外面的文件的关系。
试了下,效果还行。英文效果比中文好不少。似乎中文还是贡献率太低。
用法也简单。

tesseract imagename outputbase [-l lang] [-psm pagesegmode] [configfile...]
tesseract myscan.png out
tesseract myscan.png out -l deu
tesseract myscan.png out -l eng+deu
tesseract myscan.png out -l chi_sim hocr
tesseract myscan.png out pdf

其中hocr是一个xml文件,里面有对应文字的坐标信息,应该比较适合于做自动化。
试了下,同样的图片,白底黑字比黑底白字识别率好非常多。

x = {
a:1, 
b:function (){return this.a}, // OK,可以访问,this指的是x
b(){return this.a}, //OK,上面的简写形式.
c:()=>{return this.a} //Error! 箭头函数的this似乎在上一层,x同级的一层,global.
}

之前看了太多大约都不是官方文档看得自己晕乎乎, 直到今天决心用MDN看看
使用Promise
Promise对象的构造器

const p = function(param){
  new Promise((callItWhenResolved, callItWhenRejected)=>{
    if(doSomethingOk){callItWhenResolved(resovledResultAsParam)}
    else{callItWhenRejected(rejectedResultAsParam)}
  })
}
p(Real_param).then(function callItWhenResovled(resovledResultAsParam){})

所以Promise构建的函数,具体来说就是返回一个promise对象的函数. 这个函数的主要操作完成后, 在promise对象的构造器中根据操作结果执行resolved()函数或者rejected()函数.这两个回调函数放在p().then()中定义.

async await只是Promise的语法糖.

async function af(){
  function callItWhenResovled(resovledResultAsParam){}
  callItWhenResovled(await p(Real_param)) 
}

也能合并简写为:

async function af(){
  (function callItWhenResovled(resovledResultAsParam){})(await p(Real_param)) 
}

如果callItWhenResovled已经定义过,当然又可以省却定义的过程,例如console.log

async function af(){
  console.log(await p(Real_param)) 
}

所以: await aPromiseObject,得到的是正常完成后的返回值resovledResultAsParam. 这个返回值会输入callItWhenResovled函数作为参数,并执行callItWhenResovled.
这儿特别晕的地方就是, 回调函数callItWhenResovled的参数, 表面上是aPromiseObject在await等待的返回值resovledResultAsParam, 实际上这个返回值在Promise对象构建的时候,并没有一个return resovledResultAsParam, 却是以callItWhenResovled实参的方式提供返回值的callItWhenResovled(resovledResultAsParam). 这个透过输入实参造成输出return的效果确实让人好晕.
所以async函数干脆在函数尾部使用return 返回值来替代这种回调函数(实参返回值),使得这个逻辑一下子清晰了很多. 而其返回的实质相当于return new Promise((resolved)=>{resolved(返回值)}).
而await的作用,就是进行Promise的脱壳,将一个promise对象变成其resolved返回值. await 异步函数()相当于异步函数返回的Promise对象.then(), 而某个函数(await 异步函数())相当于异步函数返回的Promise对象.then(某个函数).
这儿有个重要区别:

某个函数(await 异步函数()) //只能在async函数内使用await
异步函数返回的Promise对象.then(某个函数)  //在普通函数中也可以使用,应用范围更广些了

x={a:{b:{c:1}}}这个Object, 如果是x.a还可以写作x['a'], 然而x.a.b.c却只能写作x['a']['b']['c'], 对于深度不定的Object来说, 会比较难以引用.
一个简单的方式是用危险的eval函数, 写作eval('x.a.b.c').
那么eval又这么危险, 又推荐了比较安全Function函数:

Function('return x.a.b.c')()

否则就要更加复杂啦:

function objValue(str){
var keys = str.split('.')
var current = this
for(var key of keys){ current = current[key] }
return current
}
objValue('x.a.b.c')

lavas
js13kpwa PWA游戏
appspot 墙外
appscope

疑问

PWA能访问本地文件系统吗?
PWA能调用本地应用吗?
PWA应用能离线发布给其他人吗?

似乎PWA应用按不同商店、不同系统、不同浏览器而不同。windows商店中的 PWA应用可以作为md文件浏览器,但只能用于Win10,在Win7的Chrome中也有PWA应用,可以在桌面建立快捷方式,单怎么看都比网页快捷方式强不到哪儿去。
充满疑惑上知乎,看了这篇2019-12-17的新鲜答案后对PWA看来也是失望透顶啦!还不如微信小程序,哈哈

从PWA似乎又引出一个Flutter,看了下,能开发IOS和Android的应用。Windows看来是没戏的。只是不知道这玩意儿相比快应用又如何。

晚上下班8点多,基于一个很简单的原因:Electron的应用好几十M太大了,我想看能否有不那么臃肿的应用,我先是找到了vuido,基于vue开发的体积更小的原生应用听起来很符合我的胃口。可是,按作者说,Vuido的应用仍然有20M+,并且至今为止已经有2年没有维护了。我是想有没有1M以内的应用呢?编译完最简单的Hello World应该是在几十到几百K的大小。
微软的传统原生应用开发平台是Visual Studio,专业版本是收费的,不过这些年有免费社区版。然而,VS向来体积巨大,一个功能包动辄4~5G,一点儿也不优雅,还不如基于Electron的VScode,这可能就是所谓的历史包袱吧。
既然VScode是微软家的,我也不想要什么图形编程界面,那么有没有基于Vscode的原生应用开发方式呢?找来找去,找到了.net core。号称跨平台开发、跨平台运行。
.net core这家伙直到3.0以前都不支持桌面GUI应用,默认都是console应用!.net core最新版本是3.1,也就是才支持桌面应用不久。支持的桌面应用框架是Winforms和WPF。
那么Winforms和WPF到底哪个好呢?经过对比,发现WinForms更加古老,WPF更新些。区别是Winforms用cs文件(C#)编写界面和逻辑,而WPF用XAML(XML形式)编写界面,cs编写逻辑(还支持VB、F#)。嗯,这听起来还比较合理,对比h5和js。
然后就开始写。xaml跟HTML果然有些像的。那么,问题来了,怎么vscode预览xaml呢?答案是不行。网上有人提了个issue给.net core开发者,开发者的反馈是:基本上没有人用vscode开发WPF,大家都用VS!最后还把这个球踢给了vscode团队,然后vscode团队给这个issue标了个out of range超范围了!
我靠。
只能又下载VS。然后发现我可能两年前装了VS2017,打开后让我升级,升级包好几个G!然后又看到VS最新的版本是2019。那么嫩不能不用卸载-下载-安装就可以直接升级到VS2019呢?网上真有人问。回答是:No。说这俩是不同Channel的,如果你装了2019,机子里会同时共存两个:2017和2019,说,你还是卸载了吧!
好吧,我卸载2017。过程好慢。到半夜12点多了,还没有卸载完!第二天在搞吧!
第二天也就是今天,卸载完了。但是居然报了个错:卸载失败!赶快去安装目录看看,还好除了留着一个2017的空目录再没有什么内容了。然后就漫长等待装2019,去吃个饭先。
吃饭时再看相关文章。发现WinForm/WPF之后,还有个UWP!这货支持HTML+JS!再看WPF,似乎近多年以来微软都没有再怎么在WPF上使劲儿,开发者对此还多有怨言。那就转向UWP?
然而,问题又来了:1、UWP只支持Win10;2、应用要上Windows商店。额,UWP有些耳熟,我记得是不是已经相当于阵亡状态,只是微软秘不发丧?查了下相关报道,还真是个这样!
UWP几乎已死WPF又上不来这怎么搞?况且UWP就算没死还不支持Win7也不是办法。这时候有人说,有个叫Xaml island的东西,可以在WPF框架里放UWP!不知道这个是不是救星。
另外,微软在放弃UWP、WPF之后,又搞了个PWA,不知道是什么东西,能不能用呢?

原意是通过vscode快速开发一个Windows GUI。 不想用electron的原因是electron打包出来的app太大。
通过框架选择,似乎只有.net core适合vscode。又发现.net core3.1只支持WinForms和WPF两种GUI框架。
通过对比,WPF似乎是更先进的。查看代码发现WPF中xaml类似HTML布局的作用,.cs写代码,而Winforms用一个cs文件写布局另一个cs文件写逻辑……不喜欢。还是WPF符合我的要求。
接着开始写xaml。这玩意儿写布局总得有个预览吧。HTML直接用任何一个浏览器打开看就行了。xaml呢?能不能在Vscode中编辑?搜索了下,真有人问了这个问题,然而回答却是残酷的:

I like the idea of a XAML editor in VS Code. But honestly all WPF and WinForms developers I know use Visual Studio. And as WPF and WinForms in .NET Core are still Windows-only UI stacks, there's no reason why you shouldn't use Visual Studio. But for cross-platform stuff it would make sense, yes. And for those who want to use VSCode for everything. :)
我喜欢VS Code中的XAML编辑器的想法。但老实说,我认识的所有WPF和WinForms开发人员都使用Visual Studio。而且由于.NET Core中的WPF和WinForms仍然是仅Windows的UI堆栈,因此没有理由不应该使用Visual Studio。但是对于跨平台的东西,这是有道理的,是的。对于那些想要对所有内容使用VSCode的人。:)

.net core

中文指南

C

中文指南
类型|JS|C#
--|--
整数| |int
浮点| |double
固定点| | demical

foreach(x in xs){}

WPF

中文指南
学习H5架构的原生Windows应用架构

要用到高级功能呢,呵呵, 看看百度经验

主要是:
1 连同标题行选择数据区域后, 选择数据-排序与筛选-高级命令. 如按关键字段筛选, 只选择关键字段列就好.
2 对话框中, 列表区域选择单列的话,只会以单列计算, 选择多列的话, 多列之间是"与"的关系.
3 勾选选择不重复的记录, 确定.

var exec = require('child_process').execSync;
var cmd = "echo 'hello world'";

var options = {
  encoding: 'utf8'
};

console.log(exec(cmd, options));

今天装Canon G5800打印机驱动时候忽然给我把我自己的Wifi密码全列出来了, 让我很震撼,哈哈

Windows

  1. 输入 netsh wlan show profile 获取本机已保存的wifi SSID
  2. 3.输入 netsh wlan show profile name=“ ” key=clear 获取密码 name里写入WiFi SSID

Github上有个WIFIpass项目可以用Python一键获取,不过我觉得批处理应该也可以有类似效果. 果然在这个网址找到了bat的方式, 试了下,只适用于英文版Windows,中文的要修改下. 代码如下:

@echo off
::
:: (c) Elias Bachaalany <lallousz-x86@yahoo.com>
:: Batchography: The Art of Batch Files Programming
::
setlocal enabledelayedexpansion
:main
    title WiFiPasswordReveal v1.0 (c) lallouslab.net - The Batchography book

    echo.
    echo Reveal all saved WiFi passwords Batch file script v1.0 (c) lallouslab.net
    echo.
    echo Inspired by the book "Batchography: The Art of Batch Files Programming"
    echo.
    :: Get all the profiles
    call :get-profiles r
    :: For each profile, try to get the password
    :main-next-profile
        for /f "tokens=1* delims=," %%a in ("%r%") do (
            call :get-profile-key "%%a" key
            if "!key!" NEQ "" (
               >>"C:\WiFi-Passwords.txt" echo WiFi: [%%a] Password: [!key!]
            )
            set r=%%b
        )
        if "%r%" NEQ "" goto main-next-profile
    echo.
    pause
    goto :eof
::
:: Get the WiFi key of a given profile
:get-profile-key <1=profile-name> <2=out-profile-key>
    setlocal
    set result=
    FOR /F "usebackq tokens=2 delims=:" %%a in (
        `netsh wlan show profile name^="%~1" key^=clear ^| findstr /C:"Key Content"`) DO (
        set result=%%a
        set result=!result:~1!
    )
    (
        endlocal
        set %2=%result%
    )
    goto :eof
::
:: Get all network profiles (comma separated) into the result result-variable
:get-profiles <1=result-variable>
    setlocal
    set result=

    FOR /F "usebackq tokens=2 delims=:" %%a in (
        `netsh wlan show profiles ^| findstr /C:"All User Profile"`) DO (
        set val=%%a
        set val=!val:~1!
        set result=%!val!,!result!
    )
    (
        endlocal
        set %1=%result:~0,-1%
    )
        goto :eof