我有一个外部应用程序,它在运行时生成一些数据并存储它(它是一个窗口应用程序 - 而不是控制台应用程序)。现在我正在创建自己的应用程序来分析这些数据。问题是外部软件必须同时运行。
当用户打开我的应用程序时,我希望它自动启动外部应用程序并将其隐藏。我在这个主题上搜索了很多,并尝试了一些我发现的建议。首先我试过了:
Process p = new Process();
p.StartInfo.FileName = @"c:\app.exe";
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p.StartInfo.UseShellExecute = false;
p.StartInfo.WorkingDirectory = @"c:\";
p.StartInfo.CreateNoWindow = true;
p.Start();
这会启动外部应用程序,但不会隐藏它。 然后我读到命令promt可以隐藏应用程序:
ProcessStartInfo psi = new ProcessStartInfo("cmd.exe", "/c \""c:\app.exe\"");
psi.UseShellExecute = false;
psi.CreateNoWindow = true;
psi.WindowStyle = ProcessWindowStyle.Hidden;
Process.Start(psi);
同样,这会启动应用程序非隐藏。
然后我考虑启动应用程序然后隐藏它。我找到了以下内容:
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
var Handle = FindWindow(null, "Application Caption");
ShowWindow(Handle, 0);
这将隐藏窗口。问题是应用程序在此状态下处于非活动状态,并且不会生成任何数据。
编辑:我更接近可接受的解决方案(尽量减少而不是隐藏)。由于外部应用程序启动有点慢,我会执行以下操作:
Process p = new Process();
p.StartInfo.FileName = @"c:\app.exe";
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p.StartInfo.UseShellExecute = false;
p.StartInfo.WorkingDirectory = @"c:\";
p.StartInfo.CreateNoWindow = true;
p.Start();
while (true)
{
int style = GetWindowLong(psi.MainWindowHandle, -16); // -16 = GWL_STYLE
if ((style & 0x10000000) != 0) // 0x10000000 = WS_VISIBLE
{
ShowWindow(psi.MainWindowHandle, 0x06);
break;
}
Thread.Sleep(200);
}
这也不起作用,但我相信这是朝着正确方向迈出的一步。
有没有办法启动和隐藏外部应用程序,同时保持活动状态?
祝你好运
答案 0 :(得分:1)
我通过以下方式使其成功:
const int GWL_STYLE = -16;
const long WS_VISIBLE = 0x10000000;
while (true)
{
var handle = FindWindow(null, "Application Caption");
if (handle == IntPtr.Zero)
{
Thread.Sleep(200);
}
else
{
int style = GetWindowLong(handle, GWL_STYLE);
if ((style & WS_VISIBLE) != 0)
{
ShowWindow(handle, 0x06);
break;
}
}
}