Archive for the ‘Uncategorized’ Category.

Changing the prompt for csh on FreeBSD 8.1

The prompt by default for csh on FreeBSD is simply a sing percent symbol.

%

There is not space before or after this.  I don’t like it and it drives me crazy. I like a prompt to tell me three things:

  1. Who is logged in.
  2. The machine name.
  3. The current path.

This change is quite simple.  It can be made temporarily, permanently for all users, or permanently for a single user.

Temporary

Sometimes you don’t want to make a permanent change to the prompt.  Especially if you are on someone else’s system temporarily and using one of their shells.  In such a case, setting the prompt temporarily is desired.

To see the prompt temporarily, simply run this command:

set prompt = “[%n@%m %c]$ “

Your prompt should now look as follows:

[SomeUser@SomeComputer ~]$

This is only temporary. As soon as you close the shell, the settings is gone and any new shells will continue to have the old setting.

All Users

To make a change for all users, the file that needs to be edited is /etc/csh.cshrc.

By default the file is empty except for some comments.  Line that are comments begin with the # character.

Add these lines to empty file:

if ($?prompt) then
        # An interactive shell -- set some stuff up
        set prompt = "[%n@%m %c]$ "
endif

After making this change, your prompt should look as follows:

[SomeUser@SomeComputer ~]$

If the file is not empty then you probably have to search yourself if the prompt is being set and replace it with the above.

Be careful that the prompt is not set for a single user because if it is, the user’s setting overrides the global settings.

Single User

The prompt can be set on a user by user basis.  The user’s settings will override the global setting.

To make a change for a single user, the file that needs to be edited is ~/csh.cshrc.

By default the file looks as follows:

# .cshrc - csh resource script, read at beginning of execution by each shell
#
# see also csh(1), environ(7).
#

alias h         history 25
alias j         jobs -l
alias la        ls -a
alias lf        ls -FA
alias ll        ls -lA

# A righteous umask
umask 22

set path = (/sbin /bin /usr/sbin /usr/bin /usr/games /usr/local/sbin /usr/local/bin $HOME/bin)

setenv  EDITOR  vi
setenv  PAGER   more
setenv  BLOCKSIZE       K

if ($?prompt) then
        # An interactive shell -- set some stuff up
        set filec
        set history = 100
        set savehist = 100
        set mail = (/var/mail/$USER)
        if ( $?tcsh ) then
                bindkey "^W" backward-delete-word
                bindkey -k up history-search-backward
                bindkey -k down history-search-forward
        endif
endif

After modification, my /etc/csh.cshrc looks like this:

# $FreeBSD$
#
# .cshrc - csh resource script, read at beginning of execution by each shell
#
# see also csh(1), environ(7).
#

alias h         history 25
alias j         jobs -l
alias la        ls -a
alias lf        ls -FA
alias ll        ls -lA

# A righteous umask
umask 22

set path = (/sbin /bin /usr/sbin /usr/bin /usr/games \
           /usr/local/sbin /usr/local/bin $HOME/bin \
           /usr/local/kde4/bin /usr/local/kde4/sbin \
           /usr/X11R6/kde4/bin /usr/X11R6/kde4/sbin \
           /usr/X11R6/kde4/lib/kde4/libexec)

setenv  EDITOR  vi
setenv  PAGER   more
setenv  BLOCKSIZE       K

if ($?prompt) then
        # An interactive shell -- set some stuff up
        set prompt = "[%n@%m %c]$ "
        set filec
        set history = 100
        set savehist = 100
        set mail = (/var/mail/$USER)
        if ( $?tcsh ) then
                bindkey "^W" backward-delete-word
                bindkey -k up history-search-backward
                bindkey -k down history-search-forward
        endif
endif

Your prompt should now look as follows:

[SomeUser@SomeComputer ~]$

Whatever you set the prompt to as a single user will override the global setting.

WIX: Creating an MSI to deploy multiple files

In this example we are going to create a simple MSI that deploys a two files.  This is not that much different than one file, but there is an implementation decision you have to make here that is important to understand.

Prequisites

Step 1 – Create a WIX project in Visual Studio

Creating a new project is a very simple task once you have done it a few times. However, I try to make my walk-thrus newbie proof, so even some one who has never done this feels comfortable. So if you need help with this step, use my instructions below. If you don’t, skip them.

  1. Open Visual Studio if it is not already open.
  2. Got to File | New | Project.
  3. You should have an option under Installed Templates for Windows Install XML. Select it.
  4. Now you should see the option for Setup Project. Select it.
  5. Enter a Name for the project. I called the project I made for this walk-thru MultiFileProject.
  6. Change the directory to store the project if you want. It doesn’t matter what directory you choose, but it is nice to keep your learning projects organized.
  7. Click OK.

Your project should now be created. In solution explorer you should now have a solution, a project, a reference and the Product.wxs. See the image below.

Ok, I hope that was easy for you. Lets move on.

Step 2 – Add two files to the project

These steps are preformed in Visual Studio on the project you just created in the above step.

  1. Right-click on the project name, MultiFileProject, and from the drop down, choose Add | New Item.
  2. Select Text File.
  3. Name it whatever you want. I used the default value, TextFile1.txt for this example.
  4. Click Add.
  5. Repeat the steps above to create a second file. My second file is TextFile2.txt.

Your files are now added to the Visual Studio project. However, they are not automatically added into the Product.wxs as a file to be installed. This is done manually in the next step.

Step 3 – Take a moment to learn

We are going to change the Product.wxs file to include the file we just created.

The Product.wxs file has the following XML text in it. Take a moment to look at the XML nodes and their elements so are familiar with the syntax it is using.

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
	<Product Id="9a19f6ed-a7b2-4cfc-a429-7069066fbf2a" Name="MultiFileProject" Language="1033" Version="1.0.0.0" Manufacturer="MultiFileProject" UpgradeCode="c1bdcc4d-b249-4b36-97fd-32609a60f8b4">
		<Package InstallerVersion="200" Compressed="yes" />

		<Media Id="1" Cabinet="media1.cab" EmbedCab="yes" />

		<Directory Id="TARGETDIR" Name="SourceDir">
			<Directory Id="ProgramFilesFolder">
				<Directory Id="INSTALLLOCATION" Name="MultiFileProject">
					<!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. -->
					<!-- <Component Id="ProductComponent" Guid="6263db4e-4c67-4adc-9ef1-e1caef798331"> -->
						<!-- TODO: Insert files, registry keys, and other resources here. -->
					<!-- </Component> -->
				</Directory>
			</Directory>
		</Directory>

		<Feature Id="ProductFeature" Title="MultiFileProject" Level="1">
			<!-- TODO: Remove the comments around this ComponentRef element and the Component above in order to add resources to this installer. -->
			<!-- <ComponentRef Id="ProductComponent" /> -->

			<!-- Note: The following ComponentGroupRef is required to pull in generated authoring from project references. -->
			<ComponentGroupRef Id="Product.Generated" />
		</Feature>
	</Product>
</Wix>

The text of the Xml gives us hints as to what we are supposed to do in its comments. Take a moment and read the comments.

Step 4 – Configure the WIX Xml file to deploy that file

Lets start editing that XML file.

Note: I am going to use the term “node’ to indicate and XML section. So and everything it contains is a node. If a node is inside it, I might call it a subnode.

  1. Uncomment the Component node the Directory nodes.
  2. Remove the two TODO: comments.
  3. Uncomment the ComponentRef node that is inside the Feature node.
  4. Remove the TODO: comment and the Note comment.
  5. Inside the Component node, at two File nodes for each of your two files as follows:
    <File Id='TextFile1.txt_id' Name='TextFile1.txt' Source='TextFile1.txt' KeyPath='yes' />
    <File Id='TextFile2.txt_id' Name='TextFile2.txt' Source='TextFile2.txt' />
    

    Notice that the second line is not marked with the KeyPath attribute. Only one file node (or maybe a registry node) can set KeyPath.

Ok, you are done.  Yes, that was all there is too it.   Feel free to add as many files as you want.

You XML syntax should now look as follows:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
  <Product Id="9a19f6ed-a7b2-4cfc-a429-7069066fbf2a" Name="MultiFileProject" Language="1033" Version="1.0.0.0" Manufacturer="MultiFileProject" UpgradeCode="c1bdcc4d-b249-4b36-97fd-32609a60f8b4">
    <Package InstallerVersion="200" Compressed="yes" />

    <Media Id="1" Cabinet="media1.cab" EmbedCab="yes" />

    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="ProgramFilesFolder">
        <Directory Id="INSTALLLOCATION" Name="MultiFileProject">
          <Component Id="ProductComponent" Guid="6263db4e-4c67-4adc-9ef1-e1caef798331">
            <File Id='TextFile1.txt_id' Name='TextFile1.txt' Source='TextFile1.txt' KeyPath='yes' />
            <File Id='TextFile2.txt_id' Name='TextFile2.txt' Source='TextFile2.txt' />
          </Component>
        </Directory>
      </Directory>
    </Directory>

    <Feature Id="ProductFeature" Title="MultiFileProject" Level="1">
      <ComponentRef Id="ProductComponent" />
      <ComponentGroupRef Id="Product.Generated" />
    </Feature>
  </Product>
</Wix>

Ok, you are ready to build.

Step 4 – Build the project

Well, there really isn’t much to debug, so we are only going to build a release version here.

  1. In the Visual Studio 2010 tool bar, there should be a drop down box that either says Debug or Release. Change it to Release if it is not already at Release.
  2. Select Build | Build Solution or use the shortcut key.

You should now have an MSI built in the project’s bin\release directory.

Step 5 – Test the MSI

Let’s go get the MSI and test it.

  1. Right-click on the project, MultiFileProject, and choose, Open Folder in Windows Explorer.
  2. In Explorer, navigate into the bin\release directory.
  3. You will see two files:
    MultiFileProject.msi – This is the MSI and is all you need.
    MultiFileProject.wixpdb – This is a file for debugging only. You may never use it unless you need to debug.
  4. You may or may not want to test the MSI on you development box. If you do, just double-click the MSI. Otherwise, copy it to a test box and run the MSI there.
  5. Verify that the file installed.
    Note: If on a 64 bit system, it will by default install as an x86 app, so look in c:\program files (x86)\ for a folder called MultiFileProject.
  6. Check Add / Remove Programs to make sure the install shows up there and that the uninstall works.

Congratulations. You just use WIX to create an MSI that deploys multiple files.

WIX: Creating an MSI and Deploying Your First File

Windows Install XML (WIX) is a nice simple way to create an MSI installation file.  Some of the items it automatically handles, such as registering with Add / Remove Programs, are very nice features.

In this example we are going to create a simple MSI that deploys a single file.

Prequisites

Step 1 – Create a WIX project in Visual Studio

Creating a new project is a very simple task once you have done it a few times.  However, I try to make my walk-thrus newbie proof, so even some one who has never done this feels comfortable. So if you need help with this step, use my instructions below.  If you don’t, skip them.

  1. Open Visual Studio if it is not already open.
  2. Got to File | New | Project.
  3. You should have an option under Installed Templates for Windows Install XML. Select it.
  4. Now you should see the option for Setup Project.  Select it.
  5. Enter a Name for the project. I called the project I made for this walk-thru DeployOneFile.
  6. Change the directory to store the project if you want.  It doesn’t matter what directory you choose, but it is nice to keep your learning projects organized.
  7. Click OK.

Your project should now be created.  In solution explorer you should now have a solution, a project, a reference and the Product.wxs.  See the image below.

Ok, I hope that was easy for you.  Let move on.

Step 2 – Add a file to the project

These steps are preformed in Visual Studio on the project you just created in the above step.

  1. Right-click on the project name, DeployOneFile, and from the drop down, choose Add | New Item.
  2. Select Text File.
  3. Name it whatever you want. I  used Install.conf for this example.
  4. Click Add.

Your file is now added to the Visual Studio project.  However, it is not automatically added into the Product.wxs as a file to be installed. This is done manually in the next step.

Step 3 – Take a moment to learn

We are going to change the Product.wxs file to include the file we just created.

The Product.wxs file has the following XML text in it.  Take a moment to look at the XML nodes and their elements so are familiar with the syntax it is using.

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
	<Product Id="fae97512-4eca-4271-821d-75b7a8861557" Name="DeployOneFile" Language="1033" Version="1.0.0.0" Manufacturer="DeployOneFile" UpgradeCode="fec17f7b-060e-466f-8bd2-7895eb2b92ce">
		<Package InstallerVersion="200" Compressed="yes" />

		<Media Id="1" Cabinet="media1.cab" EmbedCab="yes" />

		<Directory Id="TARGETDIR" Name="SourceDir">
			<Directory Id="ProgramFilesFolder">
				<Directory Id="INSTALLLOCATION" Name="DeployOneFile">
					<!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. -->
					<!-- <Component Id="ProductComponent" Guid="927a42ea-a6df-45f6-ac52-4b979194bc10"> -->
						<!-- TODO: Insert files, registry keys, and other resources here. -->
					<!-- </Component> -->
				</Directory>
			</Directory>
		</Directory>

		<Feature Id="ProductFeature" Title="DeployOneFile" Level="1">
			<!-- TODO: Remove the comments around this ComponentRef element and the Component above in order to add resources to this installer. -->
			<!-- <ComponentRef Id="ProductComponent" /> -->

			<!-- Note: The following ComponentGroupRef is required to pull in generated authoring from project references. -->
			<ComponentGroupRef Id="Product.Generated" />
		</Feature>
	</Product>
</Wix>

The text of the Xml gives us hints as to what we are supposed to do in its comments.  Take a moment and read the comments.

Step 4 – Configure the WIX Xml file to deploy that file

Lets start editing that XML file.

Note: I am going to use the term “node’ to indicate and XML section. So and everything it contains is a node. If a node is inside it, I might call it a subnode.

  1. Uncomment the Component node the Directory nodes.
  2. Remove the two TODO: comments.
  3. Uncomment the ComponentRef node that is inside the Feature node.
  4. Remove the TODO: comment and the Note comment.
  5. Inside the Component node, at a File node as follows:
    <File Id='Install.conf_id' Name='Install.conf' DiskId='1' Source='Install.conf' KeyPath='yes' />
    

Ok, you are done.  Yes, that was all there is too it.

You XML syntax should now look as follows:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
  <Product Id="fae97512-4eca-4271-821d-75b7a8861557" Name="DeployOneFile" Language="1033" Version="1.0.0.0" Manufacturer="DeployOneFile" UpgradeCode="fec17f7b-060e-466f-8bd2-7895eb2b92ce">
    <Package InstallerVersion="200" Compressed="yes" />

    <Media Id="1" Cabinet="media1.cab" EmbedCab="yes" />

    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="ProgramFilesFolder">
        <Directory Id="INSTALLLOCATION" Name="DeployOneFile">
          <Component Id="ProductComponent" Guid="927a42ea-a6df-45f6-ac52-4b979194bc10">
            <File Id='Install.conf_id' Name='Install.conf' DiskId='1' Source='Install.conf' KeyPath='yes' />
          </Component>
        </Directory>
      </Directory>
    </Directory>

    <Feature Id="ProductFeature" Title="DeployOneFile" Level="1">
      <ComponentRef Id="ProductComponent" />
      <ComponentGroupRef Id="Product.Generated" />
    </Feature>
  </Product>
</Wix>

Ok, you are ready to build.

Step 4 – Build the project

Well, there really isn’t much to debug, so we are only going to build a release version here.

  1. In the Visual Studio 2010 tool bar, there should be a drop down box that either says Debug or Release.  Change it to Release if it is not already at Release.
  2. Select Build | Build Solution or use the shortcut key.

You should now have an MSI built in the project’s bin\release directory.

Step 5 – Test the MSI

Let’s go get the MSI and test it.

  1. Right-click on the project, DeployOneFile, and choose, Open Folder in Windows Explorer.
  2. In Explorer, navigate into the bin\release directory.
  3. You will see two files:
    DeployOneFile.msi – This is the MSI and is all you need.
    DeployOneFile.wixpdb – This is a file for debugging only. You may never use it unless you need to debug.
  4. You may or may not want to test the MSI on you development box. If  you do, just double-click the MSI.  Otherwise, copy it to a test box and run the MSI there.
  5. Verify that the file installed.
    Note: If on a 64 bit system, it will by default install as an x86 app, so look in c:\program files (x86)\ for a folder called DeployOneFile.
  6. Check Add / Remove Programs to make sure the install shows up there and that the uninstall works.

Congratulations. You just use WIX to create and deploy your first MSI.

 

Bonus Information – Learning about Repair

Repairing an installation is an important feature of  to understand.

What you are going to learn here, is that if you delete a file in a component that has the KeyPath=’yes’ tag, the component will reinstall.

  1. Make sure the MSI you just created above is installed. If you uninstalled it doing steps above, reinstall it.
  2. On the machine where you installed the MSI, Browse to the installation directory.My directory is here.
    C:\Program Files (x86)\DeployOneFile
  3. The only file in that directory is the file you installed:
    Install.conf
  4. Delete the Install.conf file.
  5. Still on the machine where you installed the MSI, go to Add / Remove Programs.
  6. Right-click on the DeployOneFile instance and choose Repair.
  7. The file you deleted should be restored.

Ok, so you probably have questions about repair.  This was just a basic introduction.  Hopefully we will learn more about repair as we go on.

Why my categories span such broad topics?

Hey all,

I recently noticed I was added to another blogs blogroll.  It was funny what he said:

Rhyous’s 127.0.0.1 or ::1 covers an interesting mix of FreeBSD, PC-BSD, C# and even Windows 7 issues. An unusual mix…

Well, here is the deal.

  1. One of my hobbies is learning about open source.  My operating system of choice is FreeBSD and I am partial to PC-BSD for desktop use as well.  So naturally, I am going to post about that.
  2. However, I work for LANDesk as a Developer (previously I was a Level III support engineer), using primarily C#.  We have a lot of legacy C++ code as well.  LANDesk is mostly a Microsoft shop.  Our server software runs on Windows Servers only and we support MS SQL and Oracle back ends.  Our agent goes to Windows, Mac, Linux, and some Unix devices.  Yes, I have had the Linux version of the LANDesk agent running on FreeBSD using Linux Emulation.  I am probably going to post more on WIX now as I am on a development team that deals with our product installation.
  3. I am also just a techie in the first place so I have lots of tech interests outside my career and my hobbies.
  4. I now realize the importance of experience and I want to increase my experience and make my experience more meaningful by retaining it.  I used to do support for Nortel Networks equipment before coming to LANDesk so I have intense networking skills that are uncommon among developers. I also have 10+ years of support and troubleshooting which gives my a unique perspective.  The more you do something the easier it is.  I have a lot of experiences where some support guys were working on something for days and I walk over and solve the problem in five minutes.  It is something that comes with 10+ years experience or troubleshooting. No, that is not unique to me.  LANDesk tech support engineers are some of the best out there and there are a number of guys that can do that here.  But all of them have about 10+ years experience.
  5. I help others with their computer issues which often leads to figuring things out.

My one regret is that I didn’t start my blog in 10+ years ago.  Think of the content I would have had.

So anytime I have to look something up or research a problem and the first or second Google link is not an exact answer, I am going to blog about it, whatever the topic may be.

A simple example of starting and stopping a service in windows using C++

Hey all,

Here is a simple example of starting and stopping a service in C++. Just pass the service name as a parameter and the service will switch states. If stopped, it will start. If started, it will stop.

// StartStopService.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <windows.h>

int _tmain(int argc, _TCHAR* argv[])
{
	SC_HANDLE serviceDbHandle = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
	SC_HANDLE serviceHandle = OpenService(serviceDbHandle, argv[1], SC_MANAGER_ALL_ACCESS);

	SERVICE_STATUS_PROCESS status;
	DWORD bytesNeeded;
	QueryServiceStatusEx(serviceHandle, SC_STATUS_PROCESS_INFO,(LPBYTE) &status,sizeof(SERVICE_STATUS_PROCESS), &bytesNeeded);

	if (status.dwCurrentState == SERVICE_RUNNING)
	{// Stop it
		BOOL b = ControlService(serviceHandle, SERVICE_CONTROL_STOP, (LPSERVICE_STATUS) &status);
		if (b)
		{
			std::cout << "Service stopped." << std::endl;
		}
		else
		{
			std::cout << "Service failed to stop." << std::endl;
		}
	}
	else
	{// Start it
		BOOL b = StartService(serviceHandle, NULL, NULL);
		if (b)
		{
			std::cout << "Service started." << std::endl;
		}
		else
		{
			std::cout << "Service failed to start." << std::endl;
		}
	}

	CloseServiceHandle(serviceHandle);
	CloseServiceHandle(serviceDbHandle);

	return 0;
}

A simple example of creating or deleting a windows share using C++

Hey all,

Here is a simple example of creating or deleting a windows share in C++.

// CreateShare.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <windows.h>
#include "lm.h"

int _tmain(int argc, _TCHAR* argv[])
{
	// Create share
	if (0 == _tcscmp(argv[1], _T("create")))
	{
		SHARE_INFO_2 si =
		{
			L"ShareName",
			STYPE_DISKTREE,
			L"Any nice comment or remark",
			ACCESS_READ,
			DWORD(-1),
			0,
			L"C:\\Users\\jbarneck\\Desktop\\Share",
			L""
		};

		DWORD parameterError = 0;
		DWORD status = NetShareAdd(NULL, 2, (BYTE *) &si, &parameterError);
		if (status != ERROR_SUCCESS)
		{
			std::cout << "Error: " << status << std::endl;
			if (status == ERROR_ACCESS_DENIED) // 5L in WinError.h
			{
				std::cout << "Access denied." << std::endl;
			}
			if (status == NERR_ServerNotStarted) // 2114 in LMErr.h
			{
				std::cout << "The Server service is stopped." << std::endl;
			}
			if (status == NERR_DuplicateShare) // 2118 in LMErr.h
			{
				std::cout << "The share already exists." << std::endl;
			}
		}
		// End program
		return 0;
	}

	// Delete share
	if (0 == _tcscmp(argv[1], _T("delete")))
	{
		DWORD status = NetShareDel(NULL, L"ShareName", 0);
		if (status != ERROR_SUCCESS)
		{
			std::cout << "Could not delete share: " << status << std::endl;
		}
		// End program
		return 0;
	}

}

References:
NetShareAdd – http://msdn.microsoft.com/en-us/library/bb525384%28VS.85%29.aspx
NetShareDel – http://msdn.microsoft.com/en-us/library/bb525386%28v=VS.85%29.aspx

Detecting if the install is occuring on a 64 bit or 32 bit machine

Ok, so NSIS has most the 64 bit functionality available for their installers.

I need to write a registry key to the 64 bit registry on 64 bit machines.

I may need to install to Program Files or Program Files (x86).

If on 64 bit workstation you need to install to Program Files (x86) that is done by default because the $PROGRAMFILES constant goes to the Program Files (x86) directory.

So a simple solution that should be obvious is to check for something that is on a 64 bit machine that is not on a 32 bit machine.  Lets make a list of such differences.

Files

  1. c:\Program Files (x86) – Since this is just a folder, it could exist on a 32 bit machine, though that would be unlikely.
  2. c:\windows\SysWow64

Registry key

  1. HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node – This is a 64 bit registry and does not exist in 32 bit operating systems.

So some of these are susceptible to be “faked”.  I could see some idiot writing an installer on Windows 7 and hard coding the Program Files (x86) directory so it is installed there even on 32 bit systems.  The SysWow64 directory seems more safe and it exists on Vista, Windows 7, and 2008.  I don’t have XP or 2003 64 bit machines so someone can check for me. It seems that the registry key is also likely to be a safe check.

You can check any of these you want. 

Here is how you would change which registry to work with.

	IfFileExists $WINDIR\SYSWOW64\*.* Is64bit Is32bit
	Is32bit:
		SetRegView 32
		GOTO End32Bitvs64BitCheck

	Is64bit:
		SetRegView 64

	End32Bitvs64BitCheck:

That fixes the registry keys. So if you only care about the registry you are fine. However, you software will still install to the Program Files (x86) directory. To fix both, you could place the following code in BOTH the .onInit and the un.onInit functions.

	; Install to the correct directory on 32 bit or 64 bit machines
	IfFileExists $WINDIR\SYSWOW64\*.* Is64bit Is32bit
	Is32bit:
		MessageBox MB_OK "32 bit"
		SetRegView 32
		StrCpy $INSTDIR "$PROGRAMFILES32\LANDesk\Health Check"
		GOTO End32Bitvs64BitCheck

	Is64bit:
		MessageBox MB_OK "64 bit"
		SetRegView 64
		StrCpy $INSTDIR "$PROGRAMFILES64\LANDesk\Health Check"

	End32Bitvs64BitCheck:

Don’t forget to comment out the usual place that INSTDIR is configured.

Anyway, that seems to work.


Copyright ® Rhyous.com – Linking to this page is allowed without permission and as many as ten lines of this page can be used along with this link. Any other use of this page is allowed only by permission of Rhyous.com.

Old Games…very old…1991…on 5.25" Floppies

Hey all,

Guess what gifts my brother brought me yesterday?  Yes, he cleaned out some old DOS games from his closet.  Some of the games I thoroughly loved:

  • Advanced Dungeons & Dragons’ Eye of the Beholder II – The Legend of Darkmoon
  • Nephi’s Quest – A mormon version of Kings Quest.

Unfortunately my Kings Quest set wasn’t found, though my brother has this if I want it, and Bard’s Tale II wasn’t found.

So I instantly thought of two problems I had to solve:

  1. How to read the 5.25″ floppies
  2. How to get a DOS system that isn’t so fast the games are unplayable.

Reading the 5.25 floppy drives

Yes, they are on 5.25″ floppies.  So after about 20 minutes of looking online for a USB 5.25″ floppy drive, I gave up.

So my options are:

  1. Get an old system with a floppy drive that still works.
  2. Send my floppies to a company that will migrate them to a CD at $5 a floppy.
  3. Find someone who has already moved the software from the floppies…

Yeah, one and two just weren’t for me, so the alternative was my only option.

Alternative to Reading the 5.25 floppy drives

Ok, so I almost gave up, when my decided that some one out that had a copy of the game downloadable right.  I mean, these games are 20 years old.  They are collectable. So somebody has to have them online.  Since I purchased a license in 1991, I thought I would not be breaking any laws downloading them.

Turns out I didn’t really have to worry about legalities and copyrights.

I found this site: http://www.abandonia.com/

Yes, Abandonia is the land of “abandonware”.  According to them, many of these games no longer have a copyright and are free to download, play, distribute, etc…

So I downloaded my Advanced Dungeons & Dragons’ Eye of the Beholder II – The Legend of Darkmoon game immediately.

How to get a DOS system that isn’t so fast the games are unplayable

Well, my first thought was VMWare, but again, Abandonia helped me out here.  There is a DOS Emulator called DOS Box.

I installed DOS Box on my Windows 7 box at home, with worry that it wouldn’t work well on Windows 7 64 bit, but to  my surprise, it worked well.

I do want to find a way to make the screen bigger.  And it would be cool to have a DOS VM along with DOS Box to test if it is better or worse, but hey this is sufficient for now.

Other Abandoned Games

There were many other abandoned games, such as the first Eye of the Beholder game as well as Eye of the Beholder III.  Also, Bards Tale I, II, III, and hundreds more.

So if you are looking for a blast from the past with one of your favorite games, check it out.

Where to get a Select a Directory Dialog (or Folder Picker or Choose Directory Dialog) in WPF?

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:

http://www.ookii.org/software/dialogs/

How to upload a file to an FTP server using C#?

C# (Mono) on FreeBSD

Ok, so today I needed to FTP a file.  It took me some time and research but I have a function that will upload a file to an FTP server.

I found a lot of examples that were very complex, and rightfully so as they have a lot of error and exception handling. However, this complexity makes it difficult to learn.

So this is a non-complex version. It follows some basic steps:

  1. Get the local file name: C:\Users\Rhyous\Desktop\File1.zip
  2. Open a request using the full destination ftp path: Ftp://Ftp.Server.tld/Path/File1.zip
  3. Configure the connection request
  4. Create a stream from the file
  5. Read the file into the a local stream
  6. Close the local stream
  7. Create a stream to the FTP server
  8. Write the local stream to the FTP stream
  9. Close the stream to the FTP server
using System;
using System.IO;
using System.Net;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
			string ftplocation = "ftp://ftp.server.tld/path";
			string file = @"C:\Users\Rhyous\Desktop\File1.zip" // Or on FreeBSD: "/usr/home/jared/test2.txt";
			string user = "Anonymous";
			string password = "AnyPasswd!";
            UploadToFTP(ftplocation, file, user, password);
        }

        static void UploadToFTP(String inFTPServerAndPath, String inFullPathToLocalFile, String inUsername, String inPassword)
        {
            // Get the local file name: C:\Users\Rhyous\Desktop\File1.zip
            // and get just the filename: File1.zip. This is so we can add it
            // to the full URI.
            String filename = Path.GetFileName(inFullPathToLocalFile);

            // Open a request using the full URI, c/file.ext
            FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(inFTPServerAndPath + "/" + filename);

            // Configure the connection request
            request.Method = WebRequestMethods.Ftp.UploadFile;
            request.Credentials = new NetworkCredential(inUsername, inPassword);
            request.UsePassive = true;
            request.UseBinary = true;
            request.KeepAlive = false;

            // Create a stream from the file
            FileStream stream = File.OpenRead(inFullPathToLocalFile);
            byte[] buffer = new byte[stream.Length];

            // Read the file into the a local stream
            stream.Read(buffer, 0, buffer.Length);

            // Close the local stream
            stream.Close();

            // Create a stream to the FTP server
            Stream reqStream = request.GetRequestStream();

            // Write the local stream to the FTP stream
            // 2 bytes at a time
            int offset = 0;
            int chunk = (buffer.Length > 2048) ? 2048 : buffer.Length;
            while (offset < buffer.Length)
            {
                reqStream.Write(buffer, offset, chunk);
                offset += chunk;
                chunk = (buffer.Length - offset < chunk) ? (buffer.Length - offset) : chunk;
            }
            // Close the stream to the FTP server
            reqStream.Close();
        }
    }
}

This works well for most files.

One problem is that this code reads the entire local file into memory, which might not be a good idea for a file that is very large (multiple gigabytes). It would be better to read the local file in bits. I upload in bits so this would not be hard to read a little bit, upload it, read a little bit more, upload it, etc…

Resources:

http://msdn.microsoft.com/en-us/library/system.net.ftpwebrequest.aspx

http://msdn.microsoft.com/en-us/library/system.io.stream.aspx

http://www.vcskicks.com/csharp_ftp_upload.php