summaryrefslogtreecommitdiff
path: root/src/processrunner.h
blob: 2e9550e0cba104d2e8bde7df9f5e5f96142657a9 (plain)
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#ifndef PROCESSRUNNER_H
#define PROCESSRUNNER_H

#include "spawn.h"
#include "lockwidget.h"
#include <executableinfo.h>

class OrganizerCore;
class IUserInterface;
class Executable;
class MOShortcut;

class SpawnedProcess
{
public:
  SpawnedProcess(HANDLE handle, spawn::SpawnParameters sp);

  SpawnedProcess(const SpawnedProcess&) = delete;
  SpawnedProcess& operator=(const SpawnedProcess&) = delete;
  SpawnedProcess(SpawnedProcess&& other);
  SpawnedProcess& operator=(SpawnedProcess&& other);
  ~SpawnedProcess();

  HANDLE releaseHandle();
  void wait();

private:
  HANDLE m_handle;
  spawn::SpawnParameters m_parameters;

  void destroy();
};


class ProcessRunner
{
public:
  enum Results
  {
    Running = 1,
    Completed,
    Error,
    Cancelled,
    ForceUnlocked
  };

  enum RefreshModes
  {
    NoRefresh = 1,
    Refresh
  };

  using ForcedLibraries = QList<MOBase::ExecutableForcedLoadSetting>;

  ProcessRunner(OrganizerCore& core, IUserInterface* ui);

  ProcessRunner& setBinary(const QFileInfo &binary);
  ProcessRunner& setArguments(const QString& arguments);
  ProcessRunner& setCurrentDirectory(const QDir& directory);
  ProcessRunner& setSteamID(const QString& steamID);
  ProcessRunner& setCustomOverwrite(const QString& customOverwrite);
  ProcessRunner& setForcedLibraries(const ForcedLibraries& forcedLibraries);
  ProcessRunner& setProfileName(const QString& profileName);
  ProcessRunner& setWaitForCompletion(
    RefreshModes refresh, LockWidget::Reasons reason=LockWidget::LockUI);

  ProcessRunner& setFromFile(QWidget* parent, const QFileInfo& targetInfo);
  ProcessRunner& setFromExecutable(const Executable& exe);
  ProcessRunner& setFromShortcut(const MOShortcut& shortcut);

  ProcessRunner& setFromFileOrExecutable(
    const QString &executable,
    const QStringList &args,
    const QString &cwd,
    const QString &profile,
    const QString &forcedCustomOverwrite = "",
    bool ignoreCustomOverwrite = false);

  Results run();
  DWORD exitCode();


  bool runExecutable(const Executable& exe, bool refresh=true);

  bool runShortcut(const MOShortcut& shortcut);

  HANDLE runExecutableOrExecutableFile(
    const QString &executable,
    const QStringList &args,
    const QString &cwd,
    const QString &profile,
    const QString &forcedCustomOverwrite = "",
    bool ignoreCustomOverwrite = false);


  Results waitForApplication(
    HANDLE processHandle, LPDWORD exitCode, LockWidget::Reasons reason);

  Results waitForAllUSVFSProcessesWithLock(LockWidget::Reasons reason);

private:
  OrganizerCore& m_core;
  IUserInterface* m_ui;
  spawn::SpawnParameters m_sp;
  QString m_customOverwrite;
  ForcedLibraries m_forcedLibraries;
  QString m_profileName;
  LockWidget::Reasons m_lock;
  RefreshModes m_refresh;
  QString m_shellOpen;
  HANDLE m_handle;
  DWORD m_exitCode;

  HANDLE spawnAndWait(
    const QFileInfo &binary, const QString &arguments,
    const QString &profileName,
    const QDir &currentDirectory,
    const QString &steamAppID,
    const QString &customOverwrite,
    const QList<MOBase::ExecutableForcedLoadSetting> &forcedLibraries={},
    LPDWORD exitCode = nullptr);

  SpawnedProcess spawn(spawn::SpawnParameters sp);

  void withLock(
    LockWidget::Reasons reason, std::function<void (LockWidget&)> f);

  Results waitForProcessCompletionWithLock(
    HANDLE handle, LPDWORD exitCode, LockWidget::Reasons reason);

  Results waitForAllUSVFSProcesses(LockWidget& lock);
};

#endif // PROCESSRUNNER_H