OSDN Git Service

Shift_JIS->UTF-8化!?
[applistation/AppliStation.git] / na-get-lib / NaGet.InteropServices / ShellLink.cs
1 using System;\r
2 using System.Text;\r
3 using System.Runtime.InteropServices;\r
4 using System.Runtime.InteropServices.ComTypes;\r
5 using System.Diagnostics;\r
6 \r
7 namespace NaGet.InteropServices\r
8 {       \r
9         /// <summary>\r
10         /// ShellLinkの更新フラグ\r
11         /// </summary>\r
12         [Flags]\r
13         public enum ShellLinkResolve : uint\r
14         {\r
15                 // AnyMatch = 0x02, // winMe,win2k以降無効\r
16                 \r
17                 /// <summary>\r
18                 /// MSIを呼ぶ\r
19                 /// </summary>\r
20                 InvokeMSI = 0x80,\r
21                 /// <summary>\r
22                 /// 追跡禁止\r
23                 /// </summary>\r
24                 NoLinkInfo = 0x40,\r
25                 /// <summary>\r
26                 /// リンク先の解決ができないときダイアログを表示しない\r
27                 /// </summary>\r
28                 NoUi = 0x01,\r
29                 NoUiWithMsgPump = 0x101,\r
30                 /// <summary>\r
31                 /// リンク先のデータ更新を行わない\r
32                 /// </summary>\r
33                 NoUpdate = 0x07,\r
34                 /// <summary>\r
35                 /// 検索をしない\r
36                 /// </summary>\r
37                 NoSearch = 0x10,\r
38                 NoTrack = 0x20,\r
39                 /// <summary>\r
40                 /// リンク先を更新する\r
41                 /// </summary>\r
42                 Update = 0x04,\r
43         }\r
44         \r
45         [ComImport()]\r
46         [Guid("000214F9-0000-0000-C000-000000000046")]\r
47         [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]\r
48         public interface IShellLinkW\r
49         {\r
50                 void GetPath([MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile,\r
51                              int cchMaxPath, IntPtr pfd, uint fFlags);\r
52                 \r
53                 void GetIDList(out IntPtr ppidl);\r
54                 void SetIDList(IntPtr pidl);\r
55                 \r
56                 void GetDescription([MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDesc,\r
57                                          int cchMaxPath);\r
58                 void SetDescription(string pszDesc);\r
59                 \r
60                 void GetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir,\r
61                                          int cchMaxPath);\r
62                 void SetWorkingDirectory(string pszDir);\r
63                 \r
64                 void GetArguments([MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs,\r
65                                          int cchMaxPath);\r
66                 void SetArguments(string pszArgs);\r
67                 \r
68                 void GetHotkey(out short pwHotkey);\r
69                 void SetHotkey(short pwHotkey);\r
70                 \r
71                 void GetShowCmd(out uint piShowCmd);\r
72                 void SetShowCmd(uint piShowCmd);\r
73                 \r
74                 void GetIconLocation([MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath,\r
75                                          int cchMaxPath, out int piIcon);\r
76                 void SetIconLocation(string pszIconPath, int iIcon);\r
77                 \r
78                 void SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszPath,\r
79                                          int cchMaxPath, uint dwReserved);\r
80                 \r
81                 void Resolve(IntPtr hWnd, ShellLinkResolve fFlag);\r
82                                 \r
83                 void SetPath(string pszFile);\r
84         }\r
85 \r
86         /// <summary>\r
87         /// シェルリンク(ショートカット)のカプセルクラス\r
88         /// </summary>\r
89         public class ShellLink : IDisposable\r
90         {\r
91                 /// <summary>\r
92                 /// シェルリンクのCOMオブジェクト\r
93                 /// </summary>\r
94                 protected IShellLinkW shellLink;\r
95                 \r
96                 /// <summary>\r
97                 /// シェルリンクのGUID\r
98                 /// </summary>\r
99                 public const string ShellLinkGuid = "00021401-0000-0000-C000-000000000046";\r
100                 \r
101                 protected const int MAX_PATH = 260;\r
102                 \r
103                 public ShellLink()\r
104                 {\r
105                         Type shellLinkType = Type.GetTypeFromCLSID(new Guid(ShellLinkGuid));\r
106                         shellLink = (IShellLinkW) Activator.CreateInstance(shellLinkType);\r
107                 }\r
108                 \r
109                 public ShellLink(string path) : this()\r
110                 {\r
111                         if (! System.IO.File.Exists(path)) {\r
112                                 throw new System.IO.FileNotFoundException("File does not found", path);\r
113                         }\r
114                         \r
115                         ToPersistFile().Load(path, 0);\r
116                         Resolve(IntPtr.Zero, ShellLinkResolve.NoUpdate | ShellLinkResolve.NoUi);\r
117                 }\r
118                 \r
119                 /// <summary>\r
120                 /// シェルリンクの解析解決\r
121                 /// </summary>\r
122                 /// <param name="hWnd">親フレームのハンドル</param>\r
123                 /// <param name="fFlags">方法</param>\r
124                 public void Resolve(IntPtr? hWnd, ShellLinkResolve fFlags)\r
125                 {\r
126                         shellLink.Resolve(hWnd ?? IntPtr.Zero, fFlags);\r
127                 }\r
128                 \r
129                 /// <summary>\r
130                 /// IPersistFileとして取り出す\r
131                 /// </summary>\r
132                 /// <returns>IPersistFileにキャストされたCOMオブジェクト</returns>\r
133                 public IPersistFile ToPersistFile()\r
134                 {\r
135                         return (IPersistFile) shellLink;\r
136                 }\r
137                 \r
138                 /// <summary>\r
139                 /// リンク先パスを得る。コマンドラインを得るためにも\r
140                 /// </summary>\r
141                 /// <param name="fFlags">パスのタイプ(1:8.3形式; 2:UNCパス; 4:環境変数変換なし)</param>\r
142                 /// <returns>パス</returns>\r
143                 public string GetPath(uint fFlags)\r
144                 {\r
145                         StringBuilder sb = new StringBuilder(MAX_PATH);\r
146                         shellLink.GetPath(sb, sb.Capacity, IntPtr.Zero, fFlags);\r
147                         return sb.ToString();\r
148                 }\r
149                 \r
150                 /// <summary>\r
151                 /// リンク先パス(取得時には環境変数は展開されません)\r
152                 /// </summary>\r
153                 public string Path {\r
154                         get { return GetPath(0x04); }\r
155                         set { shellLink.SetPath(value); }\r
156                 }\r
157                 \r
158                 /// <summary>\r
159                 /// リンク先(引数)\r
160                 /// </summary>\r
161                 public string Arguments {\r
162                         get {\r
163                                 StringBuilder sb = new StringBuilder(MAX_PATH);\r
164                                 shellLink.GetArguments(sb, sb.Capacity);\r
165                                 return sb.ToString();\r
166                         }\r
167                         set { shellLink.SetArguments(value); }\r
168                 }\r
169                 \r
170                 /// <summary>\r
171                 /// 作業フォルダ\r
172                 /// </summary>\r
173                 public string WorkingDirectory {\r
174                         get {\r
175                                 StringBuilder sb = new StringBuilder(MAX_PATH);\r
176                                 shellLink.GetWorkingDirectory(sb, sb.Capacity);\r
177                                 return sb.ToString();\r
178                         }\r
179                         set { shellLink.SetWorkingDirectory(value); }\r
180                 }\r
181                 \r
182                 /// <summary>\r
183                 /// ウィンドウスタイル(ShowCmdのワッパ)\r
184                 /// </summary>\r
185                 public ProcessWindowStyle WindowStyle\r
186                 {\r
187                         get {\r
188                                 uint showcmd;\r
189                                 shellLink.GetShowCmd(out showcmd);\r
190                                 switch (showcmd) {\r
191                                         case 3:\r
192                                                 return ProcessWindowStyle.Maximized;\r
193                                         case 7:\r
194                                                 return ProcessWindowStyle.Minimized;\r
195                                         case 1:\r
196                                         default:\r
197                                                 return ProcessWindowStyle.Normal;\r
198                                 }\r
199                         }\r
200                         set {\r
201                                 switch (value) {\r
202                                         case ProcessWindowStyle.Normal:\r
203                                                 shellLink.SetShowCmd(1);\r
204                                                 break;\r
205                                         case ProcessWindowStyle.Maximized:\r
206                                                 shellLink.SetShowCmd(3);\r
207                                                 break;\r
208                                         case ProcessWindowStyle.Minimized:\r
209                                         case ProcessWindowStyle.Hidden:\r
210                                                 shellLink.SetShowCmd(7);\r
211                                                 break;\r
212                                 }\r
213                         }\r
214                 }\r
215                 \r
216                 /// <summary>\r
217                 /// アイコンの場所を得る\r
218                 /// </summary>\r
219                 /// <param name="iconPath">アイコンを含むファイルパス</param>\r
220                 /// <param name="iconIndex">アイコンのインデックス</param>\r
221                 public void GetIconLocation(out string iconPath, out int iconIndex)\r
222                 {\r
223                         StringBuilder sb = new StringBuilder(MAX_PATH);\r
224                         shellLink.GetIconLocation(sb, sb.Capacity, out iconIndex);\r
225                         iconPath = sb.ToString();\r
226                 }\r
227                 \r
228                 /// <summary>\r
229                 /// アイコンの場所を設定する\r
230                 /// </summary>\r
231                 /// <param name="iconPath">アイコンを含むファイルパス</param>\r
232                 /// <param name="iconIndex">アイコンのインデックス</param>\r
233                 public void SetIconLocation(string iconPath, int iconIndex)\r
234                 {\r
235                         shellLink.SetIconLocation(iconPath, iconIndex);\r
236                 }\r
237                 \r
238                 /// <summary>\r
239                 /// COMオブジェクトの開放\r
240                 /// </summary>\r
241                 public void Dispose()\r
242                 {\r
243                         if (shellLink != null) {\r
244                                 Marshal.ReleaseComObject(shellLink);\r
245                                 shellLink = null;\r
246                         }\r
247                 }\r
248 \r
249                 /// <summary>\r
250                 /// シェルリンクの中身をプロセス情報として取得する。起動の際に利用\r
251                 /// </summary>\r
252                 /// <returns>プロセス起動情報化されたシェルリンクの情報</returns>\r
253                 public ProcessStartInfo ToProcessStartInfo()\r
254                 {\r
255                         ProcessStartInfo procInfo = new ProcessStartInfo();\r
256                         procInfo.FileName = GetPath(0);\r
257                         procInfo.Arguments = Arguments;\r
258                         procInfo.WorkingDirectory = WorkingDirectory;\r
259                         procInfo.WindowStyle = WindowStyle;\r
260                         \r
261                         return procInfo;\r
262                 }\r
263                 \r
264                 /// <summary>\r
265                 /// プロセス情報からシェルリンクオブジェクトを生成\r
266                 /// </summary>\r
267                 /// <param name="procInfo">プロセス情報</param>\r
268                 /// <returns>生成されたシェルリンクオブジェクト</returns>\r
269                 public static ShellLink CreateFromProcessStartInfo(ProcessStartInfo procInfo)\r
270                 {\r
271                         ShellLink shelllink = new ShellLink();\r
272                         shelllink.Path = procInfo.FileName;\r
273                         shelllink.Arguments = procInfo.Arguments;\r
274                         shelllink.WorkingDirectory = procInfo.WorkingDirectory;\r
275                         shelllink.WindowStyle = procInfo.WindowStyle;\r
276                         \r
277                         return shelllink;\r
278                 }\r
279         }\r
280 }\r