获取微信小程序的源代码

微信在去年年底已经发布了小程序的游戏,引起了大家的关注,而且现在已经有达人破解了里面的算法,也顺带破解了微信小程序的机制。如何下载小程序我找了几个月了没有方案,这回被大牛破解了,赶紧记录一下

找到小程序的ID

先用fiddler进行截包,在里面找到微信小程序的ID,以跳一跳为例

跳一跳的请求头里面包含如下的信息:

https://servicewechat.com/wx7c8d593b2c3a7703/5/page-frame.html

其中 wx7c8d593b2c3a7703就是我们要找的小程序ID,后面跟着的5为版本号,可以理解为发布了5次,这两个都需要

拼接实际地址

找到ID后我们根据实际的下载地址,拼接相应的下载链接

https://servicewechat.com/weapp/release/{appid}/{version_num}.wxapkg

跳一跳的地址拼接后如下:

https://servicewechat.com/weapp/release/wx7c8d593b2c3a7703/5.wxapkg

下载后需要对包进行解压

git地址如下:

https://github.com/thedreamwork/unwxapkg

这个代码是python2的,3要修改print和在data.name后加decode(‘utf-8’)将byte转化成字符串

解压完成后就是源代码了

参考资料

https://www.v2ex.com/t/419056

https://www.v2ex.com/t/419352

参考资料里面有直接在IOS和android的微信中找wxapkg的方法,十分实用

从Win服务启动UI程序

从windows服务启动一个带UI程序的界面,这个需求在xp中是很随意的,从Vista开始似乎没有那么随意了,因为Vista中加入了Session的概念,那么什么是Session,我想这篇文章介绍的应该比我权威的多。Session隔离介绍

明白了Session的概念后,我将通过Win32 API来实现从windows服务启动一个带UI的界面(从Session 0中启动Session *的程序),这个实现过程是我从C++代码翻译过来的。

实现的思路

  1. 找到一个除Session 0之外的活动Session
  2. 通过Session ID获取用户Token
  3. 通过Token来启动UI程序

涉及的Win32 API

  1. WTSGetActiveConsoleSessionId获取活动的Session ID
  2. WTSQueryUserToken根据Session ID获取用户Token
  3. CreateProcessAsUser使用用户Token来启动UI程序
public class ProcessAsUser
{
    public struct SECURITY_ATTRIBUTES
    {
        public uint nLength;
        public uint lpSecurityDescriptor;
        public bool bInheritHandle;
    }

    public struct STARTUPINFO
    {
        public uint cb;
        public string lpReserved;
        public string lpDesktop;
        public string lpTitle;
        public uint dwX;
        public uint dwY;
        public uint dwXSize;
        public uint dwYSize;
        public uint dwXCountChars;
        public uint dwYCountChars;
        public uint dwFillAttribute;
        public uint dwFlags;
        public ushort wShowWindow;
        public ushort cbReserved2;
        public IntPtr lpReserved2;
        public IntPtr hStdInput;
        public IntPtr hStdOutput;
        public IntPtr hStdError;

    }
    public struct PROCESS_INFORMATION
    {
        public IntPtr hProcess;
        public IntPtr hThread;
        public uint dwProcessId;
        public uint dwThreadId;

    }

    [DllImport("kernel32.dll")]
    static extern uint WTSGetActiveConsoleSessionId();

    [DllImport("Wtsapi32.dll")]
    private static extern bool WTSQueryUserToken(uint SessionId, out uint hToken);

    [DllImport("Kernel32.dll")]
    private static extern uint GetLastError();

    [DllImport("kernel32.dll")]
    private static extern bool CloseHandle(IntPtr hSnapshot);

    [DllImport("advapi32.dll")]
    public extern static bool CreateProcessAsUser(IntPtr hToken,
                                            string lpApplicationName,
                                            string lpCommandLine,
                                            ref SECURITY_ATTRIBUTES lpProcessAttributes,
                                            ref SECURITY_ATTRIBUTES lpThreadAttributes,
                                            bool bInheritHandle,
                                            uint dwCreationFlags,
                                            uint lpEnvironment,
                                            string lpCurrentDirectory,
                                            ref STARTUPINFO lpStartupInfo,
                                            out PROCESS_INFORMATION lpProcessInformation);

    public static bool StartUIProcessFromService(string exePath)
    {
        //获取Session ID
        var sId=WTSGetActiveConsoleSessionId();
        if (sId == 0)
        {
            return false;
        }
        uint hToken;
        var isOk=WTSQueryUserToken(sId, out hToken);
        if (!isOk || hToken == 0)
        {
            return false;
        }
        var lpProcessAttr = new SECURITY_ATTRIBUTES();
        lpProcessAttr.nLength = (uint)Marshal.SizeOf(lpProcessAttr);

        var lpThreadAttr = new SECURITY_ATTRIBUTES();
        lpThreadAttr.nLength = (uint)Marshal.SizeOf(lpThreadAttr);

        var lpStratupInfo = new STARTUPINFO();
        lpStratupInfo.cb = (uint)Marshal.SizeOf(lpStratupInfo);
        lpStratupInfo.lpDesktop = @"winsta0\default";

        PROCESS_INFORMATION lpProcessInfo;
        isOk=CreateProcessAsUser((IntPtr)hToken,
                                    exePath,
                                    null,
                                    ref lpProcessAttr,
                                    ref lpThreadAttr,
                                    false,
                                    0,
                                    0,
                                    null,
                                    ref lpStratupInfo,
                                    out lpProcessInfo
                                );
        CloseHandle((IntPtr)hToken);
        return isOk;            
    }    
}
 

枚举活动Session ID

之前我们通过WTSGetActiveConsoleSessionId获取活动Session ID,当有多个用户登录时,Windows提供了WTSEnumerateSessions方法枚举多个Session ID。

主要涉及API

  1. WTSEnumerateSessions 检索在远程桌面会话主机 (RD 会话主机) 服务器上的会话的列表。
  2. WTSFreeMemory 释放由远程桌面服务函数分配的内存。

实现代码

[DllImport("Wtsapi32.dll")]
private static extern void WTSFreeMemory(IntPtr pSessionInfo);

[DllImport("Wtsapi32.dll")]
private extern static bool WTSEnumerateSessions(IntPtr hServer, uint reserved, uint version, out IntPtr ppSessionInfo, out uint pCount);
struct WTS_SESSION_INFO
{
    public uint SessionId;
    public string pWinStationName;
    public WTS_CONNECTSTATE_CLASS State;
}

enum WTS_CONNECTSTATE_CLASS
{
    WTSActive,
    WTSConnected,
    WTSConnectQuery,
    WTSShadow,
    WTSDisconnected,
    WTSIdle,
    WTSListen,
    WTSReset,
    WTSDown,
    WTSInit
}

private static uint EnumerateActiveSession()
{
    uint dwSessionID = 0xFFFFFFFF;
    uint dwCount = 0;
    IntPtr intPtr = IntPtr.Zero;
    try
    {
        IntPtr hServer = IntPtr.Zero;
        if (WTSEnumerateSessions(hServer, 0, 1, out intPtr, out dwCount))
        {
            var tmp = intPtr;
            for (var i = 0; i < dwCount; ++i)
            {
                var pSessionInfo = (WTS_SESSION_INFO)Marshal.PtrToStructure(tmp, typeof(WTS_SESSION_INFO));

                if (WTS_CONNECTSTATE_CLASS.WTSActive == pSessionInfo.State)
                {
                    dwSessionID = pSessionInfo.SessionId;
                    break;
                }
                if (WTS_CONNECTSTATE_CLASS.WTSConnected == pSessionInfo.State)
                {
                    dwSessionID = pSessionInfo.SessionId;
                }
                tmp += Marshal.SizeOf(typeof(WTS_SESSION_INFO));
            }
            WTSFreeMemory(intPtr);
        }
        var eCode = GetLastError();
    }
    catch (Exception ex)
    {
        var eCode = GetLastError();
    }
    return dwSessionID;
}

 

 

Excel工作表保护密码破解

去除Excel工作表保护密码

  1. 打开需要破解密码的Excel;
  2. Alt+F11,进入VBA编辑界面;
  3. 插入 -- 模块(Module);
  4. 在右边Module的空白编辑区域,复制粘贴下面所有内容;
  5. F5,运行该VBA命令;
Option Explicit

Public Sub AllInternalPasswords()
' Breaks worksheet and workbook structure passwords. Bob McCormick
' probably originator of base code algorithm modified for coverage
' of workbook structure / windows passwords and for multiple passwords
'
' Norman Harker and JE McGimpsey 27-Dec-2002 (Version 1.1)
' Modified 2003-Apr-04 by JEM: All msgs to constants, and
' eliminate one Exit Sub (Version 1.1.1)
' Reveals hashed passwords NOT original passwords
Const DBLSPACE As String = vbNewLine & vbNewLine
Const AUTHORS As String = DBLSPACE & vbNewLine & _
"Adapted from Bob McCormick base code by" & _
"Norman Harker and JE McGimpsey"
Const HEADER As String = "AllInternalPasswords User Message"
Const VERSION As String = DBLSPACE & "Version 1.1.1 2003-Apr-04"
Const REPBACK As String = DBLSPACE & "Please report failure " & _
"to the microsoft.public.excel.programming newsgroup."
Const ALLCLEAR As String = DBLSPACE & "The workbook should " & _
"now be free of all password protection, so make sure you:" & _
DBLSPACE & "SAVE IT NOW!" & DBLSPACE & "and also" & _
DBLSPACE & "BACKUP!, BACKUP!!, BACKUP!!!" & _
DBLSPACE & "Also, remember that the password was " & _
"put there for a reason. Don't stuff up crucial formulas " & _
"or data." & DBLSPACE & "Access and use of some data " & _
"may be an offense. If in doubt, don't."
Const MSGNOPWORDS1 As String = "There were no passwords on " & _
"sheets, or workbook structure or windows." & AUTHORS & VERSION
Const MSGNOPWORDS2 As String = "There was no protection to " & _
"workbook structure or windows." & DBLSPACE & _
"Proceeding to unprotect sheets." & AUTHORS & VERSION
Const MSGTAKETIME As String = "After pressing OK button this " & _
"will take some time." & DBLSPACE & "Amount of time " & _
"depends on how many different passwords, the " & _
"passwords, and your computer's specification." & DBLSPACE & _
"Just be patient! Make me a coffee!" & AUTHORS & VERSION
Const MSGPWORDFOUND1 As String = "You had a Worksheet " & _
"Structure or Windows Password set." & DBLSPACE & _
"The password found was: " & DBLSPACE & "$$" & DBLSPACE & _
"Note it down for potential future use in other workbooks by " & _
"the same person who set this password." & DBLSPACE & _
"Now to check and clear other passwords." & AUTHORS & VERSION
Const MSGPWORDFOUND2 As String = "You had a Worksheet " & _
"password set." & DBLSPACE & "The password found was: " & _
DBLSPACE & "$$" & DBLSPACE & "Note it down for potential " & _
"future use in other workbooks by same person who " & _
"set this password." & DBLSPACE & "Now to check and clear " & _
"other passwords." & AUTHORS & VERSION
Const MSGONLYONE As String = "Only structure / windows " & _
"protected with the password that was just found." & _
ALLCLEAR & AUTHORS & VERSION & REPBACK
Dim w1 As Worksheet, w2 As Worksheet
Dim i As Integer, j As Integer, k As Integer, l As Integer
Dim m As Integer, n As Integer, i1 As Integer, i2 As Integer
Dim i3 As Integer, i4 As Integer, i5 As Integer, i6 As Integer
Dim PWord1 As String
Dim ShTag As Boolean, WinTag As Boolean

Application.ScreenUpdating = False
With ActiveWorkbook
WinTag = .ProtectStructure Or .ProtectWindows
End With
ShTag = False
For Each w1 In Worksheets
ShTag = ShTag Or w1.ProtectContents
Next w1
If Not ShTag And Not WinTag Then
MsgBox MSGNOPWORDS1, vbInformation, HEADER
Exit Sub
End If
MsgBox MSGTAKETIME, vbInformation, HEADER
If Not WinTag Then
MsgBox MSGNOPWORDS2, vbInformation, HEADER
Else
On Error Resume Next
Do 'dummy do loop
For i = 65 To 66: For j = 65 To 66: For k = 65 To 66
For l = 65 To 66: For m = 65 To 66: For i1 = 65 To 66
For i2 = 65 To 66: For i3 = 65 To 66: For i4 = 65 To 66
For i5 = 65 To 66: For i6 = 65 To 66: For n = 32 To 126
With ActiveWorkbook
.Unprotect Chr(i) & Chr(j) & Chr(k) & _
Chr(l) & Chr(m) & Chr(i1) & Chr(i2) & _
Chr(i3) & Chr(i4) & Chr(i5) & Chr(i6) & Chr(n)
If .ProtectStructure = False And _
.ProtectWindows = False Then
PWord1 = Chr(i) & Chr(j) & Chr(k) & Chr(l) & _
Chr(m) & Chr(i1) & Chr(i2) & Chr(i3) & _
Chr(i4) & Chr(i5) & Chr(i6) & Chr(n)
MsgBox Application.Substitute(MSGPWORDFOUND1, _
"$$", PWord1), vbInformation, HEADER
Exit Do 'Bypass all for...nexts
End If
End With
Next: Next: Next: Next: Next: Next
Next: Next: Next: Next: Next: Next
Loop Until True
On Error GoTo 0
End If
If WinTag And Not ShTag Then
MsgBox MSGONLYONE, vbInformation, HEADER
Exit Sub
End If
On Error Resume Next
For Each w1 In Worksheets
'Attempt clearance with PWord1
w1.Unprotect PWord1
Next w1
On Error GoTo 0
ShTag = False
For Each w1 In Worksheets
'Checks for all clear ShTag triggered to 1 if not.
ShTag = ShTag Or w1.ProtectContents
Next w1
If ShTag Then
For Each w1 In Worksheets
With w1
If .ProtectContents Then
On Error Resume Next
Do 'Dummy do loop
For i = 65 To 66: For j = 65 To 66: For k = 65 To 66
For l = 65 To 66: For m = 65 To 66: For i1 = 65 To 66
For i2 = 65 To 66: For i3 = 65 To 66: For i4 = 65 To 66
For i5 = 65 To 66: For i6 = 65 To 66: For n = 32 To 126
.Unprotect Chr(i) & Chr(j) & Chr(k) & _
Chr(l) & Chr(m) & Chr(i1) & Chr(i2) & Chr(i3) & _
Chr(i4) & Chr(i5) & Chr(i6) & Chr(n)
If Not .ProtectContents Then
PWord1 = Chr(i) & Chr(j) & Chr(k) & Chr(l) & _
Chr(m) & Chr(i1) & Chr(i2) & Chr(i3) & _
Chr(i4) & Chr(i5) & Chr(i6) & Chr(n)
MsgBox Application.Substitute(MSGPWORDFOUND2, _
"$$", PWord1), vbInformation, HEADER
'leverage finding Pword by trying on other sheets
For Each w2 In Worksheets
w2.Unprotect PWord1
Next w2
Exit Do 'Bypass all for...nexts
End If
Next: Next: Next: Next: Next: Next
Next: Next: Next: Next: Next: Next
Loop Until True
On Error GoTo 0
End If
End With
Next w1
End If
MsgBox ALLCLEAR & AUTHORS & VERSION & REPBACK, vbInformation, HEADER
End Sub

 

树莓派+Win10 iot跑NetCore2网站

前期准备

  1. 一个树莓派刷上最新的Win10 iot 15063系统
  2. 一个NetCore2的网站,能在PC上正常运行就可以了

PS:如何刷Win10 iot系统和如何创建Asp.Net Core网站不在本文的讨论范围,请自行百度

网站发布

运行指令

dotnet publish -c release -r win-arm

然后把红线部分的内容复制到树莓派上

这里可以通过文件共享复制

\\192.168.99.147\c$\

PS:192.168.99.147是我树莓派的ip

然后登录到树莓派的PowerShell(可通过 Iot Dashboard 上的 我的设备 右键 找到)

运行指令,开放防火墙端口

netsh advfirewall firewall add rule name="NetCore2 APP" dir=in action=allow protocol=TCP localport=5001

默认端口是5000,我这里项目中修改成5001

然后运行

cd C:\Web
.\WeChat.exe

WeChat是我的项目名,需要自行替换成自己的

最终效果

备孕饮食宜忌

备孕是为了优孕,也就是生出一个健康的宝宝,在备孕阶段你的身体素质会直接影响到下一代的身体素质,所以大家一定得上心,让我们来看看备孕期间都有哪些饮食宜忌吧。
女性要多补充富含叶酸的食物,含叶酸较多的食物有动物肝脏、肾脏、蛋类、鱼类等,还有芹菜、菠菜、生菜、芦笋、油菜、小白菜等,水果类则有梨、柑橘、香蕉、柠檬、草莓、橙子等,坚果也是富含叶酸的食物。
男性要让精子更有活力,可以多吃富含锌的食物,可以增强精子的活动能力,锌元素主要存在于海产品、动物内脏中,豆类、花生、小米、萝卜、大白菜等也是补锌食物。
蛋白质和矿物质、维生素都是需要在备孕期间加强补充的,这类食物有牛奶、鸡蛋、肉类、豆类和动物内脏等,另外新鲜的水果蔬菜一定要多吃,可以帮助补充维生素。
备孕期的饮食也要注意以下这些禁忌:
  1. 不吃腌制食物。腌制的食物中含有较多的亚硝酸盐,不仅损害身体,还对孕妇不利,可能会导致流产、早产等情况,所以在备孕期尽量不要吃。
  2. 不吃烧烤。烧烤会减少蛋白质的利用率,影响氨基酸摄入,这些都是备孕阶段十分需要的营养物质,所以要忌嘴。
  3. 不吃高糖食物。大量的糖分会增加孕妇糖尿病的几率,怀孕后就知道它的严重性了。
  4. 不吃辛辣食物。辛辣的食物会产生胃部不适,影响备孕期身体素质。
  5. 少喝咖啡。一天一杯以上的咖啡是可能会降低怀孕几率的。
  6. 男性不吃大蒜、芹菜。大蒜、芹菜会降低精子活力,所以男性在备孕期间要忌口。

双机热备软件Rose HA日常维护技巧

  (一)双机热备软件Rose HA相关命令
 
  查询 Roseha 进程的命令: #ps –ef | grep ha
 
  hasvrd hamond
 
  停止 Roseha 进程的命令:#ha_kill ha
 
  手工启动 Roseha 进程的命令:#hamond 或者 #/opt/rose/Roseha start
 
  进入 Roseha 软件字符管理工具的命令:#hacon
 
  进入 Roseha 软件图形管理工具的命令:#gui.sh
 
  (二)双机热备软件的开关机顺序
 
  开机:先后依次开磁盘阵列,主机,备机。
 
  关机:先后依次关备机,主机,磁盘阵列。
 
  (三)双机热备软件中的术语:
 
  Bring in: 把服务带入双机,受双机软件管理。
 
  Bring out: 把服务带出双机,不受双机软件管理。
 
  Take over:手工切换服务。在备机动作,来接管主机服务。
 
  Fail over: 手工切换服务。在主机动作,来提交主机服务给备机。
 
  (四)双机热备软件常见问题及解决办法
 
  (1)如果开关机不当,有可能造成数据库无法使用
 
  解决办法:进入双机软件配置界面进到 Services—Bring in,选中此 job,点 yes 即可。只需在任意一台机器上操作即可。
 
  (2)交换机断电,交换机恢复正常后,数据库不可用
 
  解决办法:同上
 
  (3) 进入双机软件图形化界面时,无法连接.
 
  解决办法:看是否双机软件字符界面也开着,关闭它既可.(双机软件的字符界面和图形化界面不能同时存在.)
 
  (4)两台服务器上的双机软件启动后,而双机两边的资源都处于虚状态怎么办?
 
  解决办法: 在工作机上将资源一一点中,使资源处于高亮状态,点击工具栏上的 bring in 按钮。
 
  (5)当工具栏的“ takeover”, “ failover”, “bring in”, “bring out” 等快捷按 钮均为不可用。主备机的状态保持不变,提示“ the public net is functioning, but all instances of private net are down or unavailable.”
 
  解决办法:如果在“ private net ”界面下心跳线变为红色,检查心跳是否连接正常。
 
  (6)没有选择 Auto-Switch Back 开关时,关机后 先启 关机前为备机状态的 Host ,后启 关机前为主机状态的 Host 。会出现什么情况?
 
  解决办法: 先启的 Host 成为主机,后启的 Host 成为备机。
 
  (7)两台 Host 均是在本地机上启动 ROSE HA 双机,启动双机时无法启动,并出现报错“ Fail to get remote Server's IP address from the registry ”。以上情况如何处理?
 
  解决办法: 以上情��是由于两台服务器上的 Administrator 的密码不相同而造成的, 将两台服务器的 Administrator 密码改为一样,重新登录即可。

VsCode离线配置OmniSharp

环境的安装

第一步你要安装一个vscode

如果网速不给力,可以使用百度云的离线下载,然后再下载到本机安装。

第二步安装.Net Core运行环境和客户端命令

请移步dot.net站点下载.Net Core编译运行环境

第三步安装OmniSharp

在线安装在线安装方法
离线安装vsix文件安装

最后安装OmniSharp智能提示+Debugger

这一步是最慢的因为要联网下载OmniSharp和Debugger,如果网速不好的童鞋请按照如下方式安装:
打开vscode扩展安装目录中的c:\users*.vscode\extensions\ms-vscode.csharp-..\package.json文件找到下图中的url进行下载:* 这个runtimeDependencies节点包涵了所有类型的系统的智能提示Debugger工具,因为我使用的是windows,所以我需要下载了这两个工具:

  1. 智能提示:https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-win-x86-1.9-beta22.zip
    解压到C:\Users**.vscode\extensions\ms-vscode.csharp-..\bin\omnisharp目录中即可
  2. Debugger:https://vsdebugger.azureedge.net/coreclr-debug-1-6-3/coreclr-debug-win7-x64.zip
    解压到C:\Users**.vscode\extensions\ms-vscode.csharp-...debugger目录中即可
  3. 最后创建C:\Users**.vscode\extensions\ms-vscode.csharp-..\install.LOCK空文本文件即可

LBS位置服务的SQL实现原理以及SQL代码

一、位置服务(搜索周边商家POI)

  1. 自身有海量的周边搜索数据,并且一定要有经纬度坐标;(数据来源可以从网上购买,如果要直接从地图API中获取,那是要付费的,而且费用不菲)
  2. 手机定位后将经纬度发送给服务器,服务器根据经纬度在数据库中匹配数据,并按照距离由近到远排序(此处省略一万字...)

SQL实现经纬度匹配以及距离排序代码

1、SQL计算经纬度距离的自定义函数

CREATE FUNCTION dbo.GetDistance  
(  
    @LatBegin REAL  
    , @LngBegin REAL  
    , @LatEnd REAL  
    , @LngEnd REAL  
)  
RETURNS FLOAT  
AS  
BEGIN  
    DECLARE @Distance REAL  
    DECLARE @EARTH_RADIUS REAL  
    SET @EARTH_RADIUS = 6378.137  
      
    DECLARE @RadLatBegin REAL, @RadLatEnd REAL, @RadLatDiff REAL, @RadLngDiff REAL  
    SET @RadLatBegin = @LatBegin * PI() / 180.0  
    SET @RadLatEnd = @LatEnd * PI() / 180.0  
    SET @RadLatDiff = @RadLatBegin - @RadLatEnd  
    SET @RadLngDiff = @LngBegin * PI() / 180.0 - @LngEnd * PI() / 180.0  
      
    SET @Distance = 2 * ASIN(SQRT(POWER(Sin(@RadLatDiff / 2), 2) + COS(@RadLatBegin) * COS(@RadLatEnd) * POWER(SIN(@RadLngDiff/2),2)))  
    SET @Distance = @Distance * @EARTH_RADIUS  
    --SET @Distance = Round(@Distance * 10000) / 10000  
      
    RETURN @Distance * 1000  
END  

2、获取周边数据的存储过程

CREATE PROCEDURE Up_Data_GetPOI 
	@lngbegin nvarchar(50), --当前经度
	@latbegin nvarchar(50), --当前纬度
	@distance int, --搜索半径,单位为米
	@WhereStr nvarchar(200) --附加搜索条件,如and 1=2 
	AS
	declare @SqlStr nvarchar(2000)
	
	set @SqlStr='select *, dbo.GetDistance('+@latbegin+','+@lngbegin+',纬度字段,经度字段) as distance from [存储商家的数据表名] where (纬度字段<>'' and 经度字段<>'') and dbo.GetDistance('+@latbegin+','+@lngbegin+',纬度字段,经度字段)<'+Convert(nvarchar(10),@distance)+' '+@WhereStr+' order by distance asc'
	
	--print @SqlStr
	Execute Sp_ExecuteSql @SqlStr
GO

二、位置交友

  1. 要有会员数据,同样也得有客户端是否在线以及经纬度的字段(不一定要获取到经纬度,默认为空)
  2. 手机客户端定位后,更新该会员的经纬度坐标以及客户端在线状态
  3. 通过上面的SQL代码即可实现数据列表,只要输出JSON/XML给手机客户端解析即可

.Net Core使用GB2312编码

.Net Core默认是UTF8编码,但有些时候需要使用GB2312编码

Encoding.GetEncoding("GB2312")

但代码运行时候会报错误

No data is available for encoding 936.

这时需要引用Nuget包

System.Text.Encoding.CodePages 4.3.0

再在 Startup 的构造函数中加上一行代码

Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);