diff --git a/WeChatFerry.sln b/WeChatFerry.sln
index 4c077b5..edf529f 100644
--- a/WeChatFerry.sln
+++ b/WeChatFerry.sln
@@ -15,6 +15,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sdk", "sdk\sdk.vcxproj", "{
{4DE80B82-5F6A-4C4C-9D16-1574308110FA} = {4DE80B82-5F6A-4C4C-9D16-1574308110FA}
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "launcher", "launcher\launcher.vcxproj", "{B11ADC6F-20DA-4DEF-A8A0-60374427D4C6}"
+ ProjectSection(ProjectDependencies) = postProject
+ {ABFCB647-137F-478B-A73E-F0B1E3ADC215} = {ABFCB647-137F-478B-A73E-F0B1E3ADC215}
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Release|x86 = Release|x86
@@ -26,6 +31,8 @@ Global
{2FC45612-A106-42D1-871F-1DE704095B2C}.Release|x86.Build.0 = Release|Win32
{ABFCB647-137F-478B-A73E-F0B1E3ADC215}.Release|x86.ActiveCfg = Release|Win32
{ABFCB647-137F-478B-A73E-F0B1E3ADC215}.Release|x86.Build.0 = Release|Win32
+ {B11ADC6F-20DA-4DEF-A8A0-60374427D4C6}.Release|x86.ActiveCfg = Release|Win32
+ {B11ADC6F-20DA-4DEF-A8A0-60374427D4C6}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/launcher/Launcher.cpp b/launcher/Launcher.cpp
new file mode 100644
index 0000000..1bcd190
--- /dev/null
+++ b/launcher/Launcher.cpp
@@ -0,0 +1,11 @@
+#include "Launcher.h"
+
+using namespace launcher;
+
+[STAThreadAttribute]
+
+int main() {
+ Launcher launcher;
+ launcher.ShowDialog();
+ return 0;
+}
diff --git a/launcher/Launcher.h b/launcher/Launcher.h
new file mode 100644
index 0000000..00967af
--- /dev/null
+++ b/launcher/Launcher.h
@@ -0,0 +1,137 @@
+#pragma once
+
+#include "../sdk/sdk.h"
+
+namespace launcher {
+
+ using namespace System;
+ using namespace System::ComponentModel;
+ using namespace System::Collections;
+ using namespace System::Windows::Forms;
+ using namespace System::Data;
+ using namespace System::Drawing;
+
+ ///
+ /// Launcher 摘要
+ ///
+ public ref class Launcher : public System::Windows::Forms::Form
+ {
+ public:
+ Launcher(void)
+ {
+ InitializeComponent();
+ //
+ //TODO: 在此处添加构造函数代码
+ //
+ }
+
+ protected:
+ ///
+ /// 清理所有正在使用的资源。
+ ///
+ ~Launcher()
+ {
+ if (components)
+ {
+ delete components;
+ }
+ }
+ private: System::Windows::Forms::Button^ Start;
+ private: System::Windows::Forms::Button^ Stop;
+ protected:
+
+ protected:
+
+
+ protected:
+
+ private:
+ ///
+ /// 必需的设计器变量。
+ ///
+ System::ComponentModel::Container ^components;
+
+#pragma region Windows Form Designer generated code
+ ///
+ /// 设计器支持所需的方法 - 不要修改
+ /// 使用代码编辑器修改此方法的内容。
+ ///
+ void InitializeComponent(void)
+ {
+ this->Start = (gcnew System::Windows::Forms::Button());
+ this->Stop = (gcnew System::Windows::Forms::Button());
+ this->SuspendLayout();
+ //
+ // Start
+ //
+ this->Start->Font = (gcnew System::Drawing::Font(L"宋体", 14.25F, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point,
+ static_cast(134)));
+ this->Start->Location = System::Drawing::Point(36, 39);
+ this->Start->Name = L"Start";
+ this->Start->Size = System::Drawing::Size(100, 40);
+ this->Start->TabIndex = 0;
+ this->Start->Text = L"启动";
+ this->Start->UseVisualStyleBackColor = true;
+ this->Start->Click += gcnew System::EventHandler(this, &Launcher::Start_Click);
+ //
+ // Stop
+ //
+ this->Stop->Enabled = false;
+ this->Stop->Font = (gcnew System::Drawing::Font(L"宋体", 14.25F, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point,
+ static_cast(134)));
+ this->Stop->Location = System::Drawing::Point(177, 39);
+ this->Stop->Name = L"Stop";
+ this->Stop->Size = System::Drawing::Size(100, 40);
+ this->Stop->TabIndex = 1;
+ this->Stop->Text = L"关闭";
+ this->Stop->UseVisualStyleBackColor = true;
+ this->Stop->Click += gcnew System::EventHandler(this, &Launcher::Stop_Click);
+ //
+ // Launcher
+ //
+ this->AutoScaleDimensions = System::Drawing::SizeF(6, 12);
+ this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
+ this->ClientSize = System::Drawing::Size(308, 122);
+ this->Controls->Add(this->Stop);
+ this->Controls->Add(this->Start);
+ this->FormBorderStyle = System::Windows::Forms::FormBorderStyle::FixedSingle;
+ this->MaximizeBox = false;
+ this->Name = L"Launcher";
+ this->StartPosition = System::Windows::Forms::FormStartPosition::CenterScreen;
+ this->Text = L"WeChatFerry Launcher";
+ this->FormClosing += gcnew System::Windows::Forms::FormClosingEventHandler(this, &Launcher::Launcher_FormClosing);
+ this->ResumeLayout(false);
+
+ }
+#pragma endregion
+ private: System::Void Start_Click(System::Object^ sender, System::EventArgs^ e) {
+ this->Start->Enabled = false;
+ this->Stop->Enabled = true;
+ WxInitSDK();
+ }
+ private: System::Void Stop_Click(System::Object^ sender, System::EventArgs^ e) {
+ this->Stop->Enabled = false;
+ this->Start->Enabled = true;
+ WxDestroySDK();
+ }
+ private: System::Void Launcher_Closing(System::Object^ sender, System::EventArgs^ e) {
+ if (this->Stop->Enabled) { // 已经启动
+ WxDestroySDK();
+ }
+ }
+ private: System::Void Launcher_FormClosing(System::Object^ sender, System::Windows::Forms::FormClosingEventArgs^ e)
+ {
+ if (this->Stop->Enabled) { // 已经启动
+ System::Windows::Forms::DialogResult ret;
+ ret = MessageBox::Show("确定退出?", "警告", MessageBoxButtons::YesNo, MessageBoxIcon::Question);
+ if (ret == System::Windows::Forms::DialogResult::Yes) {
+ WxDestroySDK();
+ e->Cancel = false;
+ }
+ else {
+ e->Cancel = true;
+ }
+ }
+ }
+ };
+}
diff --git a/launcher/Launcher.resx b/launcher/Launcher.resx
new file mode 100644
index 0000000..61bc649
--- /dev/null
+++ b/launcher/Launcher.resx
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ True
+
+
\ No newline at end of file
diff --git a/launcher/icon.ico b/launcher/icon.ico
new file mode 100644
index 0000000..77c7d4f
Binary files /dev/null and b/launcher/icon.ico differ
diff --git a/launcher/launcher.aps b/launcher/launcher.aps
new file mode 100644
index 0000000..7e28a98
Binary files /dev/null and b/launcher/launcher.aps differ
diff --git a/launcher/launcher.rc b/launcher/launcher.rc
new file mode 100644
index 0000000..8af2e2c
--- /dev/null
+++ b/launcher/launcher.rc
@@ -0,0 +1,71 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "winres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// (壬й) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
+LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
+#pragma code_page(936)
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""winres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_ICON1 ICON "C:\\Projs\\WeChatFerry\\launcher\\icon.ico"
+
+#endif // (壬й) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/launcher/launcher.vcxproj b/launcher/launcher.vcxproj
new file mode 100644
index 0000000..ff368f2
--- /dev/null
+++ b/launcher/launcher.vcxproj
@@ -0,0 +1,151 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 16.0
+ {B11ADC6F-20DA-4DEF-A8A0-60374427D4C6}
+ v4.7.2
+ ManagedCProj
+ launcher
+ 10.0
+
+
+
+ Application
+ true
+ v142
+ true
+ Unicode
+
+
+ Application
+ false
+ v142
+ true
+ Unicode
+
+
+ Application
+ true
+ v142
+ true
+ Unicode
+
+
+ Application
+ false
+ v142
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Level3
+ WIN32;NDEBUG;%(PreprocessorDefinitions)
+
+
+ $(OutDir)sdk.lib;%(AdditionalDependencies)
+ Windows
+ main
+
+
+ xcopy /y $(OutDir)launcher.exe $(OutDir)out\launcher
+
+
+ Copy files
+
+
+
+
+ Level3
+ WIN32;_DEBUG;%(PreprocessorDefinitions)
+
+
+
+
+
+
+
+ Level3
+ _DEBUG;%(PreprocessorDefinitions)
+
+
+
+
+
+
+
+ Level3
+ NDEBUG;%(PreprocessorDefinitions)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ CppForm
+
+
+
+
+
+ Launcher.h
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/launcher/launcher.vcxproj.filters b/launcher/launcher.vcxproj.filters
new file mode 100644
index 0000000..ea37648
--- /dev/null
+++ b/launcher/launcher.vcxproj.filters
@@ -0,0 +1,40 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ 源文件
+
+
+
+
+ 头文件
+
+
+ 头文件
+
+
+
+
+ 资源文件
+
+
+
+
+ 资源文件
+
+
+
\ No newline at end of file
diff --git a/launcher/launcher.vcxproj.user b/launcher/launcher.vcxproj.user
new file mode 100644
index 0000000..88a5509
--- /dev/null
+++ b/launcher/launcher.vcxproj.user
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/launcher/resource.h b/launcher/resource.h
new file mode 100644
index 0000000..4e82c98
--- /dev/null
+++ b/launcher/resource.h
@@ -0,0 +1,16 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ ɵİļ
+// launcher.rc ʹ
+//
+#define IDI_ICON1 101
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 102
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1001
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/sdk/SDK.vcxproj b/sdk/SDK.vcxproj
index 2e67e0a..b491701 100644
--- a/sdk/SDK.vcxproj
+++ b/sdk/SDK.vcxproj
@@ -127,6 +127,7 @@
xcopy /y $(OutDir)sdk.dll $(OutDir)out\cpp
+xcopy /y $(OutDir)sdk.dll $(OutDir)out\launcher
xcopy /y $(OutDir)sdk.dll $(OutDir)out\java\src\main\resources\win32-x86
xcopy /y $(OutDir)sdk.dll $(SolutionDir)python\wcferry
xcopy /y $(SolutionDir)TEQuant.jpeg $(OutDir)out\cpp
diff --git a/spy/Spy.vcxproj b/spy/Spy.vcxproj
index 1ea8be9..4e5e2b9 100644
--- a/spy/Spy.vcxproj
+++ b/spy/Spy.vcxproj
@@ -133,9 +133,11 @@
cd $(OutDir)
md out\cpp
+md out\launcher
md out\java\src\main\java
md out\java\src\main\resources\win32-x86
xcopy /y $(OutDir)spy.dll $(OutDir)out\cpp
+xcopy /y $(OutDir)spy.dll $(OutDir)out\launcher
xcopy /y $(OutDir)spy.dll $(OutDir)out\java\src\main\resources\win32-x86
xcopy /y $(OutDir)spy.dll $(SolutionDir)python\wcferry
diff --git a/spy/rpc_server.cpp b/spy/rpc_server.cpp
index dae37cf..6fda256 100644
--- a/spy/rpc_server.cpp
+++ b/spy/rpc_server.cpp
@@ -31,7 +31,7 @@ extern std::string GetSelfWxid(); // Defined in spy.cpp
using namespace std;
-using grpc::CallbackServerContext;
+using grpc::CallbackServerContext;
using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerUnaryReactor;
@@ -231,7 +231,8 @@ public:
static DWORD lThreadId = 0;
static bool lIsRunning = false;
-static ServerBuilder lBuilder;
+static ServerBuilder lBuilder;
+static WcfImpl lService;
static unique_ptr &GetServer()
{
@@ -243,14 +244,13 @@ static unique_ptr &GetServer()
static int RunServer()
{
string server_address("0.0.0.0:10086");
- WcfImpl service;
lBuilder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
lBuilder.AddChannelArgument(GRPC_ARG_KEEPALIVE_TIME_MS, 2000);
lBuilder.AddChannelArgument(GRPC_ARG_KEEPALIVE_TIMEOUT_MS, 3000);
lBuilder.AddChannelArgument(GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS, 1);
- lBuilder.RegisterService(&service);
-
+ lBuilder.RegisterService(&lService);
+
unique_ptr &server = GetServer();
LOG_INFO("Server listening on {}", server_address);
LOG_DEBUG("server: {}", fmt::ptr(server));
@@ -261,7 +261,11 @@ static int RunServer()
}
int RpcStartServer()
-{
+{
+ if (lIsRunning) {
+ return 0;
+ }
+
HANDLE rpcThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)RunServer, NULL, NULL, &lThreadId);
if (rpcThread != 0) {
CloseHandle(rpcThread);
@@ -272,12 +276,20 @@ int RpcStartServer()
int RpcStopServer()
{
- if (lIsRunning) {
- UnListenMessage();
+ if (lIsRunning) {
+ Empty empty;
+ Response rsp;
+ CallbackServerContext context;
+
unique_ptr &server = GetServer();
- LOG_DEBUG("server: {}", fmt::ptr(server));
+ LOG_DEBUG("server: {}", fmt::ptr(server));
+ if (gIsListening) {
+ //UnListenMessage(); // Do it in RpcDisableRecvMsg
+ lService.RpcDisableRecvMsg(&context, &empty, &rsp);
+ }
server->Shutdown();
- LOG_INFO("Server stoped.");
+ LOG_INFO("Server stoped.");
+ lIsRunning = false;
}
return 0;