Nav apraksta
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501
  1. using System;
  2. using System.Diagnostics;
  3. using System.IO;
  4. using UnityEditor;
  5. using Codice.Client.Common.EventTracking;
  6. using Codice.CM.Common;
  7. using Codice.LogWrapper;
  8. using Codice.Utils;
  9. using Unity.PlasticSCM.Editor.UI.Progress;
  10. using Unity.PlasticSCM.Editor.UI.StatusBar;
  11. using Unity.PlasticSCM.Editor.Views;
  12. namespace Unity.PlasticSCM.Editor.Tool
  13. {
  14. internal static class LaunchTool
  15. {
  16. public interface IShowDownloadPlasticExeWindow
  17. {
  18. bool Show(
  19. WorkspaceInfo wkInfo,
  20. bool isGluonMode,
  21. string installCloudFrom,
  22. string installEnterpriseFrom,
  23. string cancelInstallFrom);
  24. bool Show(
  25. RepositorySpec repSpec,
  26. bool isGluonMode,
  27. string installCloudFrom,
  28. string installEnterpriseFrom,
  29. string cancelInstallFrom);
  30. }
  31. public interface IProcessExecutor
  32. {
  33. Process ExecuteGUI(
  34. string program,
  35. string args,
  36. string commandFileArg,
  37. string commandFileName,
  38. int processId);
  39. Process ExecuteWindowsGUI(
  40. string program,
  41. string args,
  42. int processId);
  43. Process ExecuteProcess(string program, string args);
  44. }
  45. internal static void OpenGUIForMode(
  46. IShowDownloadPlasticExeWindow showDownloadPlasticExeWindow,
  47. IProcessExecutor processExecutor,
  48. WorkspaceInfo wkInfo,
  49. bool isGluonMode)
  50. {
  51. if (showDownloadPlasticExeWindow.Show(
  52. wkInfo,
  53. isGluonMode,
  54. TrackFeatureUseEvent.Features.InstallPlasticCloudFromOpenGUI,
  55. TrackFeatureUseEvent.Features.InstallPlasticEnterpriseFromOpenGUI,
  56. TrackFeatureUseEvent.Features.CancelPlasticInstallationFromOpenGUI))
  57. return;
  58. mLog.DebugFormat(
  59. "Opening GUI on wkPath '{0}'.",
  60. wkInfo.ClientPath);
  61. TrackFeatureUseEvent.For(
  62. PlasticGui.Plastic.API.GetRepositorySpec(wkInfo),
  63. isGluonMode ?
  64. TrackFeatureUseEvent.Features.LaunchGluonTool :
  65. TrackFeatureUseEvent.Features.LaunchPlasticTool);
  66. if (isGluonMode)
  67. {
  68. Process gluonProcess = processExecutor.ExecuteGUI(
  69. PlasticInstallPath.GetGluonExePath(),
  70. string.Format(
  71. ToolConstants.Gluon.GUI_WK_EXPLORER_ARG,
  72. wkInfo.ClientPath),
  73. ToolConstants.Gluon.GUI_COMMAND_FILE_ARG,
  74. ToolConstants.Gluon.GUI_COMMAND_FILE,
  75. mGluonProcessId);
  76. if (gluonProcess != null)
  77. mGluonProcessId = gluonProcess.Id;
  78. return;
  79. }
  80. if (PlatformIdentifier.IsMac())
  81. {
  82. Process plasticProcess = processExecutor.ExecuteGUI(
  83. PlasticInstallPath.GetPlasticExePath(),
  84. string.Format(
  85. ToolConstants.Plastic.GUI_MACOS_WK_EXPLORER_ARG,
  86. wkInfo.ClientPath),
  87. ToolConstants.Plastic.GUI_MACOS_COMMAND_FILE_ARG,
  88. ToolConstants.Plastic.GUI_MACOS_COMMAND_FILE,
  89. mPlasticProcessId);
  90. if (plasticProcess != null)
  91. mPlasticProcessId = plasticProcess.Id;
  92. return;
  93. }
  94. processExecutor.ExecuteProcess(
  95. PlasticInstallPath.GetPlasticExePath(),
  96. string.Format(
  97. ToolConstants.Plastic.GUI_WINDOWS_WK_ARG,
  98. wkInfo.ClientPath));
  99. }
  100. internal static void OpenBranchExplorer(
  101. IShowDownloadPlasticExeWindow showDownloadPlasticExeWindow,
  102. IProcessExecutor processExecutor,
  103. WorkspaceInfo wkInfo,
  104. bool isGluonMode)
  105. {
  106. if (showDownloadPlasticExeWindow.Show(
  107. wkInfo,
  108. isGluonMode,
  109. TrackFeatureUseEvent.Features.InstallPlasticCloudFromOpenBranchExplorer,
  110. TrackFeatureUseEvent.Features.InstallPlasticEnterpriseFromOpenBranchExplorer,
  111. TrackFeatureUseEvent.Features.CancelPlasticInstallationFromOpenBranchExplorer))
  112. return;
  113. mLog.DebugFormat(
  114. "Opening Branch Explorer on wkPath '{0}'.",
  115. wkInfo.ClientPath);
  116. TrackFeatureUseEvent.For(
  117. PlasticGui.Plastic.API.GetRepositorySpec(wkInfo),
  118. TrackFeatureUseEvent.Features.LaunchBranchExplorer);
  119. if (PlatformIdentifier.IsMac())
  120. {
  121. Process plasticProcess = processExecutor.ExecuteGUI(
  122. PlasticInstallPath.GetPlasticExePath(),
  123. string.Format(
  124. ToolConstants.Plastic.GUI_MACOS_BREX_ARG,
  125. wkInfo.ClientPath),
  126. ToolConstants.Plastic.GUI_MACOS_COMMAND_FILE_ARG,
  127. ToolConstants.Plastic.GUI_MACOS_COMMAND_FILE,
  128. mPlasticProcessId);
  129. if (plasticProcess != null)
  130. mPlasticProcessId = plasticProcess.Id;
  131. return;
  132. }
  133. Process brexProcess = processExecutor.ExecuteWindowsGUI(
  134. PlasticInstallPath.GetPlasticExePath(),
  135. string.Format(
  136. ToolConstants.Plastic.GUI_WINDOWS_BREX_ARG,
  137. wkInfo.ClientPath),
  138. mBrexProcessId);
  139. if (brexProcess != null)
  140. mBrexProcessId = brexProcess.Id;
  141. }
  142. internal static void OpenChangesetDiffs(
  143. IShowDownloadPlasticExeWindow showDownloadPlasticExeWindow,
  144. IProcessExecutor processExecutor,
  145. RepositorySpec repSpec,
  146. string fullChangesetSpec,
  147. bool isGluonMode)
  148. {
  149. if (showDownloadPlasticExeWindow.Show(
  150. repSpec,
  151. isGluonMode,
  152. TrackFeatureUseEvent.Features.InstallPlasticCloudFromOpenChangesetDiffs,
  153. TrackFeatureUseEvent.Features.InstallPlasticEnterpriseFromOpenChangesetDiffs,
  154. TrackFeatureUseEvent.Features.CancelPlasticInstallationFromOpenChangesetDiffs))
  155. return;
  156. mLog.DebugFormat(
  157. "Launching changeset diffs for '{0}'",
  158. fullChangesetSpec);
  159. string exePath = (isGluonMode) ?
  160. PlasticInstallPath.GetGluonExePath() :
  161. PlasticInstallPath.GetPlasticExePath();
  162. string changesetDiffArg = (isGluonMode) ?
  163. ToolConstants.Gluon.GUI_CHANGESET_DIFF_ARG :
  164. ToolConstants.Plastic.GUI_CHANGESET_DIFF_ARG;
  165. processExecutor.ExecuteProcess(exePath,
  166. string.Format(
  167. changesetDiffArg, fullChangesetSpec));
  168. }
  169. internal static void OpenSelectedChangesetsDiffs(
  170. IShowDownloadPlasticExeWindow showDownloadPlasticExeWindow,
  171. IProcessExecutor processExecutor,
  172. RepositorySpec repSpec,
  173. string srcFullChangesetSpec,
  174. string dstFullChangesetSpec,
  175. bool isGluonMode)
  176. {
  177. if (showDownloadPlasticExeWindow.Show(
  178. repSpec,
  179. isGluonMode,
  180. TrackFeatureUseEvent.Features.InstallPlasticCloudFromOpenSelectedChangesetsDiffs,
  181. TrackFeatureUseEvent.Features.InstallPlasticEnterpriseFromOpenSelectedChangesetsDiffs,
  182. TrackFeatureUseEvent.Features.CancelPlasticInstallationFromOpenSelectedChangesetsDiffs))
  183. return;
  184. mLog.DebugFormat(
  185. "Launching selected changesets diffs for '{0}' and '{1}'",
  186. srcFullChangesetSpec,
  187. dstFullChangesetSpec);
  188. string exePath = (isGluonMode) ?
  189. PlasticInstallPath.GetGluonExePath() :
  190. PlasticInstallPath.GetPlasticExePath();
  191. string selectedChangesetsDiffArgs = (isGluonMode) ?
  192. ToolConstants.Gluon.GUI_SELECTED_CHANGESETS_DIFF_ARGS :
  193. ToolConstants.Plastic.GUI_SELECTED_CHANGESETS_DIFF_ARGS;
  194. processExecutor.ExecuteProcess(exePath,
  195. string.Format(
  196. selectedChangesetsDiffArgs,
  197. srcFullChangesetSpec,
  198. dstFullChangesetSpec));
  199. }
  200. internal static void OpenBranchDiffs(
  201. IShowDownloadPlasticExeWindow showDownloadPlasticExeWindow,
  202. IProcessExecutor processExecutor,
  203. RepositorySpec repSpec,
  204. string fullBranchSpec,
  205. bool isGluonMode)
  206. {
  207. if (showDownloadPlasticExeWindow.Show(
  208. repSpec,
  209. isGluonMode,
  210. TrackFeatureUseEvent.Features.InstallPlasticCloudFromOpenBranchDiff,
  211. TrackFeatureUseEvent.Features.InstallPlasticEnterpriseFromOpenBranchDiff,
  212. TrackFeatureUseEvent.Features.CancelPlasticInstallationFromOpenBranchDiff))
  213. return;
  214. mLog.DebugFormat(
  215. "Launching branch diffs for '{0}'",
  216. fullBranchSpec);
  217. string exePath = (isGluonMode) ?
  218. PlasticInstallPath.GetGluonExePath() :
  219. PlasticInstallPath.GetPlasticExePath();
  220. string branchDiffArg = (isGluonMode) ?
  221. ToolConstants.Gluon.GUI_BRANCH_DIFF_ARG :
  222. ToolConstants.Plastic.GUI_BRANCH_DIFF_ARG;
  223. processExecutor.ExecuteProcess(exePath,
  224. string.Format(
  225. branchDiffArg, fullBranchSpec));
  226. }
  227. internal static void OpenWorkspaceConfiguration(
  228. IShowDownloadPlasticExeWindow showDownloadPlasticExeWindow,
  229. IProcessExecutor processExecutor,
  230. WorkspaceInfo wkInfo,
  231. bool isGluonMode)
  232. {
  233. if (showDownloadPlasticExeWindow.Show(
  234. wkInfo,
  235. isGluonMode,
  236. TrackFeatureUseEvent.Features.InstallPlasticCloudFromOpenWorkspaceConfiguration,
  237. TrackFeatureUseEvent.Features.InstallPlasticEnterpriseFromOpenWorkspaceConfiguration,
  238. TrackFeatureUseEvent.Features.CancelPlasticInstallationFromOpenWorkspaceConfiguration))
  239. return;
  240. mLog.DebugFormat(
  241. "Opening Workspace Configuration on wkPath '{0}'.",
  242. wkInfo.ClientPath);
  243. TrackFeatureUseEvent.For(
  244. PlasticGui.Plastic.API.GetRepositorySpec(wkInfo),
  245. TrackFeatureUseEvent.Features.LaunchPartialConfigure);
  246. Process gluonProcess = processExecutor.ExecuteGUI(
  247. PlasticInstallPath.GetGluonExePath(),
  248. string.Format(
  249. ToolConstants.Gluon.GUI_WK_CONFIGURATION_ARG,
  250. wkInfo.ClientPath),
  251. ToolConstants.Gluon.GUI_COMMAND_FILE_ARG,
  252. ToolConstants.Gluon.GUI_COMMAND_FILE,
  253. mGluonProcessId);
  254. if (gluonProcess == null)
  255. return;
  256. mGluonProcessId = gluonProcess.Id;
  257. }
  258. internal static void OpenMerge(
  259. IShowDownloadPlasticExeWindow showDownloadPlasticExeWindow,
  260. IProcessExecutor processExecutor,
  261. WorkspaceInfo wkInfo,
  262. bool isGluonMode)
  263. {
  264. if (showDownloadPlasticExeWindow.Show(
  265. wkInfo,
  266. isGluonMode,
  267. TrackFeatureUseEvent.Features.InstallPlasticCloudFromOpenMerge,
  268. TrackFeatureUseEvent.Features.InstallPlasticEnterpriseFromOpenMerge,
  269. TrackFeatureUseEvent.Features.CancelPlasticInstallationFromOpenMerge))
  270. return;
  271. mLog.DebugFormat(
  272. "Opening Merge on wkPath '{0}'.",
  273. wkInfo.ClientPath);
  274. if (PlatformIdentifier.IsMac())
  275. {
  276. Process plasticProcess = processExecutor.ExecuteGUI(
  277. PlasticInstallPath.GetPlasticExePath(),
  278. string.Format(ToolConstants.Plastic.GUI_MACOS_MERGE_ARG, wkInfo.ClientPath),
  279. ToolConstants.Plastic.GUI_MACOS_COMMAND_FILE_ARG,
  280. ToolConstants.Plastic.GUI_MACOS_COMMAND_FILE,
  281. mPlasticProcessId);
  282. if (plasticProcess != null)
  283. mPlasticProcessId = plasticProcess.Id;
  284. return;
  285. }
  286. processExecutor.ExecuteProcess(
  287. PlasticInstallPath.GetPlasticExePath(),
  288. string.Format(ToolConstants.Plastic.GUI_WINDOWS_MERGE_ARG, wkInfo.ClientPath));
  289. }
  290. static int mPlasticProcessId = -1;
  291. static int mGluonProcessId = -1;
  292. static int mBrexProcessId = -1;
  293. static readonly ILog mLog = PlasticApp.GetLogger("LaunchTool");
  294. internal class ShowDownloadPlasticExeWindow : LaunchTool.IShowDownloadPlasticExeWindow
  295. {
  296. bool LaunchTool.IShowDownloadPlasticExeWindow.Show(
  297. WorkspaceInfo wkInfo,
  298. bool isGluonMode,
  299. string installCloudFrom,
  300. string installEnterpriseFrom,
  301. string cancelInstallFrom)
  302. {
  303. RepositorySpec repSpec = PlasticGui.Plastic.API.GetRepositorySpec(wkInfo);
  304. return ((LaunchTool.IShowDownloadPlasticExeWindow)this).Show(
  305. repSpec,
  306. isGluonMode,
  307. installCloudFrom,
  308. installEnterpriseFrom,
  309. cancelInstallFrom);
  310. }
  311. bool LaunchTool.IShowDownloadPlasticExeWindow.Show(
  312. RepositorySpec repSpec,
  313. bool isGluonMode,
  314. string installCloudFrom,
  315. string installEnterpriseFrom,
  316. string cancelInstallFrom)
  317. {
  318. if (IsExeAvailable.ForMode(isGluonMode))
  319. return false;
  320. mData = DownloadPlasticExeDialog.Show(
  321. repSpec,
  322. isGluonMode,
  323. installCloudFrom,
  324. installEnterpriseFrom,
  325. cancelInstallFrom,
  326. mData != null && !string.IsNullOrEmpty(mData.ProgressMessage) ? mData : null);
  327. return true;
  328. }
  329. UI.UIElements.ProgressControlsForDialogs.Data mData;
  330. }
  331. internal class ProcessExecutor : LaunchTool.IProcessExecutor
  332. {
  333. Process LaunchTool.IProcessExecutor.ExecuteGUI(
  334. string program,
  335. string args,
  336. string commandFileArg,
  337. string commandFileName,
  338. int processId)
  339. {
  340. string commandFile = Path.Combine(
  341. Path.GetTempPath(), commandFileName);
  342. Process process = GetGUIProcess(program, processId);
  343. if (process == null)
  344. {
  345. mLog.DebugFormat("Executing {0} (new process).", program);
  346. return ((LaunchTool.IProcessExecutor)this).ExecuteProcess(
  347. program, args + string.Format(commandFileArg, commandFile));
  348. }
  349. mLog.DebugFormat("Executing {0} (reuse process pid:{1}).", program, processId);
  350. using (StreamWriter writer = new StreamWriter(new FileStream(
  351. commandFile, FileMode.Append, FileAccess.Write, FileShare.Read)))
  352. {
  353. writer.WriteLine(args);
  354. }
  355. return process;
  356. }
  357. Process LaunchTool.IProcessExecutor.ExecuteWindowsGUI(
  358. string program,
  359. string args,
  360. int processId)
  361. {
  362. Process process = GetGUIProcess(program, processId);
  363. if (process == null)
  364. {
  365. mLog.DebugFormat("Executing {0} (new process).", program);
  366. return ((LaunchTool.IProcessExecutor)this).ExecuteProcess(program, args);
  367. }
  368. mLog.DebugFormat("Not executing {0} (existing process pid:{1}).", program, processId);
  369. BringWindowToFront.ForWindowsProcess(process.Id);
  370. return process;
  371. }
  372. Process LaunchTool.IProcessExecutor.ExecuteProcess(string program, string args)
  373. {
  374. mLog.DebugFormat("Execute process: '{0} {1}'", program, args);
  375. Process process = BuildProcess(program, args);
  376. try
  377. {
  378. process.Start();
  379. return process;
  380. }
  381. catch (Exception ex)
  382. {
  383. mLog.ErrorFormat("Couldn't execute the program {0}: {1}",
  384. program, ex.Message);
  385. mLog.DebugFormat("Stack trace: {0}",
  386. ex.StackTrace);
  387. return null;
  388. }
  389. }
  390. Process BuildProcess(string program, string args)
  391. {
  392. Process result = new Process();
  393. result.StartInfo.FileName = program;
  394. result.StartInfo.Arguments = args;
  395. result.StartInfo.CreateNoWindow = false;
  396. return result;
  397. }
  398. Process GetGUIProcess(string program, int processId)
  399. {
  400. if (processId == -1)
  401. return null;
  402. mLog.DebugFormat("Checking {0} process [pid:{1}].", program, processId);
  403. try
  404. {
  405. Process process = Process.GetProcessById(processId);
  406. if (process == null)
  407. return null;
  408. return process.HasExited ? null : process;
  409. }
  410. catch
  411. {
  412. // process is not running
  413. return null;
  414. }
  415. }
  416. readonly ILog mLog = PlasticApp.GetLogger("ProcessExecutor");
  417. }
  418. }
  419. }