Kendi serverımızda çalışması için yazdığım CMS uygulamasında CMS üzerinde eklenen her websitesi için IIS'e binding eklememiz gerekiyordu. Bu işlemi manuel yapmak zaman kaybı. Bende bu işi yapan bir konsol uygulaması yazdım ve websitesinden bu konsol uygulamasını çalıştıran ve programdan dönüş değerini okuyan bir method yazdım. Burda kodun tamamını vermeyeceğim ancak basitçe bu işlemi nasıl yapabileceğinizi anlatacağım.
Öncelikle yazının başında kendi serverımız diye başlamamın sebebi, bu tarz bir uygulamada büyük ihtimalle admin haklarına ihtiyacınız olacak. Eğer admin kullanıcı adı ve şifresine sahipseniz konsol uygulamasını nasıl impersonate edeceğinizi bir sonraki yazımda anlatacağım, şimdilik basit bir websitesi üzerinden basit bir konsol uygulaması çalıştıralım. Yazının sonunda uygulamanın örnek kodlarını indirebilirsiniz.
Websitesi üzerinde bu işlemi yapmak için tek ihtiyacımız olan şey aşağıdaki method.
///
/// Konsol uygulamasına parametre göndererek çalıştırır ve dönen değeri alır.
///
///Gönderilecek parametreler (virgül ile ayrılmış)
/// string
private static string ExecuteConsoleApp(string arguments)
{
var process = new System.Diagnostics.Process();
process.StartInfo.FileName = @"D:\Works\TestArea\ASPNETConsole\ConsoleApp\bin\Debug\ConsoleApp.exe"; // konsol uygulamasının tam yolu
process.StartInfo.Arguments = arguments;
process.StartInfo.RedirectStandardOutput = true; // standart output, bu sayede dönüş değerini okuyacağız
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true; // programın ekranda gözükmesini istemiyoruz
process.Start();
string retVal = process.StandardOutput.ReadToEnd().Trim();
process.Close();
return retVal;
}
Bu methodu bir butonun onclick olayına yazığımızı varsayalım.
protected void Button1_Click(object sender, EventArgs e)
{
// Label1 adlı label kontrolümüze konsol uygulamasından dönen değeri yazacağız
// konsol uygulamasına parametre olarak action1 gönderiyoruz, istersek hiçbişey göndermeyebiliriz
Label1.Text = ExecuteConsoleApp("action1");
}
Örnek olarak kullanacağımız konsol uygulamasının Main methodu
static void Main(string[] args)
{
// gelen parametreye göre başka işlemler yaptırabiliriz
switch (args[0])
{
case "action1": Console.WriteLine("action 1 executed"); break; // parametre action1 ise ekrana action 1 executed yazalım
case "action2": Console.WriteLine("action 2 executed"); break; // parametre action2 ise ekrana action 2 executed yazalım
}
}
Konsol uygulamamıza parametre göndererek çalıştırdık ve dönüş değerini aldık. Benim yazmış olduğum bu basit uygulamayı geliştirip başka işler yapmasını sağlayabilirsiniz.
Programın kodlarına aşağıdan indirebilirsiniz.
ASPNETConsole.rar (21,22 kb)
Solution dosyası VS2010 ile hazırlanmıştır ve Framework 3.5 kullanılmıştır.
Güncelleme
(20.12.2011)
Yazıda bahsettiğim fakat sonradan paylaşmadığım, konsol uygulamasında admin haklarla işlem yapmak için gerekli kodu paylaşıyorum.
Konsol uygulamasının içerisinde, işlem yapmadan önce ImpersonateAdmin() methodunu çağırarak işlem yaparsak admin haklara sahip oluyoruz.
static void ImpersonateAdmin()
{
string user = "admin_user";
string userDomain = "admin_domain";
string password = "admin_password";
bool impersonate = true;
IntPtr userHandle = new IntPtr(0);
WindowsImpersonationContext impersonatedUser = null;
if (impersonate)
{
bool returnValue = LogonUser(
user,
userDomain,
password,
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT,
ref userHandle
);
if (!returnValue)
{
throw new Exception("Invalid Username");
}
WindowsIdentity newId = new WindowsIdentity(userHandle);
impersonatedUser = newId.Impersonate();
}
}
//
// Bu bölüm impersonation için gerekli
//
public const int LOGON32_LOGON_INTERACTIVE = 2;
public const int LOGON32_LOGON_SERVICE = 3;
public const int LOGON32_PROVIDER_DEFAULT = 0;
[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
public static extern bool LogonUser(
String lpszUserName,
String lpszDomain,
String lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken
);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public extern static bool CloseHandle(IntPtr handle);