프로젝트

일반

사용자정보

통계
| 브랜치(Branch): | 개정판:

markus / ConvertService / ServiceBase / Markus.Service.Extensions / Exntensions / Process.cs @ ab7fe8c0

이력 | 보기 | 이력해설 | 다운로드 (7.13 KB)

1
using System;
2
using System.Collections.Generic;
3
using System.Diagnostics;
4
using System.Linq;
5
using System.Management;
6
using System.Text;
7
using System.Threading.Tasks;
8

    
9
namespace Markus.Service.Extensions
10
{
11
    public static class ProcessExtension
12
    {
13
        /// <summary>
14
        /// 프로세스의 명령줄을 가져온다.
15
        /// </summary>
16
        /// <param name="process"></param>
17
        /// <returns></returns>
18
        public static ProcessArguments Arguments(this Process process)
19
        {
20
            ProcessArguments result = new ProcessArguments();
21

    
22
            var commandLine = ProcessCommandLinesQuery(process.Id);
23

    
24
            try
25
            {
26
                if (!string.IsNullOrWhiteSpace(commandLine))
27
                {
28
                    result.WorkingDirectory = ProcessWorkingDirectory(commandLine);
29
                    result.CommandLine = SplitArguments(RemoveCommadLinesFilePath(commandLine)).ToList();
30
                }
31
                else
32
                {
33
                    
34
                    result.IsArgumentsNull = true;
35
                }
36
            }
37
            catch (Exception ex)
38
            {
39
                System.Diagnostics.Debug.WriteLine(ex.ToString());
40
            }
41
            return result;
42
        }
43

    
44
        /// <summary>
45
        /// 프로세스의 실행 경로
46
        /// </summary>
47
        /// <param name="process"></param>
48
        /// <returns></returns>
49
        public static string WorkingDirectory(this Process process)
50
        {
51
            var commandLine = ProcessCommandLinesQuery(process.Id);
52
            return ProcessWorkingDirectory(commandLine);
53
        }
54

    
55
        private static string ProcessCommandLinesQuery(int processId)
56
        {
57
            string result = "";
58

    
59
            string wmiQuery = string.Format("select CommandLine from Win32_Process where ProcessId ='{0}'", processId);
60

    
61
            ManagementObjectSearcher searcher = new ManagementObjectSearcher(wmiQuery);
62
            ManagementObjectCollection retObjectCollection = searcher.Get();
63

    
64
            if (retObjectCollection.Count > 0)
65
            {
66
                if (retObjectCollection.Cast<ManagementObject>().First()["CommandLine"] != null)
67
                {
68
                    result = retObjectCollection.Cast<ManagementObject>().First()["CommandLine"]?.ToString();
69
                }
70
                else
71
                {
72
                    result = "";
73
                }
74
            }
75

    
76
            return result;
77
        }
78

    
79
        private static string ProcessWorkingDirectory(string commandLine)
80
        {
81
           if (IO.FileExists(commandLine.Replace("\"", "")))
82
            {
83
                var file = new System.IO.FileInfo(commandLine.Replace("\"", ""));
84
                return file.DirectoryName;
85
            }
86

    
87
            var splitCommand = commandLine.Split(' ');
88
            string filePath = "";
89

    
90
            for (int i = 0; i < splitCommand.Count(); i++)
91
            {
92
                filePath += " " + splitCommand[i].Replace("\"", "");
93

    
94
                if (IO.FileExists(filePath))
95
                {
96
                    System.IO.FileInfo info = new System.IO.FileInfo(filePath);
97
                    filePath = info.DirectoryName;
98
                    break;
99
                }
100
                else if (i == splitCommand.Count() - 1)
101
                {
102
                    var firstCmd = splitCommand.First();
103

    
104
                    if (firstCmd.StartsWith("\"") && firstCmd.EndsWith("\""))
105
                    {
106
                        filePath = firstCmd.Replace("\"", "");
107
                    }
108
                }
109
                else
110
                {
111
                    filePath = commandLine;
112
                }
113
            }
114

    
115
            return filePath;
116
        }
117

    
118
        /// <summary>
119
        /// command line에서 처음에 있는 파일 경로가 \"로 묶여 있거나 묶여 있지 않은 경우가 있다.
120
        /// 파일 경로를 제거하기 위한 코드
121
        /// </summary>
122
        /// <param name="commandLine"></param>
123
        /// <returns></returns>
124
        private static string RemoveCommadLinesFilePath(string commandLine)
125
        {
126
            string result = "";
127

    
128
            var splitCommand = commandLine.Split(' ');
129
            string filePath = "";
130

    
131
            for (int i = 0; i < splitCommand.Count(); i++)
132
            {
133
                filePath += " " + splitCommand[i];
134

    
135
                if (IO.FileExists(filePath.Replace("\"", "")))
136
                {
137
                    result = string.Join(" ", splitCommand.Skip(i + 1).Take(splitCommand.Count() - i));
138
                    break;
139
                }
140
                else if (i == splitCommand.Count() - 1)
141
                {
142
                    var firstCmd = splitCommand.First();
143

    
144
                    if (firstCmd.StartsWith("\"") && firstCmd.EndsWith("\""))
145
                    {
146
                        result = string.Join(" ", splitCommand.Skip(1).Take(splitCommand.Count() - 1));
147
                    }
148
                }
149
                else
150
                {
151
                    result = commandLine;
152
                }
153
            }
154

    
155
            return result;
156
        }
157

    
158
        public static string[] SplitArguments(string commandLine)
159
        {
160
            List<string> args = new List<string>();
161
            List<char> currentArg = new List<char>();
162
            char? quoteSection = null; // Keeps track of a quoted section (and the type of quote that was used to open it)
163
            char[] quoteChars = new[] { '\'', '\"' };
164
            char previous = ' '; // Used for escaping double quotes
165

    
166
            for (var index = 0; index < commandLine.Length; index++)
167
            {
168
                char c = commandLine[index];
169
                if (quoteChars.Contains(c))
170
                {
171
                    if (previous == c) // Escape sequence detected
172
                    {
173
                        previous = ' '; // Prevent re-escaping
174
                        if (!quoteSection.HasValue)
175
                        {
176
                            quoteSection = c; // oops, we ended the quoted section prematurely
177
                            continue;         // don't add the 2nd quote (un-escape)
178
                        }
179

    
180
                        if (quoteSection.Value == c)
181
                            quoteSection = null; // appears to be an empty string (not an escape sequence)
182
                    }
183
                    else if (quoteSection.HasValue)
184
                    {
185
                        if (quoteSection == c)
186
                            quoteSection = null; // End quoted section
187
                    }
188
                    else
189
                        quoteSection = c; // Start quoted section
190
                }
191
                else if (char.IsWhiteSpace(c))
192
                {
193
                    if (!quoteSection.HasValue)
194
                    {
195
                        args.Add(new string(currentArg.ToArray()));
196
                        currentArg.Clear();
197
                        previous = c;
198
                        continue;
199
                    }
200
                }
201

    
202
                currentArg.Add(c);
203
                previous = c;
204
            }
205

    
206
            if (currentArg.Count > 0)
207
                args.Add(new string(currentArg.ToArray()));
208

    
209
            return args.ToArray();
210
        }
211
    }
212
}
클립보드 이미지 추가 (최대 크기: 500 MB)