DumpForPC.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Runtime.InteropServices;
  5. using System.Text;
  6. using UnityEngine;
  7. #if UNITY_STANDALONE_WIN
  8. enum DumpCommandType
  9. {
  10. enumDump_Begin = 0,
  11. enumDump_BackgroundExecutionFlag = enumDump_Begin, // 后台上传宕机信息(不显示DumpReport界面)
  12. enumDump_ForceUpload, // Dump是否强制上报(忽略玩家在DumpReport界面上的选择)
  13. enumDump_LogDirectory, // 设置log文件路径
  14. enumDump_CollectFile, // 设置需收集的文件名
  15. enumDump_LogDirectory_UTF8, // 设置log文件路径(传入参数为UTF8,Unity/UE 使用此参数)
  16. enumDump_CollectFile_UTF8, // 设置需收集的文件名(传入参数为UTF8,Unity/UE 使用此参数)
  17. enumDump_SetURL, // 设置上传url (internal_cn|internal_us|external|test) => (国内|海外|外部项目|内部测试)
  18. enumDump_SetBeta, // 设置 beta
  19. enumDump_SetUserIdentifier, // 设置 UserIdentifier
  20. enumDump_SetUserIdentifier_UTF8,
  21. enumDump_AddExtraData, // 添加额外数据
  22. enumDump_AddExtraData_UTF8, // 添加额外数据(传入参数为UTF8,Unity/UE 使用此参数)
  23. enumDump_leaveBreadcrumbType, // 设置面包屑传入字符串的格式
  24. enumDump_GM_TEST, // GM测试指令
  25. enumDump_Count
  26. }
  27. public class DumpForPC : MonoBehaviour
  28. {
  29. private static IntPtr StringToCharPtr(string s)
  30. {
  31. return Marshal.StringToHGlobalUni(s);
  32. }
  33. private static string YourAppVersion = "NA";
  34. [DllImport("Crasheye64")]
  35. private static extern bool InitDumperCrasheye(string appkey, string version, string channId);
  36. [DllImport("Crasheye64")]
  37. private static extern void UnInitDumper();
  38. [DllImport("Crasheye64")]
  39. private static extern bool SetConfig(int nDumpCommandType, IntPtr pArg);
  40. public static void SetForceUpload(bool isForceUpload)
  41. {
  42. IntPtr pBool = Marshal.AllocHGlobal(1);
  43. Marshal.WriteByte(pBool, Convert.ToByte(isForceUpload));
  44. SetConfig((int)DumpCommandType.enumDump_ForceUpload, pBool);
  45. Marshal.FreeHGlobal(pBool);
  46. }
  47. [DllImport("Crasheye64")]
  48. private static extern bool SetConfig(int nDumpCommandType, IntPtr[] pArg);
  49. [DllImport("Crasheye64")]
  50. public static extern bool SendScriptException(string errorTitle, string stackTrace, string language);
  51. public static bool SetBackgroundUpload(bool isBackgroundUpload)
  52. {
  53. IntPtr pBool = Marshal.AllocHGlobal(1);
  54. Marshal.WriteByte(pBool, Convert.ToByte(isBackgroundUpload));
  55. bool result = SetConfig((int)DumpCommandType.enumDump_BackgroundExecutionFlag, pBool);
  56. Marshal.FreeHGlobal(pBool);
  57. return result;
  58. }
  59. public delegate void FnOnCrashCallback(bool bCaptureSucceed, IntPtr cpszCrashReportFile);
  60. [DllImport("Crasheye64")]
  61. public static extern bool SetOnMiniDumpCreateCallBack(FnOnCrashCallback pCallback);
  62. [DllImport("Crasheye64", CharSet = CharSet.Unicode)]
  63. public static extern bool PushLogTrace([MarshalAs(UnmanagedType.LPStr)] string cpszMessage);
  64. [DllImport("Crasheye64", CharSet = CharSet.Unicode)]
  65. public static extern bool leaveBreadcrumb([MarshalAs(UnmanagedType.LPStr)] string cpszMessage);
  66. //AddExtraData专用参数
  67. private static IntPtr[] extraData = new IntPtr[2];
  68. /// <summary>
  69. /// Windows的初始化
  70. /// </summary>
  71. /// <param name="appKeyForPC">平台申请的当前应用</param>
  72. /// <param name="channIdForPC">应用的渠道号</param>
  73. public static void Init(string appKeyForPC,string channIdForPC)
  74. {
  75. try
  76. {
  77. bool res = InitDumperCrasheye(appKeyForPC, YourAppVersion, channIdForPC);
  78. }
  79. catch (Exception e)
  80. {
  81. Debug.LogError(e.Message);
  82. }
  83. }
  84. /// <summary>
  85. /// 反初始化 CrasheyeSdk
  86. /// 在程序正常退出时调用
  87. /// </summary>
  88. public static void UnInit()
  89. {
  90. try
  91. {
  92. UnInitDumper();
  93. }
  94. catch (Exception e)
  95. {
  96. Debug.LogError(e.Message);
  97. }
  98. }
  99. /// <summary>
  100. /// 设置上报路径.
  101. /// internal_cn => 国内自研项目
  102. /// internal_us => 海外自研项目
  103. /// external => 外部项目
  104. /// 若不设置, 默认是 external
  105. /// 若要设置, 建议在 Init 之前调用.
  106. /// </summary>
  107. /// <param name="url">internal_cn/internal_us/external 三选一</param>
  108. public static void SetURL(string url)
  109. {
  110. if (String.IsNullOrEmpty(url))
  111. {
  112. Debug.LogError("set url is null or empty!");
  113. return;
  114. }
  115. var szLogDir = url.Replace("/", "\\");
  116. IntPtr pLogDir = Marshal.StringToHGlobalAnsi(szLogDir);
  117. SetConfig((int)DumpCommandType.enumDump_SetURL, pLogDir);
  118. Marshal.FreeHGlobal(pLogDir);
  119. }
  120. /// <summary>
  121. /// 标记当前版本为调试版本.
  122. /// 若要设置, 建议在 Init 之前调用.
  123. /// </summary>
  124. public static void SetBeta()
  125. {
  126. try
  127. {
  128. IntPtr pLogDir = default;
  129. SetConfig((int)DumpCommandType.enumDump_SetBeta, pLogDir);
  130. }
  131. catch (Exception e)
  132. {
  133. Debug.LogError(e.Message);
  134. }
  135. }
  136. /// <summary>
  137. /// 设置用户id.
  138. /// </summary>
  139. /// <param name="userIdentifier">项目内部的用户id</param>
  140. public static void SetUserIdentifier(string userIdentifier)
  141. {
  142. if (string.IsNullOrEmpty(userIdentifier))
  143. {
  144. Debug.LogError("user identifier is null or empty!");
  145. return;
  146. }
  147. try
  148. {
  149. var szUserIdentifier = userIdentifier.Replace("/", "\\");
  150. IntPtr pUserIdentifier = Marshal.StringToHGlobalAnsi(szUserIdentifier);
  151. SetConfig((int)DumpCommandType.enumDump_SetUserIdentifier, pUserIdentifier);
  152. Marshal.FreeHGlobal(pUserIdentifier);
  153. }
  154. catch (Exception e)
  155. {
  156. Debug.LogError(e.Message);
  157. }
  158. }
  159. /// <summary>
  160. /// 设置用户id.
  161. /// </summary>
  162. /// <param name="userIdentifier">项目内部的用户id</param>
  163. public static void SetUserIdentifier_UTF8(string userIdentifier)
  164. {
  165. if (string.IsNullOrEmpty(userIdentifier))
  166. {
  167. Debug.LogError("user identifier is null or empty!");
  168. return;
  169. }
  170. try
  171. {
  172. var szUserIdentifier = userIdentifier.Replace("/", "\\");
  173. IntPtr pUserIdentifier = Marshal.StringToHGlobalAnsi(szUserIdentifier);
  174. SetConfig((int)DumpCommandType.enumDump_SetUserIdentifier_UTF8, pUserIdentifier);
  175. Marshal.FreeHGlobal(pUserIdentifier);
  176. }
  177. catch (Exception e)
  178. {
  179. Debug.LogError(e.Message);
  180. }
  181. }
  182. /// <summary>
  183. /// 添加自定义数据,额外上报信息.
  184. /// 以键值对的形式添加额外信息, 添加的信息会被包含着崩溃报告中随报告一同上报.
  185. /// </summary>
  186. /// <param name="szKey">Key</param>
  187. /// <param name="szValue">Value</param>
  188. public static void AddExtraData(string szKey,string szValue)
  189. {
  190. if (string.IsNullOrEmpty(szKey) || string.IsNullOrEmpty(szValue))
  191. {
  192. Debug.LogError("AddExtraData szKey or szVanlue is null");
  193. return;
  194. }
  195. try
  196. {
  197. extraData[0] = Marshal.StringToHGlobalAnsi(szKey);
  198. extraData[1] = Marshal.StringToHGlobalAnsi(szValue);
  199. SetConfig((int)DumpCommandType.enumDump_AddExtraData, extraData);
  200. Marshal.FreeHGlobal(extraData[0]);
  201. Marshal.FreeHGlobal(extraData[1]);
  202. }
  203. catch (Exception e)
  204. {
  205. Debug.LogError(e.Message);
  206. }
  207. }
  208. /// <summary>
  209. /// 添加自定义数据,额外上报信息.
  210. /// 以键值对的形式添加额外信息, 添加的信息会被包含着崩溃报告中随报告一同上报.
  211. /// </summary>
  212. /// <param name="szKey">Key</param>
  213. /// <param name="szValue">Value</param>
  214. public static void AddExtraDataUTF8(string szKey, string szValue)
  215. {
  216. if (string.IsNullOrEmpty(szKey) || string.IsNullOrEmpty(szValue))
  217. {
  218. Debug.LogError("AddExtraData szKey or szVanlue is null");
  219. return;
  220. }
  221. try
  222. {
  223. extraData[0] = Marshal.StringToHGlobalAnsi(szKey);
  224. extraData[1] = Marshal.StringToHGlobalAnsi(szValue);
  225. SetConfig((int)DumpCommandType.enumDump_AddExtraData_UTF8, extraData);
  226. Marshal.FreeHGlobal(extraData[0]);
  227. Marshal.FreeHGlobal(extraData[1]);
  228. }
  229. catch (Exception e)
  230. {
  231. Debug.LogError(e.Message);
  232. }
  233. }
  234. /// <summary>
  235. /// 添加额外上报日志(文件).
  236. /// 添加的文件会被包含着崩溃报告中随报告一同上报.
  237. /// </summary>
  238. /// <param name="collectFile">需要额外收集的文件</param>
  239. public static void AddCustomLog(string collectFile)
  240. {
  241. if (string.IsNullOrEmpty(collectFile))
  242. {
  243. Debug.LogError("AddCustomLog collectFile is null or empty");
  244. return;
  245. }
  246. try
  247. {
  248. var szCollectFile = collectFile.Replace("/", "\\");
  249. Debug.Log(szCollectFile);
  250. IntPtr pCollectFile = Marshal.StringToHGlobalAnsi(szCollectFile);
  251. SetConfig((int)DumpCommandType.enumDump_CollectFile_UTF8, pCollectFile);
  252. Marshal.FreeHGlobal(pCollectFile);
  253. }
  254. catch (Exception e)
  255. {
  256. Debug.LogError(e.Message);
  257. }
  258. }
  259. /// <summary>
  260. /// 添加额外上报日志(目录).
  261. /// 添加的目录会被包含着崩溃报告中随报告一同上报.
  262. /// </summary>
  263. /// <param name="collectFile">需要额外收集的文件目录</param>
  264. public static void AddCustomLogDirectory(string CollectLogDirectory)
  265. {
  266. if (string.IsNullOrEmpty(CollectLogDirectory))
  267. {
  268. Debug.LogError("AddCustomLog CollectLogDirectory is null or empty");
  269. return;
  270. }
  271. try
  272. {
  273. var szCollectLogDirectory = CollectLogDirectory.Replace("/", "\\");
  274. Debug.Log(szCollectLogDirectory);
  275. IntPtr pCollectLogDirectory = Marshal.StringToHGlobalAnsi(szCollectLogDirectory);
  276. SetConfig((int)DumpCommandType.enumDump_LogDirectory_UTF8, pCollectLogDirectory);
  277. Marshal.FreeHGlobal(pCollectLogDirectory);
  278. }
  279. catch (Exception e)
  280. {
  281. Debug.LogError(e.Message);
  282. }
  283. }
  284. /// <summary>
  285. /// 设置版本号信息
  286. /// </summary>
  287. /// <param name="yourAppVersion"></param>
  288. public static void SetAppVersion(string yourAppVersion)
  289. {
  290. if (yourAppVersion == null)
  291. {
  292. return;
  293. }
  294. YourAppVersion = yourAppVersion;
  295. }
  296. public static void SetBreadCrumbType(Int32 breadCrumbType)
  297. {
  298. IntPtr bCT = Marshal.AllocHGlobal(sizeof(Int32));
  299. Marshal.WriteInt32(bCT, breadCrumbType);
  300. SetConfig((int)DumpCommandType.enumDump_leaveBreadcrumbType, bCT);
  301. Marshal.FreeHGlobal(bCT);
  302. }
  303. public static void OnHandleUnresolvedException(object sender, UnhandledExceptionEventArgs args)
  304. {
  305. Debug.Log(args.ExceptionObject.GetType());
  306. if (args != null && args.ExceptionObject != null && typeof(Exception).IsInstanceOfType(args.ExceptionObject))
  307. {
  308. Debug.Log("OnHandleUnresolvedException Ture");
  309. Exception ex = (Exception)args.ExceptionObject;
  310. Debug.Log("C# error Source:" + ex.StackTrace);
  311. Debug.Log("C# error StackTrace:" + ex.StackTrace);
  312. LibSendScriptException(ex.Source, ex.StackTrace);
  313. }
  314. else
  315. {
  316. Debug.Log("OnHandleUnresolvedException False");
  317. }
  318. }
  319. public static void LibSendScriptException(string error, string stack)
  320. {
  321. Debug.Log("LibSendScriptException");
  322. bool res = SendScriptException(error, stack, "C#");
  323. Debug.Log(res);
  324. }
  325. public static void OnHandleLogCallback(string logString, string stackTrace, LogType type)
  326. {
  327. Debug.Log("OnHandleLogCallback: type: " + type + "logString: " + logString);
  328. if (LogType.Assert == type || LogType.Exception == type)
  329. {
  330. LibSendScriptException(logString, stackTrace);
  331. }
  332. }
  333. }
  334. #endif