Friday, February 25, 2005

Saving documents to WSS site

If you want to make a MS Office documents available on the WSS site, there are 2 ways you can do it.

First is by goto the WSS site with your IE and upload the document.

The second way is easier and more interesting. While in your Word, Excel or Outlook, click the File Save/File Save As, and then in the FileName testbox, enter the URL to your WSS site(EG: http://wss_server/sitename, http://wss_server/sites/projectserver_xxx) and hit Enter. This will open a Window containing your WSS site. Navigate to your document library and save the document. However, this only work with Office 2003.

Labels:

Useful WSS site

I come across this site, WSS FAQ which has a lot of good stuff on Windows Sharepoint Services.

Labels:

Tuesday, February 15, 2005

Shipping Product

I come across this interesting but very true statement while watching Channel 9 :

#
If doesn't matter if it work on YOUR machine, we are not shipping on YOUR machine!
#

This remind us as developer of how important it is to test as extensive and as many configurations as possible. More than 90% of the time, the code will work on the developer machine since the developer machine usually have the necessary configuration, tools and libraries that are needed. Some of these are installed and configured without the developer know about it when he install the developer tools.

If you don't have so many machine for testing, consider to invest in virtual machine tools such as VirtualPC from Microsoft and VMWare.

The extra money and time to invest in extensive testing will save you a lot of face in front of your users/customer and reduce support effort.

Thursday, February 10, 2005

Detect Windows Idle time

Here is a sample code of how you can detect idle time in Windows. The definition of idle time here refer to the time when there is no user interaction with Windows such as no keyboard and mouse input.

Detecting idle time is used in application like MSN Messenger to change the status to "Away" after the user does not interact with the Windows for a predefine time.

The enabler for this feature is the GetLastInputInfo() Win32 API and the LASTINPUTINFO Win32 structure.

1. Create a C# Winform project in Visual Studio .NET.
2. Drop a Timer, Label and Button onto the form.
3. Set the Timer Interval property to 1000(1 second).
4. Create a Click event handler for the button.
5. Create a Tick event handler for the timer.
6. Use the following code to complete the Winform code.
7. Then you can build the project and run the app.

8. When the application is running, click the button to enable to timer.
9. Stay your hand away from your keyboard and mouse.
10. You can see the lable is showing the number of seconds that the Windows has been idle.
11. The moment you move your mouse or press any key, the number is reset.

Disclaimer:

The sample code only serve as a mean to illustrate the concept and implementation. It has not been checked for minor bugs, quality and robustness.


using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace GetLastInput_Demo
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
[DllImport("user32.dll")]
static extern bool GetLastInputInfo(out LASTINPUTINFO plii);

[StructLayout( LayoutKind.Sequential )]
struct LASTINPUTINFO
{
public static readonly int SizeOf =
Marshal.SizeOf(typeof(LASTINPUTINFO));

[MarshalAs(UnmanagedType.U4)]
public int cbSize;
[MarshalAs(UnmanagedType.U4)]
public int dwTime;
}

private System.Windows.Forms.Button button1;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Timer timer1;
private System.ComponentModel.IContainer components;

public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();

}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
private void InitializeComponent()
{
// Code is omitted here.
}
#endregion

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}

private void button1_Click(object sender, System.EventArgs e)
{
timer1.Enabled = !timer1.Enabled;
}

private void timer1_Tick(object sender, System.EventArgs e)
{
int idleTime = 0;
LASTINPUTINFO lastInputInfo = new LASTINPUTINFO();
lastInputInfo.cbSize = Marshal.SizeOf( lastInputInfo );
lastInputInfo.dwTime = 0;

int envTicks = Environment.TickCount;

if( GetLastInputInfo( out lastInputInfo ) )
{
int lastInputTick = lastInputInfo.dwTime;
idleTime = envTicks - lastInputTick;
}

int a;

if(idleTime > 0)
a = idleTime / 1000;
else
a = idleTime;

label1.Text = a.ToString();
}
}
}

Labels:

Wednesday, February 09, 2005

Engaging product support conversation

I receive 2 support email from one of my customer couple of days ago. He encounter an error when he was trying to do something.

His email is one of those which are very difficult to understand. The email is made up of "short fact statement", some sentence has broken grammer, some sentence is incomplete(I remember one of the sentence only have half of the sentence and then follow by dot.dot.dot. Is he asking to me guess the second half of the second?). I couldn't really make much sense from his email.

When I ask him for more details and describe it in a better way, he responded with another email that say he already give me details up to the database table. He doesn't know what else he can give me. Database table doesn't help me much either.

I guess he has never engage in any kind of support with his users or answer any kind of enquires before.

So, what is the missing piece here ?

If you are using a product that hundreds and thousand of other peoples are also using and only you have a problem with a particular feature of that product, there must be special case that you have done.

In a support conversation, it is important and the first thing you should do is :
1) Give a small description of what your problem is.
2) Give details of what you have done and how to reproduce it(the features you are using, how you have get to that features, what interaction you have done, what data you have input, what you do after that and so on).
3) Look for other details you can give such as product version, your platform environment, have you done any changes to the environment recently(such as changing configuration or applying patch), application log files, event log, database log and so on.

Giving as much useful information as possible that would help the support people to narrow down the trouble shooting and reproduce the error more quickly. This will speed up their respond time to you in return.

Simply telling them that this doesn't work and that doesn't work is not helpful at all.





Thursday, February 03, 2005

Security Awareness

I visit a customer office today with my colleague to do some installation work. I notice the users have very little clue about security.

First, an IT staff connect to a share folder on the server from a user PC using the server's administrator account.

Second, later I ask the user what user name she use to connect to the share folder on the server. She give me her user name and password right a way. Cool, I ask for it, but doesn't mean she has to give it to me.

Third, on her cubicle, I notice there is a piece of paper sticking on the wall that have all the staffs birthday, email and phone number. If I am a bad guy, imagine what I can do with those information. I can craft a scam mail that send to their email to fool them into giving out some personal information (phishing scam). Or I can start calling them and convince them I am calling from some authority and try to acquire personal information from them (social engineering).

Labels: