Notifying a message in Action center.
Revision | 8394dde3e27502f8c141d2be3b207720e6f99eec (tree) |
---|---|
Time | 2015-09-10 10:05:48 |
Author | JeffyTS <JeffyTS@outl...> |
Commiter | JeffyTS |
Add /pos option.
@@ -443,6 +443,32 @@ namespace CtrlVix | ||
443 | 443 | } |
444 | 444 | } |
445 | 445 | |
446 | + public int GetVMProcessID(string vmxFilePath) | |
447 | + { | |
448 | + string vmxName = Path.GetFileNameWithoutExtension(vmxFilePath); // VM 名を作成 | |
449 | + | |
450 | + ManagementPath mngmntPath = new ManagementPath("Win32_Process"); | |
451 | + ManagementClass mngmntClass = new ManagementClass(mngmntPath); | |
452 | + | |
453 | + ManagementObjectCollection mngmntObjClctn = mngmntClass.GetInstances(); | |
454 | + foreach (ManagementObject obj in mngmntObjClctn) | |
455 | + { | |
456 | + object commandLineObj = obj["CommandLine"]; | |
457 | + if (commandLineObj != null) | |
458 | + { | |
459 | + string commandLine = commandLineObj.ToString(); | |
460 | + if (0 <= commandLine.IndexOf("vmplayer")) | |
461 | + { | |
462 | + if (0 <= commandLine.IndexOf(vmxName)) | |
463 | + { | |
464 | + return int.Parse(obj["ProcessId"].ToString()); | |
465 | + } | |
466 | + } | |
467 | + } | |
468 | + } | |
469 | + return 0; | |
470 | + } | |
471 | + | |
446 | 472 | private int getVMState(string vmxFilePath) |
447 | 473 | { |
448 | 474 | // VMwareの動作状態をチェック |
@@ -19,7 +19,7 @@ namespace VMwPlayerTaskTray | ||
19 | 19 | { |
20 | 20 | // This Program Name |
21 | 21 | private const string PROGRAM_NAME = "VMwPlayerTaskTray"; |
22 | - | |
22 | + | |
23 | 23 | // Messages |
24 | 24 | private const string MSG_USAGE = "Gust OS's vmx file not be in argument.\r\n" + |
25 | 25 | "\r\n" + |
@@ -28,7 +28,8 @@ namespace VMwPlayerTaskTray | ||
28 | 28 | "\r\n" + |
29 | 29 | " Option:\r\n" + |
30 | 30 | // for Player 12 " /gui | /nogui | (none)"; |
31 | - " /gui | (none)"; | |
31 | + " /gui | (none)\r\n" + | |
32 | + " /pos num_left num_top"; | |
32 | 33 | private const string MSG_RUN_DUP = PROGRAM_NAME + " has been already running with \r\n" + |
33 | 34 | "same guest OS.\r\n" + |
34 | 35 | "\r\n" + |
@@ -28,7 +28,8 @@ namespace VMwPlayerTaskTray | ||
28 | 28 | "\r\n" + |
29 | 29 | " Option:\r\n" + |
30 | 30 | // for Player 12 " /gui | /nogui | (none)"; |
31 | - " /gui | (none)"; | |
31 | + " /gui | (none)\r\n" + | |
32 | + " /pos left top | (none)"; | |
32 | 33 | private const string MSG_VIX_ERR = "A fatal error has occured inside VIX.\r\n" + |
33 | 34 | "Exiting " + PROGRAM_NAME + "..."; |
34 | 35 | private const string MSG_CONFIRM = "Are you sure?\r\n" + |
@@ -80,7 +81,6 @@ namespace VMwPlayerTaskTray | ||
80 | 81 | #if DEBUG |
81 | 82 | Debug.WriteLine("Start VMControl Thread"); |
82 | 83 | #endif |
83 | - | |
84 | 84 | await Task.Run(() => |
85 | 85 | { |
86 | 86 | ret = subVMControl(mode); // VM Control |
@@ -105,7 +105,7 @@ namespace VMwPlayerTaskTray | ||
105 | 105 | } |
106 | 106 | this.timer_MainForm.Enabled = true; // Timerを有効にする |
107 | 107 | } |
108 | - | |
108 | + | |
109 | 109 | private bool subVMControl(VMCTRL mode) |
110 | 110 | { |
111 | 111 | Constants.VMSTATE state; |
@@ -178,6 +178,15 @@ namespace VMwPlayerTaskTray | ||
178 | 178 | if (state == CtrlVix.Constants.VMSTATE.ERROR) return false; |
179 | 179 | System.Threading.Thread.Sleep(3000); |
180 | 180 | } |
181 | + if (mode == VMCTRL.GO_GUI) | |
182 | + { | |
183 | + /*** | |
184 | + while(CtrlVix.Constants. TOOLS_RUNNING.NOT_RUNNING == Vix.CheckToolsRunning(vmxFilePath)){ | |
185 | + System.Threading.Thread.Sleep(3000); | |
186 | + } | |
187 | + ***/ | |
188 | + movePlayerWindow(); // Player Windowを移動する | |
189 | + } | |
181 | 190 | break; |
182 | 191 | case VMCTRL.GO_ACPI_RESET: |
183 | 192 | case VMCTRL.GO_RESET: |
@@ -487,5 +496,116 @@ namespace VMwPlayerTaskTray | ||
487 | 496 | asmCpyrght.Copyright + "\r\n"; |
488 | 497 | MessageBox.Show(message, PROGRAM_NAME, MessageBoxButtons.OK, MessageBoxIcon.Information); |
489 | 498 | } |
499 | + | |
500 | + private bool movePlayerWindow() | |
501 | + { | |
502 | + CtrlVIX Vix = new CtrlVIX(); | |
503 | + | |
504 | + int pid = Vix.GetVMProcessID(vmxFilePath); | |
505 | + | |
506 | + if (pid != 0) | |
507 | + { | |
508 | + if (move_window(pid, Program.moveWindow_left, Program.moveWindow_top)) // Windowを移動する | |
509 | + { | |
510 | + return true; | |
511 | + } | |
512 | + } | |
513 | + return false; | |
514 | + } | |
515 | + | |
516 | + [System.Runtime.InteropServices.DllImport("user32.dll")] private extern static IntPtr GetParent(IntPtr hwnd); | |
517 | + [System.Runtime.InteropServices.DllImport("user32.dll")] private extern static IntPtr GetWindow(IntPtr hWnd, int wCmd); | |
518 | + [System.Runtime.InteropServices.DllImport("user32.dll")] private extern static IntPtr FindWindow(String lpClassName, String lpWindowName); | |
519 | + [System.Runtime.InteropServices.DllImport("user32.dll")] private extern static IntPtr GetWindowThreadProcessId(IntPtr hWnd, out int lpdwprocessid); | |
520 | + [System.Runtime.InteropServices.DllImport("user32.dll")] private extern static int IsWindowVisible(IntPtr hWnd); | |
521 | + [System.Runtime.InteropServices.DllImport("user32.dll")] private extern static IntPtr GetAncestor(IntPtr hWnd, uint gaFlags); | |
522 | + private struct RECT | |
523 | + { | |
524 | + public int Left { get; set; } | |
525 | + public int Top { get; set; } | |
526 | + public int Right { get; set; } | |
527 | + public int Bottom { get; set; } | |
528 | + } | |
529 | + [System.Runtime.InteropServices.DllImport("user32.dll")] private extern static bool GetWindowRect(IntPtr hWnd, out RECT lpRect); | |
530 | + [System.Runtime.InteropServices.DllImport("user32.dll")] private extern static bool MoveWindow(IntPtr hWnd, int x, int y, int nWidth, int nHeight, int bRepaint); | |
531 | + [System.Runtime.InteropServices.DllImport("user32.dll")] private extern static IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, int wParam, StringBuilder lParam); | |
532 | + [System.Runtime.InteropServices.DllImport("user32.dll")] private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount); | |
533 | + [System.Runtime.InteropServices.DllImport("user32.dll")] private static extern int GetWindowTextLength(IntPtr hWnd); | |
534 | + [System.Runtime.InteropServices.DllImport("user32.dll")] private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount); | |
535 | + [System.Runtime.InteropServices.DllImport("user32.dll")] private extern static IntPtr FindWindowEx(IntPtr hWndParent, IntPtr hWndChildAfter, String lpszClass, String lpszWindow); | |
536 | + | |
537 | + // 指定したPIDのWindowを移動させる | |
538 | + private bool move_window(int pid, int left, int top) | |
539 | + { | |
540 | + RECT rect = new RECT(); | |
541 | + rect.Left = 0; rect.Top = 0; rect.Right = 0; rect.Bottom = 0; | |
542 | + const int bRepaint_TRUE = 1; // TRUE for MoveWindow() = redraw | |
543 | + IntPtr hWnd = IntPtr.Zero; | |
544 | + IntPtr hWndChildAfter = IntPtr.Zero; | |
545 | + | |
546 | + if ((hWnd = getHwndFromPid(pid)) == IntPtr.Zero) | |
547 | + { | |
548 | + return false; | |
549 | + } | |
550 | + if (!GetWindowRect(hWnd, out rect)) | |
551 | + { | |
552 | + return false; | |
553 | + } | |
554 | + if (!MoveWindow(hWnd, left, top, rect.Right - rect.Left, rect.Bottom - rect.Top, bRepaint_TRUE)) | |
555 | + { | |
556 | + return false; | |
557 | + } | |
558 | + System.Threading.Thread.Sleep(1000); | |
559 | + if (!GetWindowRect(hWnd, out rect)) | |
560 | + { | |
561 | + return false; | |
562 | + } | |
563 | + if (rect.Left != left || rect.Top != top) | |
564 | + { | |
565 | + return false; | |
566 | + } | |
567 | + return true; | |
568 | + } | |
569 | + | |
570 | + // プロセスID(pid)をウィンドウハンドル(hWnd)に変換する | |
571 | + private IntPtr getHwndFromPid(int pid) | |
572 | + { | |
573 | + IntPtr hWnd; | |
574 | + const int GW_HWNDNEXT = 2; // for GetWindow() | |
575 | + // GetAncestor() | |
576 | + // const uint GA_PARENT = 1; | |
577 | + // const uint GA_ROOT = 2; | |
578 | + const uint GA_ROOTOWNER = 3; | |
579 | + IntPtr parent = IntPtr.Zero, root = IntPtr.Zero, rootowner=IntPtr.Zero; | |
580 | + | |
581 | + hWnd = FindWindow(null, null); | |
582 | + while (hWnd != IntPtr.Zero) | |
583 | + { | |
584 | + if (GetParent(hWnd) == IntPtr.Zero && IsWindowVisible(hWnd) != 0) | |
585 | + { | |
586 | + if (pid == getPidFromHwnd(hWnd)) | |
587 | + { | |
588 | + // return hWnd | |
589 | + return rootowner; // 現在のではなくてひとつ前のroot ownerを返す | |
590 | + } | |
591 | + } | |
592 | + // parent = GetAncestor(hWnd, GA_PARENT); | |
593 | + // root = GetAncestor(hWnd, GA_ROOT); | |
594 | + rootowner = GetAncestor(hWnd, GA_ROOTOWNER); | |
595 | + hWnd = GetWindow(hWnd, GW_HWNDNEXT); | |
596 | + } | |
597 | + return IntPtr.Zero; | |
598 | + } | |
599 | + | |
600 | + // ウィンドウハンドル(hWnd)をプロセスID(pid)に変換する | |
601 | + private int getPidFromHwnd(IntPtr hWnd) | |
602 | + { | |
603 | + int pid; | |
604 | + | |
605 | + GetWindowThreadProcessId(hWnd, out pid); | |
606 | + return pid; | |
607 | + } | |
608 | + | |
609 | + | |
490 | 610 | } |
491 | 611 | } |
@@ -11,6 +11,9 @@ namespace VMwPlayerTaskTray | ||
11 | 11 | // グローバル変数 |
12 | 12 | public static string vmxFilePath = ""; |
13 | 13 | public static string startMode = ""; |
14 | + public static bool moveWindow = false; | |
15 | + public static int moveWindow_left; | |
16 | + public static int moveWindow_top; | |
14 | 17 | |
15 | 18 | /// <summary> |
16 | 19 | /// アプリケーションのメイン エントリ ポイントです。 |
@@ -25,18 +28,29 @@ namespace VMwPlayerTaskTray | ||
25 | 28 | // Application.Run(new Form1()); |
26 | 29 | |
27 | 30 | string[] cmds = System.Environment.GetCommandLineArgs(); |
28 | - foreach (string cmd in cmds) | |
31 | + for(int i=0; i < cmds.Length; i++) | |
29 | 32 | { |
30 | - if ((0 <= cmd.IndexOf(":\\")) && (0 <= cmd.IndexOf(".vmx"))) | |
33 | + if ((0 <= cmds[i].IndexOf(":\\")) && (0 <= cmds[i].IndexOf(".vmx"))) | |
31 | 34 | { |
32 | - vmxFilePath = cmd; | |
35 | + vmxFilePath = cmds[i]; | |
33 | 36 | } |
34 | - else if ((0 <= cmd.IndexOf("/gui") || (0 <= cmd.IndexOf("/nogui")))) | |
37 | + else if ((0 <= cmds[i].IndexOf("/gui") || (0 <= cmds[i].IndexOf("/nogui")))) | |
35 | 38 | { |
36 | - startMode = cmd; | |
39 | + startMode = cmds[i]; | |
37 | 40 | } |
38 | - } | |
41 | + else if (0 <= cmds[i].IndexOf("/pos")) | |
42 | + { | |
43 | + int x, y; | |
39 | 44 | |
45 | + if (int.TryParse(cmds[i+1], out x) && int.TryParse(cmds[i+2], out y)) | |
46 | + { | |
47 | + moveWindow_left = x; | |
48 | + moveWindow_top = y; | |
49 | + moveWindow = true; | |
50 | + i += 2; | |
51 | + } | |
52 | + } | |
53 | + } | |
40 | 54 | new MainForm(); |
41 | 55 | |
42 | 56 | if (vmxFilePath != "") |
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices; | ||
32 | 32 | // すべての値を指定するか、下のように '*' を使ってビルドおよびリビジョン番号を |
33 | 33 | // 既定値にすることができます: |
34 | 34 | // [assembly: AssemblyVersion("1.0.*")] |
35 | -[assembly: AssemblyVersion("1.1.3.*")] | |
36 | -[assembly: AssemblyFileVersion("1.1.3.0")] | |
35 | +[assembly: AssemblyVersion("1.1.4.*")] | |
36 | +[assembly: AssemblyFileVersion("1.1.4.0")] |
@@ -7,7 +7,7 @@ | ||
7 | 7 | Installing: |
8 | 8 | You can copy VMwPlayerTaskTray files to any folder. |
9 | 9 | VMwPlayerTaskTray can work any folder. It never use any registry-key. |
10 | - You need .NET Framework 4.5 or later. | |
10 | + You need .NET Framework 4.5. | |
11 | 11 | |
12 | 12 | Files: |
13 | 13 | VMwPlayerTaskTray.exe |
@@ -21,7 +21,8 @@ | ||
21 | 21 | [NOTE] |
22 | 22 | You might be better to use shortcut files. See sample.lnk property. |
23 | 23 | Option: |
24 | - /gui | /nogui | (none) | |
24 | + /gui | (none) | |
25 | + /pos left top | (none) | |
25 | 26 | |
26 | 27 | Thanks to VMware,Inc and Microsoft Corporation. |
27 | 28 | This program has been developed on |
@@ -43,6 +44,11 @@ Rlease & modify | ||
43 | 44 | 2015/01/31 1.1.1 Improved checking whether VM tools running. |
44 | 45 | 2015/02/02 1.1.2 Changed Icons. |
45 | 46 | 2015/09/06 1.1.3 Disabled GO NoGUI menu and Changed to Any CPU for VMware Workstation Player12. |
47 | + Change developping envionment | |
48 | + VMware Workstation Player 12.0.0 and VMware VIX 1.15.0 | |
49 | + Visual Studio Community 2015 | |
50 | + Windows10 Professional 64bit. | |
51 | + 2015/02/02 1.1.4 Add /pos option. | |
46 | 52 | |
47 | 53 | |
48 | 54 |