以 C#.Net 形式托管进程会禁用某些进程的按钮
Hosting a process in C#.Net form disables some process's buttons
我正在尝试在我的 .net 应用程序(主要是视频查看软件)中托管一个 .exe,但是某些应用程序不允许我使用它们的菜单或某些控件。以前有没有人遇到过这个问题,或者知道为什么会发生这种情况?
这是我托管应用程序的代码:
#region Methods/Consts for Embedding a Window
[DllImport("user32.dll", EntryPoint = "GetWindowThreadProcessId", SetLastError = true,
CharSet = CharSet.Unicode, ExactSpelling = true,
CallingConvention = CallingConvention.StdCall)]
private static extern long GetWindowThreadProcessId(long hWnd, long lpdwProcessId);
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", SetLastError = true)]
private static extern long SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
[DllImport("user32.dll", EntryPoint = "GetWindowLongA", SetLastError = true)]
private static extern long GetWindowLong(IntPtr hwnd, int nIndex);
[DllImport("user32.dll")]
static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
[DllImport("user32.dll", SetLastError = true)]
private static extern long SetWindowPos(IntPtr hwnd, long hWndInsertAfter, long x, long y, long cx, long cy, long wFlags);
[DllImport("user32.dll", SetLastError = true)]
private static extern bool MoveWindow(IntPtr hwnd, int x, int y, int cx, int cy, bool repaint);
[DllImport("user32.dll", EntryPoint = "PostMessageA", SetLastError = true)]
private static extern bool PostMessage(IntPtr hwnd, uint Msg, int wParam, int lParam);
private const int SWP_NOOWNERZORDER = 0x200;
private const int SWP_NOREDRAW = 0x8;
private const int SWP_NOZORDER = 0x4;
private const int SWP_SHOWWINDOW = 0x0040;
private const int WS_EX_MDICHILD = 0x40;
private const int SWP_FRAMECHANGED = 0x20;
private const int SWP_NOACTIVATE = 0x10;
private const int SWP_ASYNCWINDOWPOS = 0x4000;
private const int SWP_NOMOVE = 0x2;
private const int SWP_NOSIZE = 0x1;
private const int GWL_STYLE = (-16);
private const int WS_VISIBLE = 0x10000000;
private const int WM_CLOSE = 0x10;
private const int WS_CHILD = 0x40000000;
private const int WS_MAXIMIZE = 0x01000000;
#endregion
#region Variables
private IntPtr hostedProcessHandle;
private Process hostedProcess = null;
private ProcessStartInfo hostedPSI = new ProcessStartInfo();
#endregion
//Helper method to start a process contained within the form
private void HostProcess(string processPath)
{
//Start the process located at processPath
hostedPSI.FileName = processPath;
hostedPSI.Arguments = "";
hostedPSI.WindowStyle = ProcessWindowStyle.Maximized;
hostedProcess = System.Diagnostics.Process.Start(hostedPSI);
//Stop watch is used to calculate time out period.
Stopwatch sw = new Stopwatch();
sw.Start();
//Loop to aquire application handle. Exit loop if the time out period is past.
do
{
hostedProcessHandle = hostedProcess.MainWindowHandle;
if (sw.ElapsedMilliseconds > 10000) throw new TimeoutException();
} while (hostedProcessHandle == new IntPtr(0));
//Host the process in the forms panel.
SetParent(hostedProcessHandle, this.panel1.Handle);
SetWindowLong(hostedProcessHandle, GWL_STYLE, WS_VISIBLE + WS_MAXIMIZE);
MoveWindow(hostedProcessHandle, 10, 10, this.panel1.Width - 20, this.panel1.Height - 20, true);
}
private void CloseHostedProcess()
{
hostedProcess.Kill();
}
这是我托管 VLC 的测试应用程序的屏幕截图,您可以看到一些菜单和按钮显示为灰色且无法使用:
这不仅仅是 VLC 的问题——我在托管其他应用程序时也看到了这个问题。
只是一个更新。如果我右键单击 VLC -> 播放 -> 添加并手动播放视频,菜单栏将再次工作。但是底部的视频控件仍然不起作用!滚动时它们会改变颜色,但单击它们仍然不起作用!
我遇到问题的原因似乎是因为 TeamViewer 运行 在后台运行。我目前正在尝试找出这导致我出现问题的原因,但停止 TeamViewer 的进程似乎可以解决我的问题。
我正在尝试在我的 .net 应用程序(主要是视频查看软件)中托管一个 .exe,但是某些应用程序不允许我使用它们的菜单或某些控件。以前有没有人遇到过这个问题,或者知道为什么会发生这种情况?
这是我托管应用程序的代码:
#region Methods/Consts for Embedding a Window
[DllImport("user32.dll", EntryPoint = "GetWindowThreadProcessId", SetLastError = true,
CharSet = CharSet.Unicode, ExactSpelling = true,
CallingConvention = CallingConvention.StdCall)]
private static extern long GetWindowThreadProcessId(long hWnd, long lpdwProcessId);
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", SetLastError = true)]
private static extern long SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
[DllImport("user32.dll", EntryPoint = "GetWindowLongA", SetLastError = true)]
private static extern long GetWindowLong(IntPtr hwnd, int nIndex);
[DllImport("user32.dll")]
static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
[DllImport("user32.dll", SetLastError = true)]
private static extern long SetWindowPos(IntPtr hwnd, long hWndInsertAfter, long x, long y, long cx, long cy, long wFlags);
[DllImport("user32.dll", SetLastError = true)]
private static extern bool MoveWindow(IntPtr hwnd, int x, int y, int cx, int cy, bool repaint);
[DllImport("user32.dll", EntryPoint = "PostMessageA", SetLastError = true)]
private static extern bool PostMessage(IntPtr hwnd, uint Msg, int wParam, int lParam);
private const int SWP_NOOWNERZORDER = 0x200;
private const int SWP_NOREDRAW = 0x8;
private const int SWP_NOZORDER = 0x4;
private const int SWP_SHOWWINDOW = 0x0040;
private const int WS_EX_MDICHILD = 0x40;
private const int SWP_FRAMECHANGED = 0x20;
private const int SWP_NOACTIVATE = 0x10;
private const int SWP_ASYNCWINDOWPOS = 0x4000;
private const int SWP_NOMOVE = 0x2;
private const int SWP_NOSIZE = 0x1;
private const int GWL_STYLE = (-16);
private const int WS_VISIBLE = 0x10000000;
private const int WM_CLOSE = 0x10;
private const int WS_CHILD = 0x40000000;
private const int WS_MAXIMIZE = 0x01000000;
#endregion
#region Variables
private IntPtr hostedProcessHandle;
private Process hostedProcess = null;
private ProcessStartInfo hostedPSI = new ProcessStartInfo();
#endregion
//Helper method to start a process contained within the form
private void HostProcess(string processPath)
{
//Start the process located at processPath
hostedPSI.FileName = processPath;
hostedPSI.Arguments = "";
hostedPSI.WindowStyle = ProcessWindowStyle.Maximized;
hostedProcess = System.Diagnostics.Process.Start(hostedPSI);
//Stop watch is used to calculate time out period.
Stopwatch sw = new Stopwatch();
sw.Start();
//Loop to aquire application handle. Exit loop if the time out period is past.
do
{
hostedProcessHandle = hostedProcess.MainWindowHandle;
if (sw.ElapsedMilliseconds > 10000) throw new TimeoutException();
} while (hostedProcessHandle == new IntPtr(0));
//Host the process in the forms panel.
SetParent(hostedProcessHandle, this.panel1.Handle);
SetWindowLong(hostedProcessHandle, GWL_STYLE, WS_VISIBLE + WS_MAXIMIZE);
MoveWindow(hostedProcessHandle, 10, 10, this.panel1.Width - 20, this.panel1.Height - 20, true);
}
private void CloseHostedProcess()
{
hostedProcess.Kill();
}
这是我托管 VLC 的测试应用程序的屏幕截图,您可以看到一些菜单和按钮显示为灰色且无法使用:
这不仅仅是 VLC 的问题——我在托管其他应用程序时也看到了这个问题。
只是一个更新。如果我右键单击 VLC -> 播放 -> 添加并手动播放视频,菜单栏将再次工作。但是底部的视频控件仍然不起作用!滚动时它们会改变颜色,但单击它们仍然不起作用!
我遇到问题的原因似乎是因为 TeamViewer 运行 在后台运行。我目前正在尝试找出这导致我出现问题的原因,但停止 TeamViewer 的进程似乎可以解决我的问题。