首页 > 编程语言 >使用API Monitor探测QQ安装包在创建桌面快捷方式时都调用了哪些API及COM接口,去解决C++程序安装包中的问题

使用API Monitor探测QQ安装包在创建桌面快捷方式时都调用了哪些API及COM接口,去解决C++程序安装包中的问题

时间:2024-08-12 11:25:43浏览次数:16  
标签:pLink C++ API 快捷方式 NULL 安装包

目录

1、通过代码制作安装包程序,不再使用专用的打包工具

2、问题说明

3、为啥路径中包含环境变量%ProgramFiles%会报找不到路径呢?

4、使用API Monitor监测QQ安装包在创建桌面快捷方式时都调用哪些COM组件的接口

5、同时勾选IShelllinkDatalist接口类的接口,重新开启监测

6、最后


C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/125529931C/C++实战进阶(已更新到400多篇,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_11931267.htmlVC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/124272585Windows C++ 软件开发从入门到精通(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_12695902.htmlC++软件分析工具从入门到精通案例集锦(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/131405795开源组件及数据库技术(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_12458859.html网络编程与网络问题分享(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_2276111.html       为了解决项目中遇到的问题,我们多次使用API Monitor探测主流软件在实现类似功能时调用了哪些API或COM接口,参考API接口调用及参数设置。本文通过一个项目实例分享一下API Monitor工具的使用方法和相关细节,以供借鉴或参考。

1、通过代码制作安装包程序,不再使用专用的打包工具

       为了更自主的控制软件安装包、更方便地定制安装包的UI界面,我们不再借助InstallShield、Inno Setup、NSIS等专业打包工具,我们自己用代码编写一个安装包程序,实现这些打包工具类似的功能,比如:

1)将要打包的所有文件做成压缩包,作为资源添加到安装包工程中。执行安装时从工程资源中将压缩包取出来,然后进行解压。
2)执行文件的拷贝操作。将打包的文件拷贝到安装目录中,并将部分文件拷贝到系统相应的目录中。
3)注册相关控件。程序中可能包含ocx或者ATL控件,这些控件在安装时需要向系统注册。
4)创建桌面快捷方式和开始菜单快捷方式。
5)向注册表中写入安装卸载注册表信息。其中最重要的是安装路径信息,卸载程序时需要从注册表中读取安装路径,将文件从安装路径中删除掉。

2、问题说明

       在创建桌面快捷方式时遇到了问题。软件的exe主程序换了新的图标,但安装好安装包之后,桌面快捷方式的图标并没有更新。于是尝试到快捷方式和属性中手动去更新快捷方式图标。结果在64位系统中,右键点击桌面快捷方式,打开快捷方式的属性页面:(以腾讯会议的桌面快捷方式为例,我们的软件不是腾讯会议哈!

点击更改图标按钮,弹出如下页面:

点击确定,却报如下的错误:

路径中包含了一个%ProgramFiles%的环境变量,找不到对应的exe主程序路径。

       所以,此处主要有两个问题:

1)exe主程序更新了,但安装后桌面快捷方式图标没有更新;
2)尝试到快捷方式属性中去手动更新快捷方式图标时,指向的exe主程序路径中居然包含了%ProgramFiles%环境变量,导致找不到exe主程序。

快捷方式图标的更新,应该是通过该快捷方式指向的exe程序的图标去更新的。所以,第一个问题可能是第二个问题导致的。

3、为啥路径中包含环境变量%ProgramFiles%会报找不到路径呢?

       为什么通过这个包含%ProgramFiles%环境变量的路径找不到主程序呢?因为我们的程序是32位的,在64位系统中会默认安装到C:\Program Files (x86)路径中,而在64位系中%ProgramFiles%环境变量指向的应该是C:\Program Files,所以找不到快捷方式指向的exe程序。

       在64位系统中,32位程序和64位程序的默认安装路径是有区别的,32位程序会默认安装到C:\Program Files (x86)路径中,64位程序会默认安装到C:\Program Files路径中。写代码时,调用的API接口获取的都是C:\Program Files路径,系统会根据当前程序的版本,返回重定向后的路径,即32位程序返回C:\Program Files (x86)路径,64位程序返回C:\Program Files路径。


       在这里,给大家重点推荐一下我的几个热门畅销专栏,欢迎订阅:(博客主页还有其他专栏,可以去查看)

专栏1:(该精品技术专栏的订阅量已达到500多个,专栏中包含大量项目实战分析案例,有很强的实战参考价值,广受好评!专栏文章持续更新中,预计更新到200篇以上!欢迎订阅!)

C++软件调试与异常排查从入门到精通系列文章汇总icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/125529931

本专栏根据多年C++软件异常排查的项目实践,系统地总结了引发C++软件异常的常见原因以及排查C++软件异常的常用思路与方法,详细讲述了C++软件的调试方法与手段,以图文并茂的方式给出具体的项目问题实战分析实例(很有实战参考价值),带领大家逐步掌握C++软件调试与异常排查的相关技术,适合基础进阶和想做技术提升的相关C++开发人员!

考察一个开发人员的水平,一是看其编码及设计能力,二是要看其软件调试能力!所以软件调试能力(排查软件异常的能力)很重要,必须重视起来!能解决一般人解决不了的问题,既能提升个人能力及价值,也能体现对团队及公司的贡献!

专栏中的文章都是通过项目实战总结出来的,包含大量项目问题实战分析案例,有很强的实战参考价值!专栏文章还在持续更新中,预计文章篇数能更新到200篇以上!

专栏2:  

C++常用软件分析工具从入门到精通案例集锦汇总(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/131405795

常用的C++软件辅助分析工具有SPY++、PE工具、Dependency Walker、GDIView、Process Explorer、Process Monitor、API Monitor、Clumsy、Windbg、IDA Pro等,本专栏详细介绍如何使用这些工具去巧妙地分析和解决日常工作中遇到的问题,很有实战参考价值!

专栏3:(本专栏涵盖了多方面的内容,是当前重点打造的专栏,专栏文章已经更新到400多篇,持续更新中...)

C/C++实战进阶(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_11931267.html

以多年的开发实战为基础,总结并讲解一些的C/C++基础与项目实战进阶内容,以图文并茂的方式对相关知识点进行详细地展开与阐述!专栏涉及了C/C++领域多个方面的内容,包括C++基础及编程要点(模版泛型编程、STL容器及算法函数的使用等)、C++11及以上新特性(不仅看开源代码会用到,日常编码中也会用到部分新特性,面试时也会涉及到)、常用C++开源库的介绍与使用、代码分享(调用系统API、使用开源库)、常用编程技术(动态库、多线程、多进程、数据库及网络编程等)、软件UI编程(Win32/duilib/QT/MFC)、C++软件调试技术(排查软件异常的手段与方法、分析C++软件异常的基础知识、常用软件分析工具使用、实战问题分析案例等)、设计模式、网络基础知识与网络问题分析进阶内容等。

专栏4:   

VC++常用功能开发汇总(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/124272585

将10多年C++开发实践中常用的功能,以高质量的代码展现出来。这些常用的高质量规范代码,可以直接拿到项目中使用,能有效地解决软件开发过程中遇到的问题。

专栏5: 

Windows C++ 软件开发从入门到精通(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_12695902.html

根据多年C++软件开发实践,详细地总结了Windows C++ 应用软件开发相关技术实现细节,分享了大量的实战案例,很有实战参考价值。


4、使用API Monitor监测QQ安装包在创建桌面快捷方式时都调用哪些COM组件的接口

       我们创建的桌面快捷方式出现上述问题,应该是我们写的创建快捷方式的代码有问题,估计是漏调用了一些接口了。于是想到可以使用API Monitor工具监测一下主流软件,看看它们都调用了哪些接口。QQ是主流软件,功能完备强大,于是决定去监测QQ的安装包程序。

       我们原先创建快捷方式的代码如下:(网上的通用代码)

/*
  函数功能:创建快捷方式  
  函数参数:    
  lpszFileName    指定快捷方式指向的实际exe文件路径      
  lpszLnkFileDir  指定目录,不能为NULL。        
  lpszLnkFileName 快捷方式完整路径        
  wHotkey         为0表示不设置快捷键            
  pszDescription  备注              
  iShowCmd        运行方式,默认为常规窗口           
*/
BOOL CreateFileShortcut( LPCSTR lpszFileName, LPCSTR lpszLnkFileDir, LPCSTR lpszLnkFileName, 
                                       LPCSTR lpszWorkDir, WORD wHotkey, LPCTSTR lpszDescription, int iShowCmd )
{    
    if ( lpszLnkFileDir == NULL )        
        return FALSE; 
    HRESULT hr;    
    IShellLink     *pLink;  //IShellLink对象指针    
    IPersistFile   *ppf; //IPersisFil对象指针 
    
    
    //创建IShellLink对象    
    hr = CoCreateInstance( CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&pLink );    
    
    //从IShellLink对象中获取IPersistFile接口    
    hr = pLink->QueryInterface(IID_IPersistFile, (void**)&ppf);    
    if (FAILED(hr))        
    {        
        pLink->Release();        
        return FALSE;        
    }    
    
    //目标    
    if ( lpszFileName == NULL )
    {
        pLink->SetPath(_pgmptr);
    }
    else
    {
        pLink->SetPath(lpszFileName);
    }   
    
    //工作目录    
    if (lpszWorkDir != NULL)
    {
        pLink->SetPath(lpszWorkDir);
    }
    
    //快捷键    
    if ( wHotkey != 0 )
    {  
        pLink->SetHotkey(wHotkey);
    }
    
    //备注    
    if (lpszDescription != NULL)
    {
        pLink->SetDescription(lpszDescription);
    }
    
    //显示方式    
    pLink->SetShowCmd( iShowCmd );    
    
    //快捷方式的路径 + 名称    
    char szBuffer[MAX_PATH] = { 0 };    
    if (lpszLnkFileName != NULL) //指定了快捷方式的名称
    {
        sprintf(szBuffer, "%s\\%s", lpszLnkFileDir, lpszLnkFileName);
    }
    else      
    {        
        //没有指定名称,就从取指定文件的文件名作为快捷方式名称      
        char *pstr;        
        if (lpszFileName != NULL)
        {
            pstr = (char*)strrchr(lpszFileName, '\\');
        }
        else
        {   
            pstr = strrchr(_pgmptr, '\\');
        }        
        
        if (pstr == NULL)            
        {              
            ppf->Release();            
            pLink->Release();            
            return FALSE;            
        }
        
        //注意后缀名要从.exe改为.lnk        
        sprintf(szBuffer, "%s\\%s", lpszLnkFileDir, pstr);        
        int nLen = strlen(szBuffer);        
        szBuffer[nLen - 3] = 'l';        
        szBuffer[nLen - 2] = 'n';        
        szBuffer[nLen - 1] = 'k';        
    }
    
    //保存快捷方式到指定目录下    
    WCHAR  wsz[MAX_PATH];  //定义Unicode字符串    
    MultiByteToWideChar(CP_ACP, 0, szBuffer, -1, wsz, MAX_PATH);   
    
    hr = ppf->Save(wsz, TRUE);   
    ppf->Release();    
    pLink->Release();    
    return SUCCEEDED(hr);
}

从上述代码看,创建快捷方式主要用到了IShellLink和IPersistFile两个COM接口,可以在API Monitor中选择监控这两个COM接口类的所有的成员函数。

API Monitor不仅仅可以监测系统API函数的调用,还可以监测COM组件接口的调用。

       先启动QQ的安装包程序,如下所示:

先不要点立即安装,等API Monitor开启对该QQ安装包进程的监测后,再点立即安装。

       因为QQ安装包程序肯定是以管理员权限运行的,所以启动API Monitor时也要以管理员权限启动,否则开启监控时会因为权限不对等开启监控失败。右键点击API Monitor exe程序,选择以管理员身份运行:

启动后在左边的API函数列表中勾选IShellLink和IPersistFile两个COM组件接口类的所有接口,如下所示:

          

然后在右下角的进程列表中找到QQ安装包进程,右键点击之,在弹出的右键菜单中点击“Start Monitoring”开启监控:

然后切换到QQ安装包界面,点击立即安装,进入安装过程:

API Monitor就在监测QQ安装包创建快捷方式的相关操作了(一般会在安装结尾时去创建快捷方式的)。

       安装包安装完成后,切换到API Monitor窗口,监测到了IShellLink和IPersistFile两个COM组件类接口的调用,如下所示:

从上述记录还看到,还使用到了Query了IShelllinkDatalist接口类,所以API Monitor还要监控IShelllinkDatalist接口类的接口,所以整个监测过程要重头来过。

5、同时勾选IShelllinkDatalist接口类的接口,重新开启监测

       重新启动QQ安装包程序,重新以管理员权限运行API Monitor工具,在API Monitor左边的API函数列表中将IShelllinkDatalist接口类的接口都勾选上:

然后在左下角的进程列表中找到QQ安装包进程,开启监控。待QQ安装包执行完成后,API Monitor监测到了如下的结果:

上面截图中圈中的接口调用,我们代码中是没有的,于是参考这些接口调用以及对应的参数(API Monitor中不仅能看到函数名称,还能看到具体的参数类型以及参数值),把这几个接口加到代码中,然后上述问题就解决了。新增的代码如下:(代码中调用的COM接口的含义,见下面代码中的注释)

// 新增代码1、解决快捷图标不刷新、更改图标时找不到文件的问题
pLink->SetIconLocation( lpszTargetFilePath, 0 ); // 图标路径会被解析成环境变量(x64下更改图标时系统提示找不到文件)
IShellLinkDataList *pShellLinkDataList = NULL;
hr = pLink->QueryInterface( IID_IShellLinkDataList, (void**)&pShellLinkDataList );
if ( FAILED(hr) )
{
    ppf->Release();
    pLink->Release();
    return FALSE;
}

// 新增代码2:避免图标路径被解析成环境变量
DWORD dwFlags = SLDF_DEFAULT;
pShellLinkDataList->GetFlags( &dwFlags );
if ( (dwFlags & SLDF_HAS_EXP_ICON_SZ) == SLDF_HAS_EXP_ICON_SZ )
{
    pShellLinkDataList->SetFlags( SLDF_DEFAULT );
    pShellLinkDataList->RemoveDataBlock( EXP_SZ_ICON_SIG );
}
pShellLinkDataList->Release();

         修改后的创建快捷方式的完整代码如下:

// 1、得到公共用户桌面路径
BOOL GetPublicUserDesktopPath( TCHAR *pszDesktopPath )
{
    LPITEMIDLIST  ppidl = NULL;  
    if ( SHGetSpecialFolderLocation( NULL, CSIDL_COMMON_DESKTOPDIRECTORY, &ppidl ) == S_OK )
    //if ( SHGetFolderLocation(NULL, CSIDL_COMMON_DESKTOPDIRECTORY, NULL, 0 , &ppidl ) == S_OK )
    {
        BOOL flag =  SHGetPathFromIDList( ppidl, pszDesktopPath );

        CString strLog;
        strLog.Format( _T("[CProcessLogic::GetPublicUserDesktopPath]CSIDL_COMMON_DESKTOPDIRECTORY path: %s"), 
            pszDesktopPath );
        uilog( strLog );

        CoTaskMemFree( ppidl );
        return flag;
    }

    return FALSE;
}

// 2、创建桌面快捷方式
void CreateDesktopShortCut()
{
    ::CoInitialize( NULL );

    TCHAR achDesktopDir[MAX_PATH] = { 0 };    
    BOOL bRet = GetPublicUserDesktopPath( achDesktopDir );
    if ( !bRet )
    {
        ::CoUninitialize();
        return;
    }

    // 假设主程序的名称为 TestDlg.exe,桌面快捷方式的名称为TestDlg.lnk 
    // m_strInstallPath为当前用户选择的安装路径
    CString strExePath;
    strExePath.Format( _T("%s\\TestDlg.exe"), m_strInstallPath);
    CString strLnkPath;
    strLnkPath.Format( _T("%s\\TestDlg.lnk"), achDesktopDir);
    CreateFileShortcut( strRunTrueLinkPath, strLnkPath, 0, NULL );

    ::CoUninitialize(); 
}


/*
  函数功能:创建快捷方式(封装的创建快捷方式的公用函数)  
  函数参数:    
  lpszFileName    指定快捷方式指向的实际exe文件路径      
  lpszLnkPath     快捷方式完整路径                
  wHotkey         为0表示不设置快捷键            
  pszDescription  备注                                                                                                  
  iShowCmd        运行方式,默认为常规窗口           
*/
BOOL CreateFileShortcut( LPCTSTR lpszTargetFilePath, LPCTSTR lpszLnkPath, WORD wHotkey, 
    LPCTSTR lpszDescription, int iShowCmd )
{    
    if ( lpszTargetFilePath  == NULL || lpszLnkPath == NULL ) 
    {
        return FALSE;
    }

    HRESULT hr;    
    IShellLink   *pLink;  // IShellLink对象指针    
    IPersistFile *ppf;    // IPersisFil对象指针 

    //::CoInitialize( NULL );
    
    // 创建IShellLink对象    
    hr = CoCreateInstance( CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&pLink );    
    if (  FAILED( hr ) )  
    {
        //::CoUninitialize()
        return FALSE;
    }
    
    // 从IShellLink对象中获取IPersistFile接口    
    hr = pLink->QueryInterface( IID_IPersistFile, (void**)&ppf );    
    if ( FAILED( hr ) )        
    {        
        pLink->Release();  
        //::CoUninitialize()
        return FALSE;        
    }    
    
    // 快捷方式指向的实际文件路径    
    if ( lpszTargetFilePath != NULL )
    {
        CString strWorkDirectry = lpszTargetFilePath;
        strWorkDirectry = strWorkDirectry.Left( strWorkDirectry.ReverseFind( _T('\\') ) );

        pLink->SetPath( lpszTargetFilePath );
        pLink->SetWorkingDirectory( strWorkDirectry );

        // 新增代码1、解决快捷图标不刷新、更改图标时找不到文件的问题
        pLink->SetIconLocation( lpszTargetFilePath, 0 ); // 图标路径会被解析成环境变量(x64下更改图标时系统提示找不到文件)
        IShellLinkDataList *pShellLinkDataList = NULL;
        hr = pLink->QueryInterface( IID_IShellLinkDataList, (void**)&pShellLinkDataList );
        if ( FAILED(hr) )
        {
            ppf->Release();
            pLink->Release();
            return FALSE;
        }
        
        // 新增代码2:避免图标路径被解析成环境变量
        DWORD dwFlags = SLDF_DEFAULT;
        pShellLinkDataList->GetFlags( &dwFlags );
        if ( (dwFlags & SLDF_HAS_EXP_ICON_SZ) == SLDF_HAS_EXP_ICON_SZ )
        {
            pShellLinkDataList->SetFlags( SLDF_DEFAULT );
            pShellLinkDataList->RemoveDataBlock( EXP_SZ_ICON_SIG );
        }
        pShellLinkDataList->Release();
    }   
    
    // 快捷键    
    if ( wHotkey != 0 )
    {  
        pLink->SetHotkey( wHotkey );
    }
    
    // 备注    
    if ( lpszDescription != NULL )
    {
        pLink->SetDescription( lpszDescription );
    }
    
    // 显示方式    
    pLink->SetShowCmd( iShowCmd );    
    
    // 保存快捷方式到指定目录下    
    // 要将路径字符串转化成宽字节字符串,COM接口ppf->Save要传入宽字符
    BOOL bUnicode = FALSE;
    WCHAR* pwTemp = NULL;
#ifdef _UNICODE
    pwTemp = (LPTSTR)lpszLnkPath;
    bUnicode = TRUE;
#else
    int nLen = MultiByteToWideChar( CP_ACP, 0, lpszLnkPath, -1, NULL, 0 );
    pwTemp = new WCHAR[nLen+1];
    memset( pwTemp, 0, (nLen+1)*sizeof(WCHAR) );
    MultiByteToWideChar( CP_ACP, 0, lpszLnkPath, -1, pwTemp, nLen+1, NULL, NULL );
#endif
    
    hr = ppf->Save( pwTemp, TRUE ); 

    ppf->Release();    
    pLink->Release(); 

    if ( !bUnicode && pwTemp != NULL )
    {
        delete []pwTemp;
        pwTemp = NULL;
    }

    //::CoUninitialize();

    return SUCCEEDED( hr );    
}

6、最后

       本文通过使用API Monitor监测目标程序来解决实际项目中的问题,详细讲解了API Monitor使用过程与相关细节,有一定的实战参考价值,希望能对大家有所帮助。

标签:pLink,C++,API,快捷方式,NULL,安装包
From: https://blog.csdn.net/chenlycly/article/details/140177266

相关文章

  • 调用百度api的情绪分析网站(Flask+HTML)搭建(附超详细代码)
      概要:本文调用多个api接口来进行不同类型(数据文件)情绪分析处理,并利用flask框架与前端联调将自己的情绪分析项目部署到服务器端。。实现下图功能。(第一篇文章小小记录下,要是有帮助就点个赞叭)一.免费申请百度api并调用首先在百度智能云中申请免费的自然语言处理api选......
  • Android studio报错 Caused by: org.gradle.api.internal.plugins.PluginApplicationE
    Androidstudio报错Causedby:org.gradle.api.internal.plugins.PluginApplicationExceptionAndroidstudio运行报错:Causedby:org.gradle.api.internal.plugins.PluginApplicationException:Failedtoapplyplugin[id‘com.android.application’]解决方法:在项......
  • OpenAI API: How do I handle errors in Python?
    题意:在使用OpenAIAPI进行Python开发时,怎样处理错误?问题背景:Itriedusingthebelowcode,buttheOpenAIAPIdoesn'thavethe AuthenticationError methodinthelibrary.HowcanIeffectivelyhandlesucherror.我尝试使用下面的代码,但是OpenAIAPI的库中并没......
  • API安全与等保测评:接口安全测试技术与工具选择
    关键技术点:1.认证与授权:检查API是否实施了强大的身份验证机制,如OAuth2.0、JWT,并验证授权逻辑是否严谨。2.输入验证:测试API对用户输入的处理,确保有效防止SQL注入、跨站脚本(XSS)等攻击。3.数据加密:评估传输层安全(TLS)配置以及敏感数据在存储和传输时的加密策略。4.速率限......
  • swagger-api生成接口文档
    引入swagger-api生成接口文档1.引入pom依赖<!--swagger2依赖--><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.9.2</version&......
  • API 的多分支管理,让 Apifox 帮你轻松搞定!
    在产品迭代的过程中,对API的更新和维护是必然的,也是至关重要的。当产品需要引入新功能或对现有功能进行调整时,相应的API往往也需要进行升级或修改,这种情况在快速迭代的产品中很是常见。然而,API的迭代更新并非易事,在随着产品进行升级或修改的过程中,在管理API时往往会面......
  • JS那些api会改变原数组,哪些不会
    会改变数组增删1.push() 在数组最后面插入项,返回数组的长度arr.push(插入元素) 2.pop()在数组最后取出一项,返回取出项arr.pop()3.shift()取出数组中第一项,返回取出项arr.shift() 4.unshift()在数组最前面插入项,返回数组的长度arr.unshift()  5.spli......
  • 【Web API 】渗透测试指南
    一、概述1.1API的基本概念1.2API的作用1.3API的类型二、WebAPI渗透测试2.1测试工具2.2信息收集2.2.1目录扫描2.2.2网络流量分析2.2.3使用互联网资源2.3漏洞检测2.4实战案例2.4.1接口枚举2.4.......
  • 在IIS上部署ASP.NET Core Web API
    在IIS上部署ASP.NETCoreWebAPI和BlazorWasm详细教程  前言前段时间我们完成了七天.NET8操作SQLite入门到实战的开发系列教程,有不少同学留言问如何将项目发布部署到IIS上面运行。本篇文章我们就一起来讲讲在IIS上部署ASP.NETCoreWebAPI和BlazorWasm。前提条件......
  • LLaMA-Factory微调llama3之模型的合并,并采用llama.cpp量化成ollama支持的gguf格式模型
    上期我们已经成功的训练了模型,让llama3中文聊天版知道了自己的名字这次我们从合并模型开始,然后使用llama.cpp量化成gguf格式,并且调用api(1)前期准备上期链接: 基于LLaMA-Factory微调llama3成为一个角色扮演大模型,保姆级教学零基础,导出GGUF格式前篇-CSDN博客 首先根据上期......