應用程序A(例如:AutoCAD,Word,...)運行時,它將在運行時調用DLL X來執行任務→打開表單登錄如何在其他應用程序中關閉1個應用程序的表單?
應用程序B(例如:Photoshop,Excel .. 。)當運行時,它會在運行時調用DLL Y執行任務→我想關閉上面的登錄表單可以這樣做嗎?
這可能嗎?
應用程序A(例如:AutoCAD,Word,...)運行時,它將在運行時調用DLL X來執行任務→打開表單登錄如何在其他應用程序中關閉1個應用程序的表單?
應用程序B(例如:Photoshop,Excel .. 。)當運行時,它會在運行時調用DLL Y執行任務→我想關閉上面的登錄表單可以這樣做嗎?
這可能嗎?
這是一個小示例,展示瞭如何在另一個進程中關閉窗口。創建一個新的Windows窗體項目,將它添加兩種形式,並在第一個添加兩個按鈕,並把這些代碼在Form1中:
public partial class Form1 : Form
{
delegate bool EnumWindowsProc(IntPtr Hwnd, IntPtr lParam);
[DllImport("user32", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private extern static bool EnumThreadWindows(int threadId, EnumWindowsProc callback, IntPtr lParam);
[DllImport("user32", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool EnumChildWindows(IntPtr hwndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam);
[DllImport("user32", SetLastError = true, CharSet = CharSet.Auto)]
private extern static int GetWindowText(IntPtr hWnd, StringBuilder text, int maxCount);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
private const int WM_CLOSE = 0x10;
public Form1()
{
InitializeComponent();
button1.Click += button1_Click;
button2.Click += button2_Click;
}
private void button1_Click(object sender, EventArgs e)
{
var frm = new Form2();
frm.Show(this);
}
private void button2_Click(object sender, EventArgs e)
{
Process[] processes = Process.GetProcessesByName("FindWindowSample");
foreach (Process p in processes)
{
var handle = FindWindowInProcess(p, x => x == "Form2");
if (handle != IntPtr.Zero)
{
SendMessage(handle, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
}
}
}
public static IntPtr FindWindowInProcess(Process process, Func<string, bool> compareTitle)
{
IntPtr windowHandle = IntPtr.Zero;
foreach (ProcessThread t in process.Threads)
{
windowHandle = FindWindowInThread(t.Id, compareTitle);
if (windowHandle != IntPtr.Zero)
{
break;
}
}
return windowHandle;
}
private static IntPtr FindWindowInThread(int threadId, Func<string, bool> compareTitle)
{
IntPtr windowHandle = IntPtr.Zero;
EnumThreadWindows(threadId, (hWnd, lParam) =>
{
StringBuilder text = new StringBuilder(200);
GetWindowText(hWnd, text, 200);
if (compareTitle(text.ToString()))
{
windowHandle = hWnd;
return false;
}
return true;
}, IntPtr.Zero);
return windowHandle;
}
}
編譯並運行應用程序的兩個實例。在第一次單擊Button1以顯示Form2。在第二個實例上點擊Button2從第一個實例關閉Form2。
以及如果只是關閉正在運行的proccess最簡單的方法很可能是像類似
using System.Diagnostics;
var autocad = Process.GetProcesses().FirstOrDefault(w=>w.ProcessName == "AutoCAD");
autocad.Close();
打開你大概可以循環proccesses爲所需的名稱。它不是非常冒險,但它會完成工作,如果它剛剛打開和關閉你的後面
我想關閉在AutoCAD中被打開的形式,但AutoCAD中沒有關閉(不退出) – Oosutsuke
所以you're試圖關閉被通過AutoCAD中打開,但只有對話而不是整個的AutoCAD proccess? – subkonstrukt
是的,它是真實的一種形式。 – Oosutsuke
你可以用一個(只是一個例子)無窗口控制檯應用程序來檢查新進程。我有一個例子:
做一個控制檯應用程序和登錄表單
使控制檯應用程序Windows應用程序像這樣的一個新項目:
請在檢查過程中的控制檯應用程序定時器:
public static bool IsOpen = false;
static void Main(string[] args)
{
Timer t = new Timer(TimerCallback, null, 0, 1200);
while (true)
{
//keep it running
}
}
private static void TimerCallback(Object o)
{
if (!IsOpen && Process.GetProcesses().Select(r => r.ProcessName).Contains("EXCEL"))
{
//Excel is running, show the form
Form1 loginForm = new Form1();
loginForm.ShowDialog();
//Stop it from spawning a million forms by setting bool
IsOpen = true;
}
}
關閉表單時,應用程序可以關閉此計時器內部放太多的邏輯,用同樣的方式。
要打開控制檯窗口形式,但是你需要將引用添加到控制檯應用程序:
如果你想進程名稱:
只需使用一種形式,補充一點:
foreach (var proc in Process.GetProcesses())
{
MessageBox.Show(proc.ProcessName);
}
這將顯示當前正在運行的所有進程的名稱。
cad,excel等是非常糟糕的例子。 –
@LeiYang他們和任何人一樣好,這不是一個好主意,因爲你將不得不惹上ROT。 Oosutsuke你應該谷歌ROT和實現東西在計時器 – EpicKip
@雷洋:我**只是想**的例子(CAD,單詞,...)很容易想象。因爲我不知道如何,我希望有人提出想法。 EpicKip:謝謝。我會谷歌ROT! – Oosutsuke