程序控

IPPP (Institute of Penniless Peasent-Programmer) Fellow

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::
  75 随笔 :: 0 文章 :: 470 评论 :: 116万 阅读
< 2025年2月 >
26 27 28 29 30 31 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 1
2 3 4 5 6 7 8

可能不少在沙盘(Sandboxie)里运行QQ的同学都会遇到这样的问题:

先把QQ装在沙盘里,然后把QQ的安装文件夹复制到另一个地方,清空沙盘,再从沙盘中启动QQ:

QQ出错

经过排除法查找,确定这个问题是由于两个安全组件(COM)没有注册引起的。这两个组件的动态链接库文件分别是安装在以下目录的SSOCommon.dll和SSOPlatform.dll

c:\program files\common\tencent\TXSSO\版本号\bin\

为了解决这个问题,写了一个简单的QQ启动器,把它放在QQ的bin目录下,在沙盘里运行它就可以自动注册这两个组件,并自动启动QQ了。是代码附在下面仅供参考,编译需要项目文件支持。

点击这里下载配置好的项目文件包(VS2008)

点击这里下载编译好的程序

注意,我当前版本的TXSSO是1.2.1.38。如果你的QQ不是这个版本,请将项目里的两个dll替换成你的QQ里附带的版本,并重新编译。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include <tchar.h>
#include <windows.h>
#include <atlstr.h>
#include <shlobj.h>
#include "resource.h"
 
HKEY CreateKey(LPCTSTR lpKey)
{
    HKEY hKey;
    DWORD dwDisp;
    RegCreateKeyEx(HKEY_LOCAL_MACHINE, lpKey, 0, NULL,
        REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &dwDisp);
    return hKey;
}
 
void SetValue(HKEY hKey, LPCTSTR lpName, LPCTSTR lpValue)
{
    CString strValue(lpValue);
    if (lpName)
    {
        RegSetValueEx(hKey, lpName, 0, REG_SZ, (LPBYTE)(LPCTSTR)strValue,
            strValue.GetLength() * sizeof(TCHAR));
    }
    else
    {
        RegSetValue(hKey, NULL, REG_SZ, strValue, strValue.GetLength());
    }
}
 
void SaveResourceFile(LPCTSTR lpType, DWORD dwResId, LPCTSTR lpFileName)
{
    DWORD dwRet;
    HRSRC hResInfo = FindResource(NULL, MAKEINTRESOURCE(dwResId), lpType);
    HGLOBAL hResMem = LoadResource(NULL, hResInfo);
    DWORD dwSize = SizeofResource(NULL, hResInfo);
    LPVOID lpData = LockResource(hResMem);
    HANDLE hDllFile = CreateFile(lpFileName, GENERIC_WRITE, 0, NULL,
        CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    WriteFile(hDllFile, lpData, dwSize, &dwRet, NULL);
    CloseHandle(hDllFile);
}
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine, int nCmdShow)
{
    CString strRoot, strSubPath, strFile;
    SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES_COMMON,
        NULL, SHGFP_TYPE_CURRENT, strRoot.GetBuffer(MAX_PATH));
    strRoot.ReleaseBuffer();
    strRoot += _T("\\Tencent\\");
    CreateDirectory(strRoot, NULL);
    strRoot += _T("TXSSO\\");
    CreateDirectory(strRoot, NULL);
    strRoot += _T("1.2.1.38\\");
    CreateDirectory(strRoot, NULL);
    strRoot += _T("Bin\\");
    CreateDirectory(strRoot, NULL);
 
 
    SaveResourceFile(_T("DLLFILE"), IDR_DLL_SSOCOMMON,
        strRoot + _T("SSOCommon.dll"));
    SaveResourceFile(_T("DLLFILE"), IDR_DLL_SSOPLATFORM,
        strRoot + _T("SSOPlatform.dll"));
 
    HKEY hKey;
 
    hKey = CreateKey(_T("SOFTWARE\\TENCENT\\TXSSO"));
    SetValue(hKey, _T("Version"), _T("1.2.1.38"));
    RegCloseKey(hKey);
 
    hKey = CreateKey(_T("SOFTWARE\\Classes\\SSOAxCtrlForPTLogin.SSOForPTLogin2"));
    SetValue(hKey, NULL, _T("SSOForPTLogin2 Class"));
    RegCloseKey(hKey);
 
    hKey = CreateKey(_T("SOFTWARE\\Classes\\SSOAxCtrlForPTLogin.SSOForPTLogin2\\CLSID"));
    SetValue(hKey, NULL, _T("{EAAED308-7322-4b9b-965E-171933ADD473}"));
    RegCloseKey(hKey);
 
    hKey = CreateKey(_T("SOFTWARE\\Classes\\SSOAxCtrlForPTLogin.SSOForPTLogin2\\CurVer"));
    SetValue(hKey, NULL, _T("SSOAxCtrlForPTLogin.SSOForPTLogin.2"));
    RegCloseKey(hKey);
 
    ShellExecute(NULL, _T("open"), _T("QQ.exe"), NULL, NULL, SW_SHOW);
 
    return 0;
}

 

posted on   Devymex  阅读(7323)  评论(0编辑  收藏  举报
编辑推荐:
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· .NET Core内存结构体系(Windows环境)底层原理浅谈
阅读排行:
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· DeepSeek 解答了困扰我五年的技术问题。时代确实变了!
· 本地部署DeepSeek后,没有好看的交互界面怎么行!
· 趁着过年的时候手搓了一个低代码框架
· 推荐一个DeepSeek 大模型的免费 API 项目!兼容OpenAI接口!
点击右上角即可分享
微信分享提示