July, 2010

...now browsing by month

 

Display Windows Message Box from Console App

Tuesday, July 27th, 2010

In a Console app, you normally write out message to screen using Console.WriteLine(). How should I display a Windows message box like we usually do in a Windows Form app?

Call the MessageBox method from user32.dll COM API is one of the methods I learned, and here were how it was done (no need to set reference to user32.dll; just do DllImport):

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Runtime.InteropServices;

 

namespace ComInterop

{

class Message

{

 

public static void ShowMessage(string msg,string caption)

{

 

//MessageBox(new IntPtr(0), msg, caption, 0); //type=0 only show OK button

MsgBox(new IntPtr(0), msg, caption, 1); //Type=1 shows both OK and Cancel button

 

 

}

[DllImport(“user32.dll”)]

private static extern int MessageBox(IntPtr hwnd, String text, String caption, uint type);

//if want to use different method name other than what’s given in the type lib, use EntryPoint attribute

[DllImport(“user32.dll”, EntryPoint = “MessageBox”)]

private static extern int MsgBox(IntPtr hwnd, String text, String caption, uint type);

}

 

class Program

{

static void Main(string[] args)

{

//user32.dll DLLImport

Message.ShowMessage(“This method used DllImport”, “DllImport is Cool”);

}

}

 

}

 

Playing with sapi.dll

Tuesday, July 27th, 2010

With Microsoft’s Speech Library, it is extremely easy to add voice to your .Net application.

I created a small Console app in VS2010 and here were the steps I took:

  1. Add reference to sapi.dll, which was found in my computer’s C:\Program Files\Common Files\Microsoft Shared\Speech (Windows XP SP2)
  2. Import the Speech type library namespace
  3. Instantiated a SpVoice and called the Speak method; that was all.
Sample codes:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SpeechLib;
namespace ComInterop
{
class Speech
{
public static void SayThis(string words)
{
SpVoice voice = new SpVoice();
voice.Speak(words, SpeechVoiceSpeakFlags.SVSFDefault);
}
}
static void Main(string[] args)
{
////speech library
Console.WriteLine(“Type a few words to speak”);
string words = Console.ReadLine();
Speech.SayThis(words);
Console.ReadKey();
}
}

 

Directory Access Control

Sunday, July 25th, 2010

The other day I was playing with ACL and got myself locked out of a directory that I tried to access. Then I tried to add a new FileSystemAccessRule with FullControl right and Allow type, hoping to regain the access to the folder; but it turned out that was not the way to do it. I had to call RemoveAccessRule from the DirectorySecurity object in order to re-grant myself access to the folder. So I figured I would make a note here so that myself and others can use as reference when things about ACL get murky again in the future.

To grant a Windows user access to a specific directory, use the following codes (need using these namespaces : System.Security.Principal,System.Security.AccessControl,System.IO)

 

public static void GrantDirectoryAccess(string dir, string userName)

{

DirectorySecurity ds = Directory.GetAccessControl(dir);

ds.AddAccessRule(new FileSystemAccessRule(userName,FileSystemRights.FullControl, AccessControlType.Allow));

Directory.SetAccessControl(dir,ds);

 

}

To deny user Read access to the folder, use the following:

public static void DenyDirectoryAccess(string dir, string username)

{

DirectorySecurity ds = Directory.GetAccessControl(dir);

ds.AddAccessRule(new FileSystemAccessRule(username,FileSystemRights.Read, AccessControlType.Deny));

Directory.SetAccessControl(dir,ds);

}

 

If you want to give user back the access right, you would think that by running GrantDirectoryAccess() method again you can achieve that, correct? Wrong! The ACL rule is if there are Deny and Allow access types both tied to a user or a user group, then the Deny will take precedence.

So, in order to give the access right back, you’ll need to remove the access rule by running the codes below instead:

public static void RemoveDirectoryDeny(string dir, string userName)

{

DirectorySecurity ds = Directory.GetAccessControl(dir);

ds.RemoveAccessRule(new FileSystemAccessRule(userName, FileSystemRights.Read, AccessControlType.Deny));

Directory.SetAccessControl(dir, ds);

}

Here is the sample of how to grant user “steve” access to “c:\test” folder, then deny it, thn re-grant it:

static void Main(string[] args)

{

Console.WriteLine(“Messing around with C:\test”);

//first grant fullcontrol access

GrantDirectoryAccess(@”c:\test”,”steve);

//then deny the Read access

DenyDirectoryAccess(@”c:\test”, “Steve”);

//Tried to run GrantDirectoryAccess() again and see if it worked;, it didn’t

//Had to remove the Deny rule

UserSecurity.RemoveDirectoryDeny(@”c:\test”, “Steve”);

Console.WriteLine(“Access to c:\test has been regained. Press any key to exit”);

Console.ReadKey(true);

 

}