Без опису
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

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