24.5.08

Windows Forms/WPF i komandno-linijska aplikacija u jednom...?

Nedavno sam na jednom projektu imao zathjev da se aplikacija može pokrenuti u sučelju u kojem korisnik interaktivno može postavljati parametre procesiranja, te da se ta ista aplikacija može pokrenuti u komandnoj liniji gdje se svi parametri procesiranja postavljaju kao komandno-linijski argumenti.

Iako na prvu problem ne zvuči komplicirano ugrađena podrška za takav scenarij ne postoji u .NET Frameworku. Ukoliko za projekt Windows aplikacije Output type promijenimo u Console Application...

image

image

...rezultat neće biti ono što bi se svakome svidjelo:

image

Srećom Win32 API ima metode kojima se to može riještiti.

private const uint ATTACH_PARENT_PROCESS = 0x0ffffffff;

[DllImport("kernel32.dll")]
public static extern bool AllocConsole();

public static bool AttachConsole()
{
return AttachConsole(ATTACH_PARENT_PROCESS);
}

[DllImport("kernel32.dll")]
public static extern bool AttachConsole(uint dwProcessId);

[DllImport("kernel32.dll")]
public static extern bool FreeConsole();


Korištenjem navedenih P/Invoke metoda možemo otvoriti samo konzolu ili samo Windows aplikaciju kao u slijedećem kodu:



static void Main(string[] args)
{
if (args.Length > 0 && args[0].Equals("/cmd"))
{
if (!AttachConsole())
{
AllocConsole();
}

// do Console.* work...

FreeConsole();
}
else
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}


AttachConsole će se pokušati spojiti na postojeću konzolu (ako je aplikacija pokrenuta iz komandne linije), a ako ne uspije (AttachConsole vrati false) pozvat ćemo AllocConsole što će kreirati novu konzolu i u njoj izvršiti aplikaciju. FreeConsole na kraju pozivamo kako bismo oslobodili lock na trenutnu konzolu.



smile_shades

No comments: