调用windows系统动态库实现wifi连接及问题

2023-05-16

有个项目是c#做的, 有个需求是程序启动自动连接指定wifi,想到windows有个系统库支持,就用c++调的系统库,然后c#再调c++封装好的接口,比较简单,先上代码

c++动态库部分

静态调用的时候好像有问题,没细琢磨,就直接改用动态加载了

.h

#pragma once

#include <wlanapi.h>
#pragma comment(lib,"wlanapi.lib")
#pragma comment(lib,"ole32.lib")

typedef int WINBOOL;

typedef DWORD(WINAPI* pfnWlanGetAvailableNetworkList)(
	HANDLE hClientHandle,
	const GUID* pInterfaceGuid,
	DWORD dwFlags,
	PVOID pReserved,
	PWLAN_AVAILABLE_NETWORK_LIST* ppAvailableNetworkList
	);

typedef DWORD(WINAPI* pfnWlanOpenHandle)(
	DWORD dwClientVersion,
	PVOID pReserved,
	PDWORD pdwNegotiatedVersion,
	PHANDLE phClientHandle
	);

typedef DWORD(WINAPI* pfnWlanEnumInterfaces)(
	HANDLE hClientHandle,
	PVOID pReserved,
	PWLAN_INTERFACE_INFO_LIST* ppInterfaceList
	);

typedef DWORD(WINAPI* pfnWlanQueryInterface)(
	HANDLE hClientHandle,
	const GUID* pInterfaceGuid,
	WLAN_INTF_OPCODE OpCode,
	PVOID pReserved,
	PDWORD pdwDataSize,
	PVOID* ppData,
	PWLAN_OPCODE_VALUE_TYPE pWlanOpcodeValueType
	);

typedef DWORD(WINAPI* pfnWlanSetProfile)(
	HANDLE hClientHandle,
	const GUID* pInterfaceGuid,
	DWORD dwFlags,
	LPCWSTR strProfileXml,
	LPCWSTR strAllUserProfileSecurity,
	WINBOOL bOverwrite,
	PVOID pReserved,
	DWORD* pdwReasonCode
	);

typedef DWORD(WINAPI* pfnWlanSetInterface)(
	HANDLE hClientHandle,
	const GUID* pInterfaceGuid,
	WLAN_INTF_OPCODE OpCode,
	DWORD dwDataSize,
	const PVOID pData,
	PVOID pReserved
	);

typedef DWORD (WINAPI* pfnWlanConnect)(
	HANDLE hClientHandle,
	const GUID* pInterfaceGuid,
	const PWLAN_CONNECTION_PARAMETERS pConnectionParameters,
	PVOID pReserved
	);

typedef DWORD (WINAPI* pfnWlanDisconnect)(
	_In_ HANDLE hClientHandle,
	_In_ CONST GUID* pInterfaceGuid,
	_Reserved_ PVOID pReserved
);

typedef DWORD (WINAPI* pfnWlanCloseHandle)(
	_In_ HANDLE hClientHandle,
	_Reserved_ PVOID pReserved
);

typedef VOID (WINAPI* pfnWlanFreeMemory)(
	_In_ PVOID pMemory
);

class exportDLl
{
public:
	static exportDLl* m_pInstance;
	static exportDLl* getInstance();

public:
	bool pLoadLibrary();
	void pReleaseLibrary();
	int pFindWifi(const char* sWifiName);
	int connect(const char* sXmlName);
private:
	bool wifiInit();
	int isConnect(const char* sWifiName);
private:
	pfnWlanGetAvailableNetworkList fnWlanGetAvailableNetworkList = nullptr;
	pfnWlanOpenHandle fnWlanOpenHandle = nullptr;
	pfnWlanEnumInterfaces fnWlanEnumInterfaces = nullptr;
	pfnWlanQueryInterface fnWlanQueryInterface = nullptr;
	pfnWlanSetProfile fnWlanSetProfile = nullptr;
	pfnWlanSetInterface fnWlanSetInterface = nullptr;
	pfnWlanConnect  fnWlanConnect = nullptr;
	pfnWlanDisconnect fnWlanDisconnect = nullptr;
	pfnWlanCloseHandle fnWlanCloseHandle = nullptr;
	pfnWlanFreeMemory fnWlanFreeMemory = nullptr;


	HMODULE hDll = nullptr;

	HANDLE hClient = NULL;
	DWORD dwMaxClient = 2;
	DWORD dwCurVersion = 0;
	DWORD dwResult = 0;
	PWLAN_CONNECTION_ATTRIBUTES pConnectInfo = NULL;
	DWORD connectInfoSize = sizeof(WLAN_CONNECTION_ATTRIBUTES);
	WLAN_OPCODE_VALUE_TYPE opCode = wlan_opcode_value_type_invalid;
	PWLAN_INTERFACE_INFO pIfInfo = NULL;
	PWLAN_INTERFACE_INFO_LIST pIfList = NULL;

	bool m_bisLoad = false;
};


extern "C"
{
	__declspec(dllexport) bool pLoadLibrary();
	__declspec(dllexport) int pFindWifi(const char* path);
	__declspec(dllexport) int connect(const char* filename);
}



.cpp

#include "pch.h"
#include "exportDLl.h"
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
using namespace std;

static string string_to_hex(const string& str)
{
    string result = "";
    string tmp;
    std::stringstream ss;
    for (int i = 0; i < str.size(); i++)
    {
        ss << hex << int(str[i]) << endl;
        ss >> tmp;
        result += tmp;
    }
    return result;
}
static LPCWSTR StringToLPCWSTR(std::string orig)
{
    size_t origsize = orig.length() + 1;
    const size_t newsize = 100;
    size_t convertedChars = 0;
    wchar_t* wcstring = (wchar_t*)malloc(sizeof(wchar_t) * (orig.length() - 1));
    mbstowcs_s(&convertedChars, wcstring, origsize, orig.c_str(), _TRUNCATE);
    return wcstring;
}


static void LPCWSTRToString(std::string& szDst, wchar_t* wchar)
{
    wchar_t* wText = wchar;
    DWORD dwNum = WideCharToMultiByte(CP_OEMCP, NULL, wText, -1, NULL, 0, NULL, FALSE);// WideCharToMultiByte的运用
    char* psText; // psText为char*的临时数组,作为赋值给std::string的中间变量
    psText = new char[dwNum];
    WideCharToMultiByte(CP_OEMCP, NULL, wText, -1, psText, dwNum, NULL, FALSE);// WideCharToMultiByte的再次运用
    szDst = psText;// std::string赋值
    delete[]psText;// psText的清除
}

exportDLl* exportDLl::m_pInstance = nullptr;
exportDLl* exportDLl::getInstance()
{
    if (!m_pInstance)
    {
        m_pInstance = new exportDLl;
    }
    return m_pInstance;
}


bool pLoadLibrary()
{
    return exportDLl::getInstance()->pLoadLibrary();
}

int pFindWifi(const char* sWifiName)
{
    return exportDLl::getInstance()->pFindWifi(sWifiName);
}

int connect(const char* filename)
{
    return exportDLl::getInstance()->connect(filename);
}

//加载wlanapi.dll系统动态库
bool exportDLl::pLoadLibrary()
{    
    if (m_bisLoad)
    {
        return true;
    }
    if (hDll == nullptr)
    {
        hDll = LoadLibraryA("wlanapi.dll");
    }
    else
    {
        return true;
    }

    if (hDll == nullptr)
    {
        m_bisLoad = false;
        return false;
    }

    fnWlanGetAvailableNetworkList = (pfnWlanGetAvailableNetworkList)GetProcAddress(hDll, "WlanGetAvailableNetworkList");
    fnWlanOpenHandle = (pfnWlanOpenHandle)GetProcAddress(hDll, "WlanOpenHandle");
    fnWlanEnumInterfaces = (pfnWlanEnumInterfaces)GetProcAddress(hDll, "WlanEnumInterfaces");
    fnWlanQueryInterface = (pfnWlanQueryInterface)GetProcAddress(hDll, "WlanQueryInterface");
    fnWlanSetProfile = (pfnWlanSetProfile)GetProcAddress(hDll, "WlanSetProfile");
    fnWlanSetInterface = (pfnWlanSetInterface)GetProcAddress(hDll, "WlanSetInterface");
    fnWlanConnect = (pfnWlanConnect)GetProcAddress(hDll, "WlanConnect");
    fnWlanDisconnect = (pfnWlanDisconnect)GetProcAddress(hDll, "WlanDisconnect");
    fnWlanCloseHandle = (pfnWlanCloseHandle)GetProcAddress(hDll, "WlanCloseHandle");
    fnWlanFreeMemory = (pfnWlanFreeMemory)GetProcAddress(hDll, "WlanFreeMemory");

    if (!fnWlanGetAvailableNetworkList || !fnWlanOpenHandle || !fnWlanEnumInterfaces || !fnWlanQueryInterface
        || !fnWlanSetProfile || !fnWlanSetInterface || !fnWlanConnect || !fnWlanDisconnect || !fnWlanCloseHandle || !fnWlanFreeMemory)
    {
        FreeLibrary(hDll);
        hDll = nullptr;
        m_bisLoad = false;
        return false;
    }
    m_bisLoad = true;
    return true;
}

void exportDLl::pReleaseLibrary()
{
    fnWlanGetAvailableNetworkList = nullptr;
    fnWlanOpenHandle = nullptr;
    fnWlanEnumInterfaces = nullptr;
    fnWlanQueryInterface = nullptr;
    fnWlanSetProfile = nullptr;
    fnWlanSetInterface = nullptr;
    fnWlanConnect = nullptr;
    fnWlanDisconnect = nullptr;
    fnWlanCloseHandle = nullptr;
    fnWlanFreeMemory = nullptr;
}

int exportDLl::pFindWifi(const char* sWifiName)
{
    if (!m_bisLoad)
    {
        return -3;
    }
    if (!wifiInit())
    {
        return -4;
    }
    if (isConnect(sWifiName) == 0)
    {
        //等于0  则需要查找的wifi正在连接  后续不用再操作
        //关闭句柄
        fnWlanCloseHandle(hClient, NULL);
        if (pIfList != NULL) {
            WlanFreeMemory(pIfList);
            pIfList = NULL;
        }
        pReleaseLibrary();
        return 0;
    }

    //有正在连接的wifi 断开连接
    fnWlanDisconnect(hClient, &pIfInfo->InterfaceGuid, 0);

    PWLAN_AVAILABLE_NETWORK_LIST pBssList = NULL;
    PWLAN_AVAILABLE_NETWORK pBssEntry = NULL;

    fnWlanGetAvailableNetworkList(hClient, &pIfInfo->InterfaceGuid, 0, NULL, &pBssList);

    if (pBssList == NULL)
    {
        return -1;
    }
    cout << pBssList->dwNumberOfItems << endl;

    for (int j = 0; j < (int)pBssList->dwNumberOfItems; ++j)
    {
        pBssEntry = (WLAN_AVAILABLE_NETWORK*)&pBssList->Network[j];
        std::string temp = std::string(reinterpret_cast<char*>(pBssEntry->dot11Ssid.ucSSID));
        if (temp.empty())
        {
            cout << "null wifiname\n";
            continue;
        }
        cout << temp.c_str() << " <-> "<<sWifiName << endl;
        if(strcmp(temp.c_str(),sWifiName) == 0)
        {
            return (int)pBssList->dwNumberOfItems;
        }
    }
    return -2;
}

int exportDLl::connect(const char* sXmlPath)
{
    if (!m_bisLoad)
    {
        return -2;
    }
    ifstream infile;
    infile.open(sXmlPath);
    if (!infile.is_open())
    {
        return 1;
    }

    char c;
    string s;
    infile >> noskipws;
    while (infile >> c) //读xml文件
    {
        s += c;       
    }  
    infile.close(); 
    cout << s << endl;
    
    WLAN_REASON_CODE Wlanreason; 
    //此处第四个参数是profile文件的内容,就是c#调用里组的xml
    int ret = fnWlanSetProfile(hClient,  &pIfInfo->InterfaceGuid, 0, StringToLPCWSTR(s), NULL, TRUE, NULL, &Wlanreason);

    if (ret != 0)
    {
        return -1;
    }
    string sXMLName = sXmlPath;

    int index = sXMLName.find_last_of("\\") + 1;
    if (string::npos == index)
    {
        //未查找到 \ 符号 说明文件在当前目录下 不用截取
    }
    else
    {
        sXMLName = sXMLName.substr(index);
    }

    DOT11_SSID stSsid;
    WLAN_CONNECTION_PARAMETERS stConnectionParameters;
    memset(&stSsid, 0, sizeof(stSsid));
    memset(&stConnectionParameters, 0, sizeof(WLAN_CONNECTION_PARAMETERS));
    memcpy(stSsid.ucSSID, sXMLName.c_str(), sizeof(stSsid.ucSSID));
    stSsid.uSSIDLength = strlen(sXMLName.c_str()) + 1;
    stConnectionParameters.pDot11Ssid = &stSsid;
    stConnectionParameters.wlanConnectionMode = wlan_connection_mode_discovery_unsecure;
    stConnectionParameters.strProfile = StringToLPCWSTR(sXMLName);  
    stConnectionParameters.dot11BssType = dot11_BSS_type_independent;  // msdn说可以dot11_BSS_type_any,实测不行
    stConnectionParameters.pDesiredBssidList = NULL;
    stConnectionParameters.dwFlags = 0; // WLAN_CONNECTION_ADHOC_JOIN_ONLY 
    //此处第三个参数很关键,也很复杂,稍微传错一点就会失败,暂时还没弄得很清楚
    ret = fnWlanConnect(hClient, &pIfInfo->InterfaceGuid, &stConnectionParameters, NULL);//pIfList   

    if (ret == ERROR_SUCCESS)
    {
        cout << "连接成功\n";
        fnWlanCloseHandle(hClient, NULL); //关闭句柄
        if (pIfList != NULL) {
            WlanFreeMemory(pIfList);
            pIfList = NULL;
        }
        pReleaseLibrary();
    }
    return ret;
 }


bool exportDLl::wifiInit()
{
    if (!m_bisLoad)
    {
        return false;
    }
    dwResult = fnWlanOpenHandle(dwMaxClient, NULL, &dwCurVersion, &hClient);
    if (ERROR_SUCCESS != dwResult)
    {
        cout << "WlanOpenHandle failed with error:" << dwResult;
        return false;
    }
    dwResult = fnWlanEnumInterfaces(hClient, NULL, &pIfList);
    if (ERROR_SUCCESS != dwResult)
    {
        cout << "WlanEnumInterfaces failed with error " << dwResult;
        return false;
    }
    int iScan = 1;
    PVOID pData = &iScan;
    dwResult = fnWlanSetInterface(hClient, &pIfInfo->InterfaceGuid, wlan_intf_opcode_background_scan_enabled, sizeof(int), pData, NULL);

    return true;
}

int exportDLl::isConnect(const char* sWifiName)
{
    if (!m_bisLoad)
    {
        return -3;
    }
    pIfInfo = (WLAN_INTERFACE_INFO*)&pIfList->InterfaceInfo[0];
    string CurConnectedWlanProfileName;
    if (pIfInfo->isState == wlan_interface_state_connected)
    {
        dwResult = fnWlanQueryInterface(hClient,
            &pIfInfo->InterfaceGuid,
            wlan_intf_opcode_current_connection,
            NULL,
            &connectInfoSize,
            (PVOID*)&pConnectInfo,
            &opCode);
        if (dwResult != ERROR_SUCCESS)
        {
            //
        }
        else
        {
            switch (pConnectInfo->isState)
            {
            case wlan_interface_state_connected:
            {
                string s;
                LPCWSTRToString(s,pConnectInfo->strProfileName);
                cout << s << " is connected\n";
                if (strcmp(s.c_str(), sWifiName) == 0)
                {
                    //如果要查找的wifi已经连接 则不再操作
                    return 0;
                }
                return -1;
            }
            default:
            {
                break;
            }
            }
        }
    }
    else
    {
        return -1;
        //未连接
    }
    return -1;
}

c#调用部分

using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace csharpWlan
{
    class Program
    {
        [DllImport("wlandll.dll")]
        public extern static bool pLoadLibrary();      

        [DllImport("wlandll.dll")]
        public extern static int pFindWifi(String wifiName);


        [DllImport("wlandll.dll")]
        public extern static int connect(String xmlPath);

        public static void CreateNode(XmlDocument xmlDoc, XmlNode parentNode, string name, string value)
        {
            XmlNode node = xmlDoc.CreateNode(XmlNodeType.Element, name, null);
            node.InnerText = value;
            parentNode.AppendChild(node);
        }

        public delegate int MethodWlanConn();

        public static String CreateXML(String path = "")
        {           
            if (path == "")
            {
                path = String.Format(@"{0}\{1}", System.Environment.CurrentDirectory, sXMLName);
            }
            if (File.Exists(sXMLName))
            {
                return path;
            }
            XmlDocument xmlDoc = new XmlDocument();            
            XmlDeclaration Declaration = xmlDoc.CreateXmlDeclaration("1.0", "", null);
            xmlDoc.AppendChild(Declaration);

            XmlNode rootNode = xmlDoc.CreateElement("WLANProfile");
            XmlAttribute rootNodeattribute = xmlDoc.CreateAttribute("xmlns");
            rootNodeattribute.Value = "http://www.microsoft.com/networking/WLAN/profile/v1";
            rootNode.Attributes.Append(rootNodeattribute);

            xmlDoc.AppendChild(rootNode);
            XmlNode Node1 = xmlDoc.CreateElement("name");
            Node1.InnerText = sWifiName;
            rootNode.AppendChild(Node1);

            XmlNode Node2 = xmlDoc.CreateElement("SSIDConfig");
            XmlNode Node3_1 = xmlDoc.CreateElement("SSID");
            XmlNode Node4_1 = xmlDoc.CreateElement("hex");
            Node4_1.InnerText = BitConverter.ToString(ASCIIEncoding.Default.GetBytes(sWifiName)).Replace("-", ""); //wifi名转十六进制
            XmlNode Node4_2 = xmlDoc.CreateElement("name");
            Node4_2.InnerText = sWifiName;
            Node3_1.AppendChild(Node4_1);
            Node3_1.AppendChild(Node4_2);
            Node2.AppendChild(Node3_1);        
            rootNode.AppendChild(Node2);

            XmlNode Node2_1 = xmlDoc.CreateElement("connectionType");
            XmlNode Node2_2 = xmlDoc.CreateElement("connectionMode");
            Node2_1.InnerText = "ESS";
            Node2_2.InnerText = "auto";
            rootNode.AppendChild(Node2_1);
            rootNode.AppendChild(Node2_2);

            XmlNode Node2_3 = xmlDoc.CreateElement("MSM");
            XmlNode Node3_3 = xmlDoc.CreateElement("security");
            XmlNode Node4_3 = xmlDoc.CreateElement("authEncryption");          
            XmlNode Node5_1 = xmlDoc.CreateElement("authentication");
            Node5_1.InnerText = "WPA2PSK";
            XmlNode Node5_2 = xmlDoc.CreateElement("encryption");
            Node5_2.InnerText = "AES";
            XmlNode Node5_3 = xmlDoc.CreateElement("useOneX");
            Node5_3.InnerText = "false";

            XmlNode Node4_4 = xmlDoc.CreateElement("sharedKey");
            XmlNode Node5_4 = xmlDoc.CreateElement("keyType");
            Node5_4.InnerText = "passPhrase";
            XmlNode Node5_5 = xmlDoc.CreateElement("protected");
            Node5_5.InnerText = "false";
            XmlNode Node5_6 = xmlDoc.CreateElement("keyMaterial");
            Node5_6.InnerText = sWifipwd; //密码
            Node4_4.AppendChild(Node5_4);
            Node4_4.AppendChild(Node5_5);
            Node4_4.AppendChild(Node5_6);
            Node4_3.AppendChild(Node5_1);
            Node4_3.AppendChild(Node5_2);
            Node4_3.AppendChild(Node5_3);
            Node3_3.AppendChild(Node4_3);
            Node3_3.AppendChild(Node4_4);
            Node2_3.AppendChild(Node3_3);
            rootNode.AppendChild(Node2_3);


            XmlNode Node2_4 = xmlDoc.CreateElement("MacRandomization");
            XmlAttribute Node2_4attribute = xmlDoc.CreateAttribute("xmlns");
            Node2_4attribute.Value = "http://www.microsoft.com/networking/WLAN/profile/v3";
            Node2_4.Attributes.Append(Node2_4attribute);
            XmlNode Node3_4 = xmlDoc.CreateElement("enableRandomization");
            Node3_4.InnerText = "false";
            Node2_4.AppendChild(Node3_4);

            rootNode.AppendChild(Node2_4);

            try
            {
                xmlDoc.Save(path);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            Console.WriteLine(path);

            return path;
        }
        public static bool loadLibrary()
        {           
            return pLoadLibrary();
        }

        public static int findWifi(String wifiName = "")
        {
            if (wifiName == "")
            {
                wifiName = sWifiName;
            }

            return pFindWifi(wifiName);
        }
        public static int connWifi()
        {         
            if (!loadLibrary())
            {
                Console.WriteLine("loadLibrary() == false\n");
                return -1;
            }
            Console.WriteLine("loadLibrary ok\n");

            int find = findWifi();
            if (find < 0)
            {
                Console.WriteLine("findWifi() <= 0\n");
                return -1;
            }
            else if(find == 0)
            {
                Console.WriteLine("connect is already ok\n");
                return 0;
            }
            
            Console.WriteLine("findWifi ok\n");

            int conn = connect(CreateXML());
            if (conn != 0)
            {
                Console.WriteLine(conn+" connect error\n");
                return -1;
            }
            Console.WriteLine(conn + " connect ok\n");
            return 0;
        }


        static void Main(string[] args)
        {
            connWifi();
        }

        static String sXMLName = "XXXXXX.xml";//profile文件名
        static String sWifiName = "wifiname"; //wifi名
        static String sWifipwd = "12345678"; //密码
        static String sDLLName = "wlandll.dll";

    }
}

补充一点:

netsh wlan show profile //可以查看所有连接过的wifi

netsh wlan export profile key=clear //导出所有连接过的wifi信息

做完了之后,发现有三个问题
1.调用完fnWlanSetProfile之后,有的wifi就已经能连接成功了,后面的fnWlanConnect无论返回什么都不影响。
2.有的wifi虽然fnWlanSetProfile和fnWlanConnect都返回成功,但是wifi实际却没有连接成功。
3.不是百分百每次都能连接成功,偶尔会失败

如果哪位大神知道是啥情况,请指教指教

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

调用windows系统动态库实现wifi连接及问题 的相关文章

  • Ubuntu通过终端命令行换阿里源(顺带解决ubuntu过时版本问题)

    1 检查Ubuntu系统的Codename lsb release a 得到结果 No LSB modules are available Distributor ID Ubuntu Description Ubuntu 17 10 Rel
  • Debian10 更换apt源

    http mirrors 163 com help debian html 163 官方源地址 xff0c 每4小时更新一次 如果是 Debian10 更换apt源 xff0c 查看debian10具体代号 xff0c 是buster xf
  • 位运算符之左移右移(简单易懂)

    前言 位运算符是用来对二进制位进行操作的 c语言中有6种位运算符 amp 按位与 链接 https blog csdn net weixin 42837024 article details 98736834 按位或 链接 https bl
  • Win10 快捷键大全(史上最全)

    windows 10常用快捷键 win10正式版是微软续已发布的Windows系统的最新版操作系统 windows10 win10正式版 让人感到最意外的就是直接跳过了win9 那么今天我为大家讲解他推出的常用快捷键 希望能够帮到大家 复制
  • clash配置只代理某一个网站

    1 如果你已经导入了某一个订阅 xff0c 右键edit 2 在rules里配置 例如 xff1a 配置只代理域名为aa com开头的网站 DOMAIN SUFFIX aa com proxy1 参数说明 xff1a DOMAIN SUFF
  • bash/tcsh实现回收站(rm -rf 血的教训)

    rm rf 慎用 命令敲得多了 xff0c 常在河边走 xff0c 难免会湿鞋 昨天 xff0c 一个手误 xff0c 敲错了命令 xff0c 把原本想要留的文件夹给rm rf掉了 几天心血全木有了 xff0c 靠 xff0c 死的心都有了
  • Windows远程连接Ubuntu (远程桌面和XDMCP)

    从 RHEL CentOS 转过来 xff0c 几乎所有的编码都在 windows 下 xff0c 不习惯原生 linux 开发 总结了远程连接的两种方式 xff0c 一种用 Windows 自带的 rdp 协议 xff0c 另外一种用 x
  • Linux启动java程序很慢

    Linux启动java程序很慢 xff0c 原因有很多 网上的解决方式也很多 1 修改jre配置参数 xff08 尝试无效 xff0c 可能场景不一 xff09 JAVA HOME jre lib security java securit
  • MySQL数据库备份的几种方式

    MySQL备份的几种方式 最近一直想写点博客 xff0c 但是不知道写什么 xff0c 感觉自己最近的知识没有什么增加 xff0c 今天想到了一篇可以写的博客 以前试过根据data文件夹备份MySQL xff0c 但是从来没有成功过 xff
  • 【docker】深入探讨container,通过container生成image

    深入探讨container 对于上图的理解 image其实是由一层一层的layer来组成的 最底层基于linux内核在上面加了一层一层的layer 从docker仓库pull的image是由Dockerfile来生成 这个image是只读的
  • 创建表时附带的ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic 的解释

    ENGINE 61 InnoDB DEFAULT CHARSET 61 utf8 COLLATE 61 utf8 general ci ROW FORMAT的解释 1 示例 CREATE TABLE 96 student 96 96 id
  • c语言编程“水仙花数”

    文章目录 打印所有的水仙花数 所谓的 水仙花数 是指一个三位数 xff0c 其各位数字的立方和等于该数本身 例如 xff0c 153是水仙花数 xff0c 因为153 61 1 3 43 5 3 43 3 3 打印所有的水仙花数 所谓的 水
  • inux查看日志的几种方法

    linux 日志查看 tail head cat tac sed less echo 1 命令格式 tail 必要参数 选择参数 文件 f 循环读取 q 不显示处理信息 v 显示详细的处理信息 c lt 数目 gt 显示的字节数 n lt
  • asp不能正常用的原因

    前几天做网站时 xff0c 机子出现了这种症状 xff0c 重装过IE和IIS一样也无法解决 xff0c 在百度里找了一下 xff0c 下面的方法真的很适用 症状 xff1a 运行asp程序 包括其他动态网页程序 出现500内部错误信息 x
  • 用DLL实现把数据库的记录导出到EXCEL中(VB)

    39 新建一个ActiveX DLL工程工程名为DbToExcel 39 工程 gt 引用 引用Microsoft ActiveX Data Objects 2 6 Library 39 Microsoft Excel 9 0 Object
  • MySQL转换为SqlServer数据库

    如何将MySQL数据导入到SqlServer中 xff0c 请看以下步骤 xff1a 1 安装mysql数据库的ODBC驱动 xff0c mysql connector odbc 3 51 19 win32 msi 2 打开控制面板管理工具
  • DataTimePicker数据绑定遇到Null时异常的原因

    DateTimePicker1 DataBindings Add 34 Value 34 bindingSource1 34 assessortime 34 如果字段 assessortime的值 为 null 时 就会出现异常 后来发现
  • c#中DataTable与实体集合相互转换

    以下是将集合类转换成DataTable lt summary gt 将集合类转换成DataTable lt summary gt lt param name 61 34 list 34 gt 集合 lt param gt lt return
  • 用Linux命令行生成随机密码的十种方法

    转载自 极客范 xff0c 不得不夸夸强大的Bash啊 xff01 xff01 xff01 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
  • C++20 Ranges

    VS2019 C 43 43 20的Ranges 01 引入范围的动机02 范围 ranges 03 range v3库04 C 43 43 20 range demo 01 引入范围的动机 C 43 43 17以前的标准库中大多数通用算法

随机推荐

  • 面向对象分析设计步骤

    一 创建用例 初步确定用例 xff1a 1 确定参与者 2 确定用例 xff08 系统操作 xff09 3 确定参与者与用例之间的关系 用例细节描述 xff1a 1 用例名称 2 操作详细描述 3 前置条件描述 4 部署约束 5 正常事件流
  • collect2: ld terminated with signal 9 错误解决办法

    编译android是出现如下错误 xff1a target Java CameraEffectsTests out target common obj APPS CameraEffectsTests intermediates classe
  • 浅谈Stein算法求最大公约数(GCD)的原理及简单应用

    一 Stein算法过程及其简单证明 1 一般步骤 xff1a s1 当两数均为偶数时将其同时除以2至至少一数为奇数为止 xff0c 记录除掉的所有公因数2的乘积k xff1b s2 如果仍有一数为偶数 xff0c 连续除以2直至该数为奇数为
  • 【已解决】@Configration爆红

    64 Configration爆红 问题原因 xff1a 一 xff1a 没有添加依赖 二 xff1a 添加依赖了 xff0c 但是依赖版本过低 解决方法 xff1a 把依赖的版本改的高一点 span class token generic
  • 关于冒泡排序的程序( 第三次作业)

    此前想过把两种排序方式都一起写在一个工程文件里 xff0c 但做了下 xff0c 能力有限 xff0c 没法写完整 xff0c 所以就只能分别写 xff0c 这个是冒泡排序 xff0c 代码已尽量做到准确的注释 xff0c 希望提醒自己往后
  • BSS段

    深入理解计算机系统 bss段 xff0c data段 text段 堆 heap 和栈 stack 1 关于BSS段的大小 2 1 BSS段中的内容 2 2 BSS段在加载运行前的处理 3 3 BSS段的作用 3 4 代码优化对BSS段的影响
  • Java 比较两个List对象差集(根据某一值)

    很多都是比较List lt String gt 的 xff0c 和自身业务不符 xff0c jdk1 8 新特性强大的Stream API xff0c 具体是什么方法 xff0c 什么作用自行百度 xff0c 复制粘贴可以解决问题就OK 4
  • Windows10 安装Redis(图文教程)

    Redis xff08 Remote Dictionary Server xff0c 即远程字典服务 xff0c 是一个开源的使用ANSI C语言编写 支持网络 可基于内存亦可持久化的日志型 Key Value数据库 一 下载redis客户
  • e17 enlightenment 介绍及配置

    为什么要有一个窗口管理器 为什么一定要有一个桌面背景 xff0c 甚至是标题栏 或是如果把一个应用程序如firefox当成桌面背景行不行 桌面能不能再快一点 我不想把资源浪费在那些用不到的地方 Linux那么多虚拟桌面 xff0c 为什么我
  • Vim: Warning: input is not from a terminal 后退出 vim 终端异常

    Vim Warning input is not from a terminal 后退出 vim 终端异常 今天执行了如下命令调用 vi 来打开 find 搜索到的文件 xff1a longyu 64 longyu pc span clas
  • UNPV2 学习:Posix Message Queues

    文章目录 特点消息队列的释放mq notify 函数mq notify 使用信号通知消息到达直接在信号处理函数中调用 mq notify 与 mq receive 函数来接收数据在信号处理函数中设置标志在程序主逻辑中调用 mq notify
  • VMware ESXI虚拟机磁盘在线扩容后fdisk -l 找不到问题解决

    VMware ESXI虚拟机磁盘在线扩容后fdisk l 找不到问题解决 在VMware ESXI终端页面为虚拟机新增磁盘后 xff0c 进入虚拟机执行fdisk l 找不到新增的盘 重启系统肯定是可以解决的 xff0c 但是机器有在跑测试
  • go调用python

    安装 安装python和go的环境 xff0c 在debian和ubuntu系统上 xff0c 还要sudo apt install python all dev安装sudo apt get install pkg config安装go g
  • C++ 20 Concept 语法

    requires expression 一种表达式 xff0c 它很像一个lambda表达式 xff0c 一个未命名元函数 例如 xff1a requires int a int b a 43 b 其中 xff1a xff08 xff09
  • 带你一步步破解Android微信聊天记录解决方案

    哪个小可爱在偷偷的看我 前言 最近公司需要做个内部应用 xff0c 需求有通话并录音上传服务器 xff0c 微信聊天记录上传服务器 xff0c 我擦 xff0c 竟然要做严重窃取隐私的功能 xff0c 一万个草泥马奔腾而来 xff0c 于是
  • 51单片机定时器初值的计算

    什么是时钟周期 xff1f 什么是机器周期 xff1f 什么是指令周期 xff1f 时钟周期 时钟周期也称为振荡周期 xff0c 定义为时钟脉冲的倒数 xff08 可以这样来理解 xff0c 时钟周期就是单片机外接晶振的倒数 xff0c 例
  • 计算机操作系统之系统调用

    目录 x1f4a8 什么是系统调用 xff0c 有何作用 xff1f x1f4a8 系统调用与库函数的区别 x1f4a8 系统调用背后的过程 x1f4a8 总结 我们将带着以下问题去学习什么是系统调用 什么是系统调用 xff0c 有何作用
  • Python简易逻辑运算

    1 逻辑运算符 逻辑运算在编程中是十分重要的组成部分 xff0c 除了布尔值外 xff0c 还有其他用于逻辑运算的运算符 and 与 or 或 not 非 and连接的条件判断必须前后全部成立结果才能成立 xff08 所有条件True才输出
  • RCE漏洞之绕过

    文章目录 花括号斜杠空格过滤一些命令分隔符黑名单绕过拼接绕过编码绕过单引号和双引号绕过利用Shell 特殊变量绕过linux中直接查看文件内容的工具文件构造 花括号 在Linux bash中还可以使用 OS COMMAND ARGUMENT
  • 调用windows系统动态库实现wifi连接及问题

    有个项目是c 做的 xff0c 有个需求是程序启动自动连接指定wifi xff0c 想到windows有个系统库支持 xff0c 就用c 43 43 调的系统库 xff0c 然后c 再调c 43 43 封装好的接口 xff0c 比较简单 x