Thursday, September 3, 2009

Javascript Command Line

I never really mastered shell programming, but I do have JS skills. Maybe this article will come in handy.

Tuesday, July 7, 2009

Granting Execute Permissions to SQL Users

Granting exectution permission to users in SQL used to mean giving them DBO or granting permission to each stored proc. individually.

Last year I found a stored proc that would grant permissions when called but when new stored procs are created, you have to re-run it.

Today I found out that there is a way in SQL 2005 and later to create a new role that has execute permissions to all with the following Code:

CREATE ROLE db_executor

GRANT EXECUTE TO db_executor

After you have executed that script you can then see the role in the permissions list and assign it there. The user will then have permission to stored procedures added later.

Wednesday, July 1, 2009

VMWare Tips

VMWare Player is free, and it works ok, the UI is a little slow, but it works well otherwise.

VMWare Server is also free, and it works well but does not support audio.

VMWare Converter is free, it can make a VM from a physical computer (as well as do some other things I haven't looked into yet)

I am very much a rookie at VMWare, but I have found out a couple things about VMWare workstation Settings:
  • It is a hassle to increase the size of the C:\ drive so make it big enough to start.
  • It is easy to add drives, but you have to format them in Windows before you can use them.
  • Use Bridged networking if you need to browse network shares.
  • Make sure the sum of RAM available to your VMs does not exceed the amount of RAM on your machine, leaving around 512mb for the root OS (for win XP pro).
  • Install VMWare tools or the UI is very clunky
  • Use the shared folders feature on the Options tab of the Settings dialog to share drives on the root OS with drives on the VM.
  • Don't take a snapshot of a paused machine, or a running machine if you ever want to clone it. You can't clone a running or paused snapshot.

Tuesday, June 30, 2009

Doing a re-install on a Lenovo T60

After exactly 2 years of use, my Lenovo T60 was all messed up. Here are some of the problems I came to experience:
  • Windows required 12-15 minutes to start up.
  • It required 5-7 minutes to shut down.
  • When "waking" from sleep status onto a new network, the OS could not re-configure itself requiring a re-boot.
  • Trying to italicize something in Excel required 2 minutes the first time.
  • The 100 gb HD was full and required constant effort to empty so I could work.
  • All my music had to be stored on thumb drives
  • There were at least a dozen extra services starting up and I had no idea what they did.
So I decided to get a new HD and re-install Windows XP from scratch, and decided not to use the Lenovo system disk since a lot of what was installed was not required.

Further, I decided to ONLY install windows, VMWare workstation, and any VPN software I might need to connnect to my client's networks so that re-boot times and network problems would not recur and to do all future work on VMs. We subscribe to Microsoft's ActionPak program so we get 5 copies of every OS they offer for development purposes.

2 weeks later, I am nearly done. It has taken me at least 24 hours of effort, and almost every day until today I have had to switch back to the original HD to get most of my work done.

I decided to work on 3 VMs:
A pure development VM with
  • SQL 2008 Developer,
  • VS 2008 and various toolsets I use like telerik and subsonic
  • VSS,
  • SQL Compare,
  • Dynamics NAV
  • A good editor ( I used to use JEdit, but it craps out after being left open too long and I don't like to have Java running just for one editor, so I need to find a new one that has a good XML indent feature, side-by-side comparisons, text highlighting, and can deal with VERY large files. If you know of one let me know).

An application VM with

  • MS Office (including visio and project)
  • Inkscape

A throw-away VM with

  • I-tunes
  • Firefox
  • Java
  • uTorrent
  • VLC Media Player
  • SQL 2005 for legacy SSIS package work I may need to do.
  • All the other crap I have to load to get things done or because I am curious to see how it works

The first problem on the T60 is you have to change your system bios storage settings to be "compatible" to get it to install.

Once that is done, you can run windows update to get some drivers and download the rest of the drivers here for the HD, Intel Chipset, and Wireless, then change the storage settings back. That took me about 4 days to figure out and complete, I did not install any other drivers to ensure I didn't have things installed that I don't need.

Next, validate your XP Install, patch it, and purchase (or demo) VMWare workstation, and use VMWare converter to make an image of your machine and run the VMs, install the appropriate software, and start moving all the data (I bought a USB enclosure for the SATA drive to make that easy).

Install the VMWare tools to increase performance significantly, and if you partition the HD on your root OS, you can share one of the partitions between all the machines as a network share so they all have access to the same data.

Unfortunately that share can not be used for SQL databases, since it is not seen as a local volume, so make the development VM large enought to hold all the databases, and all the backups. I needed to add a 20gb extra drive for a total of 50gb, and I only have about 10gb free on that VM.

I will need some more RAM to run all 3 VMs at once, but I was going to up my RAM from 2gb to 4 gb anyway.

After all that work, it is a bit cumbersome to move things between VMs, but all the issues that led me to this configuration have been resolved and it takes 1-2 minutes to boot up, less than 1 minute to start up a VM that was paused, and 1-3 minutes to shut down. Plus I don't have to shut down to get networking to function when changing networks. I think that this change will be saving me 20-30 minutes a day. So my ROI is about 4 months. If I had to do it over again, I think it would take about half as long, so if you stumbled upon this, hopefully it will take you less time.

And when I get a new machine in 1-2 years, the migration should take less than an hour.

Wednesday, March 25, 2009

Determining an object size in C#

I am implementing business logic for a web application that will result in a sizeable data structure being housed in a class. I may decide to cache the class in the session at some point and I wanted to know how much RAM the class takes up. To figure that out, the best way I could find (here) was to serialize it and determine the size of the resulting binary. Of course the entire class (and any classes it holds as public properties) needs to be serializable.

long lSize = 0;
System.IO.MemoryStream stream = new System.IO.MemoryStream();
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter objFormatter =
new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
objFormatter.Serialize(stream, this.SalesOrder);
lSize = stream.Length;
output.Write("Size of the Object: " + lSize.ToString());

Wednesday, February 18, 2009

Creating a Matrix form in Dynamics NAV

I have always just copied matrix forms and hacked them up to create a new one.  Today, after developing in NAV since it was called Avista in 1996, I created one from scratch.  Here are the steps (sorry there are no images, maybe later):

Create a New, blank form, set the SourceTable of the form to the record to be used as the rows in the matrix.  Add any columns you want on each row to the left of the matrix using the Field Menu.

Create 2 text values: MatrixValue, and MatrixHeader.

Put a Matrix control on the form, assign the MatrixSourceTable to be the record defining the columns of the matrix.

If the form is to be focused on another record (like a matrix of sizes and colors for a single item), you can create a function used to open the form, create the record as a global variable and get the source record in that function.

Add a text box to the right section of the matrix, set the sourceexpression to MatrixValue.
Add a text box to the header portion of the new column, set the sourceexpression to MatrixHeader

If the matrix rec (the record defining the number of columns in the matrix) is bound to the source rec, call 

On form open, set filter on the SourceTable variable, using the source record, changing to filter group 2 before, and then 0 afterward, then filter the MatrixSourceTable if needed as follows:


Select the entire Matrix control, and in the Matrix-OnAfterGetRecord() trigger:

MatrixHeader := CurrForm.Matrix.MatrixRec."Field";

Or any other value.  In my case, I appended the code with the description since the users needed both.

Select the right portion of the Matrix control and go to the C/AL code.

In the OnFormat section assign the text to whatever you want displayed in each grid box, using the Currform.Matrix.MatrixRec to determine the Column, and the SourceTable for the row, and the SourceRecord if needed.

That's it!

Tuesday, January 27, 2009

Resetting password with security

When using hashed passwords, if a user forgets their password, there is no obvious way to reset it, since the old password is needed to assign a new password, and hashed passwords can not be retrieved from the database, the but it can be done.

The key is to reset the password first, then use the reset password to create a new password entered by the administrator.

I put a couple textboxes up on a page (tbPassword and tbConfirmPassword) and in the Web.Config set the requiresQuestionAndAnswer property of the security provider to false.

With that in place, if the administrator puts a value in the "New Password" text box, I know they intend to change the password and call the following code:

if (tbPassword.Text != "")
string tempPassword = Membership.Provider.ResetPassword(membershipUser.UserName, "");
Membership.Provider.ChangePassword(membershipUser.UserName, tempPassword, tbPassword.Text);

AJAX and browser cache

When using AJAX to update a page, if the user leaves the page and comes back via the back button, the content will revert to the values the page had when it initally loaded.  To remove that behavior the following c# code will force a refresh from the server and display the page based on the latest information on the server.

Response.Buffer = true;
Response.ExpiresAbsolute = DateTime.Now;
Response.Expires = 0;
Response.CacheControl = "no-cache";

Thursday, January 22, 2009

Modifying a table in SQL 2008 Mgt Studio

When adding a field or making other changes that requires a table be dropped and re-added, you may receive an error like 

"Saving changes is not permitted. The changes you have made require the following tables to be dropped and re-created. You have either made changes to a table that can't be re-created or enabled the option Prevent saving changes that require the table to be re-created."

If that happens, you need to update the management studio options as described here.

Wednesday, January 14, 2009


I am always forgetting how to use ToString() to get things formatted the way I want them.

To format a datetime as a date: