BSD Magazine releases its May 2010 Issue.
Hello all,
BSDMag just released the may issue. Get it here.
Archive for April 2010
Hello all,
BSDMag just released the may issue. Get it here.
Hey all,
I have a process that is a C# process. I need to do something different if someone just double-clicks the application than if it is launched by a certain other process. So I decided to check the parent process.
I couldn’t find a simple C# only method. But I did find a code snippet that works. There were actually lots of posts on that provided the following code snippet or variations thereof, so I consider it to be public domain. So obviously I didn’t write this part.
private static Process GetParentProcess()
{
int iParentPid = 0;
int iCurrentPid = Process.GetCurrentProcess().Id;
IntPtr oHnd = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (oHnd == IntPtr.Zero)
return null;
PROCESSENTRY32 oProcInfo = new PROCESSENTRY32();
oProcInfo.dwSize =
(uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(PROCESSENTRY32));
if (Process32First(oHnd, ref oProcInfo) == false)
return null;
do
{
if (iCurrentPid == oProcInfo.th32ProcessID)
iParentPid = (int)oProcInfo.th32ParentProcessID;
}
while (iParentPid == 0 && Process32Next(oHnd, ref oProcInfo));
if (iParentPid > 0)
return Process.GetProcessById(iParentPid);
else
return null;
}
static uint TH32CS_SNAPPROCESS = 2;
[StructLayout(LayoutKind.Sequential)]
public struct PROCESSENTRY32
{
public uint dwSize;
public uint cntUsage;
public uint th32ProcessID;
public IntPtr th32DefaultHeapID;
public uint th32ModuleID;
public uint cntThreads;
public uint th32ParentProcessID;
public int pcPriClassBase;
public uint dwFlags;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szExeFile;
};
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr CreateToolhelp32Snapshot(uint dwFlags, uint th32ProcessID);
[DllImport("kernel32.dll")]
static extern bool Process32First(IntPtr hSnapshot, ref PROCESSENTRY32 lppe);
[DllImport("kernel32.dll")]
static extern bool Process32Next(IntPtr hSnapshot, ref PROCESSENTRY32 lppe);
}
I took this code snippet and improved upon it and made myself the following static class. This class more easily exposes:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Runtime.InteropServices;
namespace ParentProcess
{
public class ParentProcess
{
public static String ProcessName
{
get { return GetParentProcess().ProcessName; }
}
public static int ProcessId
{
get { return GetParentProcess().Id; }
}
public static String FullPath
{
get
{
return GetParentProcess().MainModule.FileName;
}
}
public static String FileName
{
get
{
return System.IO.Path.GetFileName(GetParentProcess().MainModule.FileName);
}
}
public static String DirectoryName
{
get
{
return System.IO.Path.GetDirectoryName(GetParentProcess().MainModule.FileName);
}
}
private static Process GetParentProcess()
{
int iParentPid = 0;
int iCurrentPid = Process.GetCurrentProcess().Id;
IntPtr oHnd = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (oHnd == IntPtr.Zero)
return null;
PROCESSENTRY32 oProcInfo = new PROCESSENTRY32();
oProcInfo.dwSize =
(uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(PROCESSENTRY32));
if (Process32First(oHnd, ref oProcInfo) == false)
return null;
do
{
if (iCurrentPid == oProcInfo.th32ProcessID)
iParentPid = (int)oProcInfo.th32ParentProcessID;
}
while (iParentPid == 0 && Process32Next(oHnd, ref oProcInfo));
if (iParentPid > 0)
return Process.GetProcessById(iParentPid);
else
return null;
}
static uint TH32CS_SNAPPROCESS = 2;
[StructLayout(LayoutKind.Sequential)]
public struct PROCESSENTRY32
{
public uint dwSize;
public uint cntUsage;
public uint th32ProcessID;
public IntPtr th32DefaultHeapID;
public uint th32ModuleID;
public uint cntThreads;
public uint th32ParentProcessID;
public int pcPriClassBase;
public uint dwFlags;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szExeFile;
};
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr CreateToolhelp32Snapshot(uint dwFlags, uint th32ProcessID);
[DllImport("kernel32.dll")]
static extern bool Process32First(IntPtr hSnapshot, ref PROCESSENTRY32 lppe);
[DllImport("kernel32.dll")]
static extern bool Process32Next(IntPtr hSnapshot, ref PROCESSENTRY32 lppe);
}
}
This makes it easier for me to simply include the class above in my code and make simple calls:
String exename = ParentProcess.FileName; String FullPathToExe = ParentProcess.FullPath; String DirectoryInWhichExeResides= ParentProcess.DirectoryName;
…and the pid and process name, etc…
I hope this helps you.
References
http://www.facebook.com/note.php?note_id=73447531256
http://www.debugging.com/bug/6657
http://www.eggheadcafe.com/software/aspnet/35541264/how-to-get-the-parent-pro.aspx
Hey all,
Today I was working on XML Serialization.
After learning how to do it, I discovered it takes four lines of code to write an XML and four lines of code to read in an XML.
However, I prefer one line of code to four so I made a Serializer.cs class with two static functions.
After thinking about it, I made these classes generic so they work with any type. I hope this helps someone.
using System;
using System.IO;
using System.Xml.Serialization;
namespace BlogTool
{
public class Serializer
{
#region Functions
public static void SerializeToXML(T t, String inFilename)
{
XmlSerializer serializer = new XmlSerializer(t.GetType());
TextWriter textWriter = new StreamWriter(inFilename);
serializer.Serialize(textWriter, t);
textWriter.Close();
}
public static T DeserializeFromXML(String inFilename)
{
XmlSerializer deserializer = new XmlSerializer(typeof(T));
TextReader textReader = new StreamReader(inFilename);
T retVal = (T)deserializer.Deserialize(textReader);
textReader.Close();
return retVal;
}
#endregion
}
}
So now if you have a class you can more easily serialize it to and from an XML.
Here is an example Project that contains these files:
Blog.cs
using System;
namespace BlogTool
{
[Serializable()]
public class Blog
{
#region Member Variables
String mBlogUrl;
String mCategory;
#endregion
#region Constructors
public Blog()
{
}
public Blog(String inURL, String inCategory)
{
mBlogUrl = inURL;
mCategory = inCategory;
}
#endregion
#region Properties
public String BlogUrl
{
get { return mBlogUrl; }
set { mBlogUrl= value; }
}
public String Category
{
get { return mCategory; }
set { mCategory= value; }
}
#endregion
}
}
BlogList.cs
using System.Collections.Generic;
namespace BlogTool
{
[Serializable]
public class BlogList
{
#region Member Variables
List mBlogs = new List();
#endregion
#region Constructors
/*
* The default constructor
*/
public BlogList()
{
}
#endregion
#region Properties
public List Blogs
{
get { return mBlogs; }
set { mBlogs = value; }
}
#endregion
}
}
Program.cs
namespace BlogTool
{
class Program
{
static void Main(string[] args)
{
BlogList bloglist = new BlogList();
Blog b1 = new Blog("http://rhyous.com","Software");
Blog b2 = new Blog("http://www.alittletipsy.com", "Crafts");
bloglist.Blogs.Add(b1);
bloglist.Blogs.Add(b2);
Serializer.SerializeToXML(bloglist, "FavoriteBlogs.xml");
}
}
}
Serializer.cs
using System;
using System.IO;
using System.Xml.Serialization;
namespace BlogTool
{
public class Serializer
{
#region Functions
public static void SerializeToXML(T t, String inFilename)
{
XmlSerializer serializer = new XmlSerializer(t.GetType());
TextWriter textWriter = new StreamWriter(inFilename);
serializer.Serialize(textWriter, t);
textWriter.Close();
}
public static T DeserializeFromXML(String inFilename)
{
XmlSerializer deserializer = new XmlSerializer(typeof(T));
TextReader textReader = new StreamReader(inFilename);
T retVal = (T)deserializer.Deserialize(textReader);
textReader.Close();
return retVal;
}
#endregion
}
}
Ok, so now that you have the files, you can run this program.
In the bin\debug or bin\release directory where you executable is placed when you build, you will see the FavoriteBlogs.xml file. The XML should look as follows:
<!--?xml version="1.0" encoding="utf-8"?-->
http://rhyous.com
Software
http://www.alittletipsy.com
Crafts
I know, this is not written very well as a walk-thru, but I wrote it fast. Maybe I will clean it up later.
The following is my complete Serializer class after it was in use for a while and tested for a while.
using System;
using System.IO;
using System.Xml.Serialization;
using System.Xml;
using System.Threading;
namespace CoveringArrayXmlExample
{
public static class Serializer
{
#region Functions
/// <summary>
/// This function writes the serialized XML to the file name passed in.
/// </summary>
/// <typeparam name="T">The object type to serialize.</typeparam>
/// <param name="t">The instance of the object.</param>
/// <param name="outFilename">The file name. It can be a full path.</param>
public static void SerializeToXML<T>(T t, String outFilename, XmlSerializerNamespaces inNameSpaces = null)
{
if (outFilename.Contains(@"\"))
{
String[] dirs = outFilename.Split(@"\".ToCharArray());
for (int i = 0; i < dirs.Length - 1; i++)
{
if (!Directory.Exists(dirs[i]))
Directory.CreateDirectory(dirs[i]);
}
}
XmlSerializerNamespaces ns = inNameSpaces;
if (ns == null)
{
ns = new XmlSerializerNamespaces();
ns.Add("", "");
}
XmlSerializer serializer = new XmlSerializer(t.GetType());
TextWriter textWriter = (TextWriter)new StreamWriter(outFilename);
serializer.Serialize(textWriter, t, ns);
textWriter.Close();
}
/// <summary>
/// This function returns the serialized XML as a string
/// </summary>
/// <typeparam name="T">The object type to serialize.</typeparam>
/// <param name="t">The instance of the object.</param>
/// <param name="outString">The string that will be passed the XML.</param>
public static String SerializeToXML<T>(T t, XmlSerializerNamespaces inNameSpaces = null)
{
XmlSerializerNamespaces ns = inNameSpaces;
if (ns == null)
{
ns = new XmlSerializerNamespaces();
ns.Add("", "");
}
XmlSerializer serializer = new XmlSerializer(t.GetType());
TextWriter textWriter = (TextWriter)new StringWriter();
serializer.Serialize(textWriter, t, ns);
return textWriter.ToString();
}
/// <summary>
/// This function deserializes the XML file passed in.
/// </summary>
/// <typeparam name="T">The object type to serialize.</typeparam>
/// <param name="inFilename">The file or full path to the file.</param>
/// <returns>The object that was deserialized from xml.</returns>
public static T DeserializeFromXML<T>(String inFilename)
{
// Wait 1 second if file doesn't exist, in case we are waiting on a
// separate thread and beat it here.
if (!File.Exists(inFilename))
Thread.Sleep(1000);
// File should exist by now.
if (File.Exists(inFilename))
{
XmlSerializer deserializer = new XmlSerializer(typeof(T));
TextReader textReader = (TextReader)new StreamReader(inFilename);
XmlTextReader reader = new XmlTextReader(textReader);
try { reader.Read(); }
catch { }
T retVal = (T)deserializer.Deserialize(reader);
textReader.Close();
return retVal;
}
else
{
throw new FileNotFoundException(inFilename);
}
}
/// <summary>
/// This function deserializes the XML string passed in.
/// </summary>
/// <typeparam name="T">The object type to serialize.</typeparam>
/// <param name="inString">The string containing the XML.</param>
/// <returns>The object that was deserialized from xml.</returns>
public static T DeserializeFromXML<T>(ref String inString)
{
XmlSerializer deserializer = new XmlSerializer(typeof(T));
TextReader textReader = (TextReader)new StringReader(inString);
T retVal = (T)deserializer.Deserialize(textReader);
textReader.Close();
return retVal;
}
#endregion
}
}
Sources:
http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.aspx
http://www.switchonthecode.com/tutorials/csharp-tutorial-xml-serialization
Ok, so I have an IBM T40 and I am installed PC-BSD 8. Then for fun, I downloaded a more recent snapshot (PCBSD 8-Stable) and installed that.
However, woe is me, I ran into this FreeBSD bug: 131087. This prevents me from using my Wireless, which on a laptop is a show stopper.
So I got out the release version of the PCBSD 8 installer and tried to install again, however, now it fails.
Here is the log:
Running: find-update-parts kern.geom.debugflags: 0 -> 16 Cleaning up ad0 Running: dd if=/dev/zero of=/dev/ad0 count=2048 2048+0 records in 2048+0 records out 1048576 bytes transferred in 0.391058 secs (2681383 bytes/sec) Running fdisk on ad0 Running: fdisk -I /dev/ad0 fdisk: invalid fdisk partition table found fdisk: Class not found ******* Working on device /dev/ad0 ******* ERROR: The slice ad0s1 doesn't exist! FDISK Failure Running: umount /cdmnt-install umount: /cdmnt-install: statfs: No such file or directory umount: /cdmnt-install: unknown file system
So obviously something is broke with the partition table. I am not sure if this can be duplicated but it sure is annoying.
So how do I fix this? Well, right now I decided to use dd to wipe my drive.
dd if=/dev/zero of=/dev/ad0 bs=4096k
That took something more than an hour and then I reinstalled an all worked fine.
Anyway, I wonder if there is a bug with the installer that caused this or if this is a result of the multiple crashes that occurred due to the iwi bug that causes kernel panic.
Hello all,
I thought I would share my experiences of using PCBSD 8 on an IBM T40. I am going to put the information in separate headings, and I am going to document who is responsible for the feature I am talking about by prefacing each line with the responsible party. If it is a positive experience, the responsible party will be in Green. If it is a negative experience the responsible party will be in Red.
I am probably going to reinstall and do all this over again with the “snapshot” version and look for any improvements and try to submit any bugs/suggestions to Kris and his team.
Intel Pentium M
ATI Radeon Mobility M7 LQ (Mobility Radeon 7500 (fdds)
Intel PRO/Wireless 2200BG
Realtek AC97 Audio
Intel 82801DB PRO/100 VE Network Connection
UltraATA/100 EIDE Controller
34 GB 5400 RPM drive
9:20 AM started boot process
9:25 AM Finished configuring and clicked “Install”
9:37 AM 47% finished
Sorry, I was pulled away for an hour so I don’t know how long hte install took. I did find an install log, but unfortunately it had no date stamps. I rebooted before I realized that the log file itself might have had a timestamp.
PCBSD: So I don’t know how long the install took but it felt too long. I wonder if there are some tricks that can be done to speed this up. For example, the install could use an image. It could lay down the image, then extend the last partition to fill the drive, and then modify the key files after the image is laid down, add any packages not included in the image.
PCBSD: Adding the “Run X in Vesa mode” as item 6 is pretty cool.
PCBSD: Adding the “Run the Display setup wizard” is nice, so you can try to use a different video card post setup.
PCBSD: Single user mode and other boot options normal to FreeBSD still exist.
PCBSD: Splash screen works (this is an x86 box)
PCBSD: The bootup takes too long, there should be some ways to speed it up.
FreeBSD: I like to have a shorter delay when booting. 10 seconds is too long for me. So I added this to /boot/loader.conf
# Boot Options
autoboot_delay=”3″
Update: So I reinstalled because I tried a PC-BSD 8-stable snapshot, but ran into a FreeBSD bug, so I returned to PCBSD 8 release. On Reinstall, the ATI-3D-Enabled drivers worked, so I am editing this to say so. I am not sure why they didn’t appear to work the first time. Maybe because I had tried the Radeon settings first, I don’t know.
PCBSD: On first boot, there was a great interface for configuring Xorg.
PCBSD: This has a Radeon card, but there was no option for Radeon, just ATI or Radeonhd and neither worked really.
Note: I found another solution that added 3D features I wanted. See the Xorg and KDE4 Features section.
Networking
FreeBSD: Wired networking worked using DHCP without me having to do anything.
FreeBSD: Unplugging the wired network and plugging into a different subnet does not automatically cause dhclient to run again. So in order to get new IP settings, I had to run /etc/netstart as root. It didn’t work the first time either, I had to run it again.
PCBSD/KDE4: I couldn’t easily find a network tool to configure WIFI. I finally found it under System Settings.
PCBSD/KDE4: Once I did find the Newtork Configuration tool, it was easy to use and I connected to my WPA2 secured wireless network using a D-Link DIR-615 router. It worked very well and I downloaded a lot with no hiccups.
FreeBSD/ACPI: Put machine to sleep. Worked fine.
FreeBSD/ACPI/moused: Woke machine up. No mouse. Had to use Ctrl + Alt + F1 to get a command prompt and fix this by restarting the moused daemon.
Note: Added this line before exit 0 in the /etc/rc.resume. This doesn’t resolve the bug, but restarts the mouse so it works, which is a workaround, but workable none-the-less.
/etc/rc.d/moused/restart
PCBSD/FreeBSD: Closing the lid does not put the machine to sleep.
Note: I fixed this by added this line to the /etc/sysctl.conf
hw.acpi.lid_switch_state=S3
After making the above settings, you can run this command to change it in the current booted system so you don’t have to reboot. But the setting in /etc/sysctl.conf is what makes this persist on reboot.
sysctl -w hw.acpi.lid_switch_state=S3
PCBSD: Ports Console is easily confused with a regular console as Icon Text is not always looked at, I recommend a different icon and naming it Ports Jail. I created this for myself.
KDE4/PCBSD: The fonts were a little off for the four default icons vs the background…but this only seems to be an issue with dark backgrounds.
Shutdown and Reboot works as a regular user by default.
KDE4: After selecting Reboot or Shutdown, there is a hesitation before the shutdown/reboot popup, so I sometimes double click. I don’t like how the shutdown/reboot popup just disappears if a second click occurs with the mouse anywhere but on the shutdown/reboot popup.
Firefox/Flash/FreeBSD: YouTube – Went online and clicked on one of the first videos and it played.
Update: Do to a reinstall, I noticed that choosing ATI 3D actually worked an enabled 3D features. I will check on the settings below to see whey they set.
Even though I had a Radeon, only the ATI or ATI 3D drivers worked. The RadeonHd drivers did not work. Probably because it is an old Radeon and not a new RadeonHd.
Note: I got the Radeon driver to work myself by using the xorg.conf from the ati3d settting and changing the “Device” section to use the settings below. I didn’t make these up on my own, I found them here: http://userweb.cs.utexas.edu/~walter/geek/linux-t40.html#video
Section "Device" Identifier "ATI Radeon" Driver "radeon" Option "DynamicClocks" "on" Option "AGPMode" "4" Option "RenderAccel" "on" Option "EnablePageFlip" "on" Option "BIOSHotkeys" "on" BusID "PCI:1:0:0" EndSection
After doing this, I got much better settings as described below:
Xorg/KDE4: Konsole supports transparency when using ATI 3D.
Xorg/KDE4/3D: Moving the cursor to the top of the screen will do a cool screen where it shows your configured screen in a line from left to right (four by default though I always change to 3).
Xorg/KDE4/3D: Moving the cursor to the top right corner of the screen will do a cool screen where it shows your configured screens in a 3D object (cube or pyramid).
Ctrl + Alt + Backspace is disabled
Ctrl + Alt + F1 does display the terminal sessions and then:
Alt + F2, F3, F4, …, F8 will all take you to one of the open console terminal sessions.
Alt + F9 returns you to your Xorg seesion
KDE4/PCBSD: Alt + F1 does NOT open the start bar. Right-clicking on the Fireball and choosing Application Launcher settings shows no shortcut, so you can configure it if desired. When I install KDE4 the default is Alt + F1, not None, so I assume this is something PCBSD changed.
KDE4: After selecting Reboot or Shutdown, I don’t like how the reboot option or shutdown option just disappears if I click with the mouse on the desktop.
PCBSD: PBIs make installing software fairly easy.
PCBSD: There are not enough PBIs.
PCBSD: The size of PBIs are HUGE, which is by design, they include every library they need to run, but by design or not, they are huge.
PCBSD: I installed Firefox and Open Office and Pidgin post install because there are updated version to those on disk anyway.
KDE4/Firefox: Firefox prompts every single time I open it to be the default browser. Saying yes appears to do nothing. I manually went to KDE4′s System Settings and change the default application for the web browser to be /Programs/bin/firefox3.sh and this issue stopped.
PCBSD: K3b installed perfected first try.
PCBSD: K3b burnt a DVD (the latest PC-BSD snapshot) without having to perform any tweak, and for those who know how many tweaks are required when using just FreeBSD and not PC-BSD, you know why this is awesome.
Every boot when loading KDE4, the following error displays: The profile “” has been selected but it does not exist.
I plan to update this from time to time with my experiences, so this post is in no way final.
Hello all,
PC-BSD’s Ports Console in a jail is cool, but I keep clicking when I want a normal console!
So today, I got fed up and I drew a new Icon for it:
I then renamed it from Ports Console to Ports Jail.
I’ll never make this mistake again and I think I will suggest this idea on the PC-BSD forums.
Oops!
This didn’t exactly work as expected. Sure, I never confuse the Icon on the desktop anymore, or in the KDE Menu, but now I have a different problem. If I open the Jail first, then open the regular Konsole, the icon for the running Konsole and Jail apps in the task bar are both Jail icons. The same in reverse. If I open Konsole, then open the Jail, the icons for the running Konsole and Jail apps in the task bar are both Konsole icons.
I can’t seem to make this work how I want.
Ok, so I had a hard time finding Windows Color and Appearance in Windows 7.
It is pretty easy to get to the Windows Color and Appearance tool if you know where to go. The problem is that where to go is not obvious. So here is where you go:
Besides the problem that it is not obvious where to go, there are also some computer some diseases that make this harder than it should be.
Disease #1 – Limited Clicking Ability Disorder or LCAD
People have what is called Limited Clicking Ability Disorder or LCAD. In layman’s terms, click laziness. Yes, that means we want to get there in less clicks.
It is 4 clicks to get to the Windows Color and Appearance tool, assuming you know where you are going. Otherwise, you have to click all over till you find it. Whether it is four or more, this is way too many clicks for someone who suffers from click laziness or LCAD.
The Cure
Create desktop shortcuts or shortcuts on your startbar.
Steps for creating a shortcut to the Windows Color and Appearance tool.
You now have a shortcut on your desktop which will all you to access Windows Color and Appearance in one click and cure your LCAD.
Note: If you want, you can right-click on the shortcut and choose properties and click the Change icon button and select a different icon if you want.
Disease #2 – Keyboard-to-Mouse Tropophobia
Tropophobia is the fear of moving and yes, Keyboard-to-Mouse Tropophobia is the fear of moving the hands from the keyboard to the mouse.
The Cure
Learn to access as many features as you can without using the mouse.
So how can you access the Windows Color and Appearance tool without going to mouse? This one was not as easy as others, but the solution was found.
Steps for accessing the Windows Color and Appearance tool using only the keyboard
Do this:
Sources:
This page got me started and my own knowledge got me an easier solution than what was posted here:
http://www.sevenforums.com/tutorials/59884-window-color-appearance-shortcut-create.html
Ok, so to my dismay, Microsoft has not created a default widget for selecting a directory.
I searched and searched and searched. Found some here are there, but none were really what I wanted.
I finally found one I like, so I thought I would share it with you. Here is what I like about the one I found:
Ok, so I wanted to create a little Help | About page that looks like this.
MyProgram 1.0.0.5
Author: Jared Barneck
Contributors: John, Mike, Mark, Tom, Bill, Jane, Ryan, Josh
I don’t really want to have to remember to change the version in the help file with each release, so I wanted to get the version dynamically.
Turns out that you can get the version as a string with a single line of code:
String theVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
Once you have the version as a string, you can display it how you want.