Windows Mobile Development

Posted by 빵빵빵
2009/01/15 00:08 전산(컴퓨터)/PC-Windows



http://www.christec.co.nz/blog/archives/category/user-interface/




Archive for the ‘User Interface’ Category

Creating custom animated wait cursors

Friday, April 4th, 2008

Most .NET Compact Framework developers will be familiar with theCursor.Current property and how to display the standard Wait Cursor, but did you know that you could easily display your own custom cursor? This blog entry discusses how you can replace the standard wait cursor with your own application specific cursor. This is an ideal way to brand kiosk style applications for example.

Creating a custom cursor

Recent versions of the Windows CE operating system (and hence Windows Mobile) support an OS API called LoadAnimatedCursor. This API enables you to specify a sequence of individual bitmap frames and will convert them into an animated cursor. For example an animated cursor of a rotating monkey could be made up of the following 4 bitmaps.

101 102 103 104

The more frames the cursor consists of the smoother the animation will be. Individual frames within the animation should be 48×48 pixel bitmap resources within a *.dll or *.exe file. The bitmap resources are identified by a numeric ID and must be in sequential order (such as the values 101, 102, 103 and 104 used in the example above).

The id of the first bitmap, the total number of frames and the period of time to delay between frames is then passed into the LoadAnimatedCursor API which will return a handle to the newly created cursor (an HCURSOR). Passing this handle to the SetCursor API will then make the cursor visible on the screen.

Unfortunately the LoadAnimatedCursor function is not as easy to use from managed code as it should be. The API expects the bitmap images to be native bitmap resources meaning you can not store them within a *.resx resource file within your .NET Compact Framework application. The easiest way to store the bitmaps in the correct format is to create a native C++ DLL project. You can then remove all the C++ source files, leaving a sole Win32 *.rc resource file to which you can add the bitmaps to (as will be demonstrated later).

Sample Application

[Download animatedcursortest.zip - 37KB]

The sample application available for download consists of two projects. The first (called AnimatedCursors) demonstrates how to create a resource only DLL that contains the bitmap images required for the two custom cursors shown above.

The second project is a C# example demonstrating how to use Platform Invoke to access theLoadAnimatedCursor and SetCursor APIs to display the custom cursors. This second project loads the custom cursors from the AnimatedCursors.dll file built by the first project.

The C# sample wraps up the required Platform Invoke code within a class called AnimatedWaitCursor. This class implements the IDisposable interface so that the following syntax can be used to display a custom cursor. This code structure should be familiar to anyone who has used MFC’s CWaitCursor class.

// Use the animated cursor that has 4 frames starting with
// bitmap id 101, delaying 125 milliseconds between each frame.
string dll = @"\path\to\some.dll";
using (AnimatedWaitCursor cursor = new AnimatedWaitCursor(dll, 101, 4, 125))
{
  // do some long running task
}

How to make your ListView columns reorderable

Tuesday, March 18th, 2008

Another finishing touch that I like to see in applications that use ListViews is the ability for the end user to re-order the columns to suit their own preferences. This blog entry discusses one approach for adding this functionality to the ListView control present within the .NET Compact Framework. Although it is difficult to convey in a static screenshot, the screenshot above shows a user dragging the stylus over the header of the listview control to move the position of the “First Name” column.

Obtaining Draggable Columns

The System.Windows.Forms.ListView control is a wrapper over top of the native ListView control. The native ListView control supports the notion of extended styles, which allow various optional features to be enabled or disabled as desired. One of the extended styles is calledLVS_EX_HEADERDRAGDROP. If this extended style is enabled the user can re-order the columns by dragging and dropping the headers shown at the top of the listview while it is in report mode.

Although the .NET Compact Framework ListView control does not expose a mechanism to enable extended styles, we can use a technique discussed in a previous blog entry of mine to add or remove the LVS_EX_HEADERDRAGDROP extended style as desired.

private const int LVM_SETEXTENDEDLISTVIEWSTYLE = 0x1000 + 54;
private const int LVS_EX_HEADERDRAGDROP = 0x00000010;
 
public static void SetAllowDraggableColumns(this ListView lv, bool enabled)
{
  // Add or remove the LVS_EX_HEADERDRAGDROP extended
  // style based upon the state of the enabled parameter.
  Message msg = new Message();
  msg.HWnd = lv.Handle;
  msg.Msg = LVM_SETEXTENDEDLISTVIEWSTYLE;
  msg.WParam = (IntPtr)LVS_EX_HEADERDRAGDROP;
  msg.LParam = enabled ? (IntPtr)LVS_EX_HEADERDRAGDROP : IntPtr.Zero;
 
  // Send the message to the listview control
  MessageWindow.SendMessage(ref msg);
}

This method allows the drag feature to be turned on and off for a given ListView control. Notice that this method makes use of a C# 3.0 feature called Extension Methods. The “this” keyword in front of the first parameter means that this method can be called as if it was part of the standard ListView control, meaning the following code snippet will work (assuming listView1 is an instance of the System.Windows.Forms.ListView control).

listView1.SetAllowDraggableColumns(true);

This is pure syntactic sugar, behind the scenes the C# compiler is simply passing in listView1 as the first parameter to the SetAllowDraggableColumns method.

Persisting Column Order Preferences

Once you have reorder-able columns it can be desirable to persist the user’s preferred layout across multiple executions of your application. It would be a pain if the columns always defaulted back to a standard order everytime the form was displayed.

The native ListView control provides two window messages, LVM_GETCOLUMNORDERARRAYand LVM_SETCOLUMNORDERARRAY that can be used to implement this feature. The code sample available for download wraps up these two window messages to allow you to query the current order of the columns by using a statement such as the following:

int[] columnOrder = listView1.GetColumnOrder();
// TODO: save 'columnOrder' to the registry
// or another persistent store

When columns are added to a ListView they are given an index. The first column is column 0 while the second is column 1 and so on. When columns are re-ordered they keep their index value but their position on screen changes. The array returned by the GetColumnOrder function contains the index for each column in the order that they are visible on screen. For example if the array contains the values 2, 0, and 1 it means that the last column (column 2) has been dragged from the right hand side of the listview to become the left most column.

Once we have obtained the order of the columns we can store the data in any persistent storage mechanism such as a file, a database table, or registry key. When the form is reloaded we can initialise the default order of the columns by calling the equivalent SetColumnOrder method with the value we previously saved:

// TODO: should read 'columnOrder' from the registry
// or other persistent store
int[] columnOrder = new int[]{2, 0, 1};
 
listView1.SetColumnOrder(columnOrder);

Sample Application

[Download ListViewExtenderTest.zip - 11 KB]

The sample application displays a list of three columns. While running on a Windows Mobile Professional device you should be able to re-order the columns by dragging and dropping the column headers with your stylus. If you exit and restart the application you should see that your custom column ordering is persisted. Via the left soft key menu item you can select an option that will disable the user from re-ordering the columns.

Most of the magic occurs within a file you can reuse in your own applications called ListViewExtender.cs. The sample application targets .NET CF 3.5 and hence requires Visual Studio 2008. With minor tweaks the source code would also be usable within .NET CF 2.0 projects. I would be keen to hear what your thoughts are about this. Is it time to shift code samples to .NET CF 3.5/Visual Studio 2008 or are you still wanting .NET CF 2.0 and Visual Studio 2005 compatible samples?

Improvements to the OpenFileDialog class

Saturday, March 8th, 2008

José Gallardo Salazar has blogged about an enhanced OpenFileDialog implementation that fixes a number of common complaints with the standard .NET Compact Framework version. The most common complaints being not able to browse outside the “My Documents” folder and the lack of support for Smartphone (Windows Mobile Standard) devices.

As indicated in his blog entry on adding Smartphone support the OpenFileDialogEx class is still a work in progress with many possible areas of improvement. I have taken José’s source code and made a number of changes.

My improvements include:

  • Shell Icon List support - The dialog now uses the same icons as shown in File Explorer. Directories for example may have a custom icon (for example the Games folder shown in the screenshot above).
  • DPI / Resolution awareness - icons change size to match current system settings (i.e. larger icons on higher resolution devices).
  • Support for both Pocket PC and Smartphone - the platform is detected at runtime so a single assembly can alter it’s UI behaviour to run on both platforms. Some UI elements are hidden while running on a Smartphone for example.
  • Back Key support - The Back key on Smartphone Devices now moves up one directory when pressed (just like the builtin File Explorer application on WM6 devices).
  • Sorted Directory Listings - Directory entries are now sorted into alphabetical order. There is provision for the sort order to be easily modified (although this is not yet publicly exposed).
  • InitialDirectory property - This property enables the dialog to default to displaying a directory other than the root of the filesystem.

Sample Application

[Download iconviewer.zip - 22KB]

The sample application available for download demonstrates how to use the OpenFileDialogEx class and demonstrates its cross platform capability. Once you have built the application you should be able to run it on practically any Windows Mobile device and see a file dialog that is tailored to the capabilities of the current device.

One small disadvantage of my changes is the fact that the control is now less “pure”. It relies upon a number of Platform Invoke calls to access some of the system functionality not exposed by the .NET Compact Framework. An interesting note is that .NET Compact Framework version 3.5 removes the need for most of the Platform Invoke code due to new functionality or bug fixes. At this point in time however supporting .NET CF 2.0 is still important to me.

Improving Comboboxes on Smartphone devices

Monday, February 11th, 2008

Screen real-estate is at a premium on smaller Windows Mobile smartphone devices, so it is important to maximise the use of every available pixel in conveying useful information to the user. This blog entry demonstrates a technique to maximise the usability of combo boxes within .NET Compact Framework applications by reusing some of the existing screen real-estate.

Defining the problem

When you place a Combobox control on a form within a Smartphone application you get a control which shows a single item with left/right arrows that allow you to scroll through the list of options.

As an alternative if you press the Action key (middle of the D-PAD) on the combobox the full list is displayed in a fullscreen window. This window however is always labelled “Select an Item”. Because the window is fullscreen it is possible for the user to loose context (they can’t see any labels etc you have placed on your form), and forget what they are meant to be selecting. What we would like to do is to replace the “Select an Item” title with something more appropriate for the current field.

What we get by default What we desire

Developing a solution

This is where having knowledge of the underlying native (C/C++) APIs that implement Windows Mobile is useful. When targeting a smartphone device a .NET Compact Framework Combobox control is actually implemented via two separate controls as far as the operating system is concerned, a 1 item high listbox coupled to an up/down control. The native Win32 smartphone documentation calls this type of configuration a Spinner Control.

By using a utility included with Visual Studio called Remote Spy++ we can see this collection of controls. In the screenshot to the left you can see that one of the combo boxes in the sample application is selected, and underneath it you can clearly see the listbox and up/down (msctls_updown32) controls it is made up of.

In order to change the title of the popup window associated with a combo box we need to:

  1. Find the native window handle for the up/down control
  2. Change it’s window title to the desired prompt text

The ComboBox class has a Handle property that returns a native window handle (HWND) that is associated with the managed control. For a ComboBox the Handle property actually returns the handle of the listbox control and not the parent “NETCFITEMPICKERCLASS_A” control as may be expected. This was probably done for native code interop compatibility reasons. So to find the native window handle of the up/down control we simply need to find the handle for the window immediately after the window returned by the ComboBox.Handle property.

Once we have found the window handle for the up/down control we are finally ready to replace the popup window title. According to the Spin Box Control documentation, the popup window title comes from the title of the up/down control, and it defaults to the “Select an Item” prompt if a title isn’t specified. We can change the title of a native window by calling the SetWindowText API.

All these individual steps can be wrapped up into an easy to call method as follows:

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
 
public static class ComboboxExtender
{
  public static void SetPromptText(ComboBox combo, String text)
  {
    // Obtain the native window handle of the up/down spinner control
    IntPtr hWndListBox = combo.Handle;
    IntPtr hWndSpinner = GetWindow(hWndListBox, GW_HWNDNEXT);
 
    // Set the title of the spinner
    SetWindowText(hWndSpinner, text);
  }
 
  [DllImport("coredll.dll")]
  private static extern bool SetWindowText(IntPtr hWnd, String lpString);
 
  [DllImport("coredll.dll")]
  private static extern IntPtr GetWindow(IntPtr hWnd, UInt32 uCmd);
 
  private const UInt32 GW_HWNDNEXT = 2;
}

Sample Application

[Download ComboBoxPromptExample.zip - 16KB]

The sample application available for download demonstrates using the ComboBoxExtender class developed above. The interface consists of two combo boxes which have been configured identically. The first combo box shows the default prompt text, while the second has had its prompt text replaced via a call to ComboBoxExtender.SetPromptText within the Form’s Load event handler as shown below:

ComboBoxExtender.SetPromptText(comboBox2, "Select Car Colour");

I am a stickler for improving the quality and polish of Windows Mobile applications. This tip is a very minimal code change that can be implemented quickly, yet can have a profound impact on the usability of your application if it is full of combo boxes. A similar trick can also be implemented for Expandable Edit controls.

If you are developing .NET Compact Framework applications that target the Windows Mobile Smartphone (Standard) platform, I seriously encourage you to consider making this usability change to your applications.

Aspect Ratio Picture Box control

Tuesday, January 29th, 2008

One feature missing from the PictureBox control within the .NET Compact Framework is the Zoom SizeMode. This mode makes the image contained within the PictureBox as large as possible while still maintaining its original aspect ratio. Luckily this feature is easy to implement as a custom control.

Scaling an Image

The ratio of a picture’s width to height is known as its aspect ratio. An image with an aspect ratio greater than 1 means that it is wider than it is high (landscape image). While an image with an aspect ratio of less than one is taller than it is wide (portrait image). If the aspect ratio is exactly 1 the image is square.

By comparing the aspect ratio of an image against the aspect ratio of our control we can determine if the best axis to stretch the image (in order to maximise its size) is vertically or horizontally. Once we have determined the maximum width or height of our scaled image we can then utilise the aspect ratio to calculate the other dimension in order to keep the same aspect ratio.

Creating a custom control

There are two main types of custom controls within a System.Windows.Forms based application, those that derive from the Control base class and those that derive from the UserControl base class. For this kind of custom control, deriving from System.Windows.Forms.Control is the best approach since we are after a fairly light weight control.

To make a custom control we simply need to declare a class which derives from Control:

using System.Windows.Forms;
 
public class AspectRatioPictureBox : Control
{
}

The code sample above is a complete custom control. Once it is compiled you will be able to place an AspectRatioPictureBox control onto a form, in the same way you would any other control such as a Button or Label.

The control however is quite boring, being a completely white rectangle making it indistinguishable from the form it is placed upon. Before we cover how to paint more attractive contents, we need a way for the user to specify the image they would like to display. The easiest way to do this is to implement a public property by adding the following to our class definition:

private Bitmap photo;
 
public Bitmap Image
{
   get { return photo; }
   set
   {
     photo = value;
 
     // Redraw the contents of the control
     Invalidate();
   }
}

Any public property exposed by our control will be accessible via the Properties window within the Forms Designer when the user utilises our control.

Notice the call to the Control.Invalidate method within the Image property setter? This is important, as this is the call which notifies the operating system that our control has changed state and needs to be redrawn. If the control is not invalidated, the OS will not attempt to redraw it and the user would not be able to see the new image that has just been provided. In general any property which affects the onscreen presentation of a custom control should invalidate it.

Now that we have a way to specify the bitmap we want to display, we can finally implement the code that will paint the contents of the control. We do this by overriding the OnPaint method as follows:

protected override void OnPaint(PaintEventArgs e)
{
  if (photo != null)
  {
    float controlAspect = (float)ClientSize.Width / (float)ClientSize.Height;
    float photoAspect = (float)photo.Width / (float)photo.Height;
 
    if (photoAspect < controlAspect)
    {
      // Stretch the height of the photo to match
      // the height of the control
      ....
    }
    else
    {
      // Stretch the width of the photo to match
      // the width of the control
      ....
    }
  }
}

The framework will call the OnPaint method each time the OS needs the control’s contents to be repainted onto the screen. For a complete implementation of this method see the sample application downloadable below.

Using a custom control

Using custom controls within your projects is reasonably straight forward. Once you have created your new custom control class you simply need to recompile your project in order for the control to be picked up by Visual Studio and displayed in the Toolbox as a custom control. This is shown in the above screenshot. Once an instance of the custom control has been placed onto a form its properties can be configured via the standard Property window.

Unlike the Desktop development environment, Smart Device custom controls do not directly utilise attributes such as [Description()] to configure their appeance and behaviour within the Visual Studio IDE. Instead Smart Device custom controls utilise what is called an XMTA file. Customising the design time experience of your custom controls will be discussed in a future blog post.

Sample Application

[Download aspectratiopictureboxtest.zip - 25.7KB]

A small sample application is available for download. It demonstrates the use of the AspectRatioPictureBox custom control developed within this blog entry in a number of different scenarios.

Feel free to utilise the included AspectRatioPictureBox.cs file within your own projects. As an added feature an additional property called “Restricted” has been added. When the Restricted property of the control is set to true the image will not be stretched any larger than it’s original size. When “unrestricted” the image will be stretched to take the full width or height of the control, even if that means stretching the image beyond it’s original size. The restricted mode is useful for image viewing applications where you don’t want to stretch small images and degrade their quality, while still ensuring large images are scaled down to fit the screen.

Determining the depth of a node within a TreeView control

Sunday, January 13th, 2008

Given a TreeNode somewhere within a TreeView control, a desktop System.Windows.Forms developer would query the TreeNode.Level property to determine the depth of the node within the tree as demonstrated below:

MessageBox.Show(
  String.Format("Depth of node: {0}",
    treeView1.SelectedNode.Level));

However as stated by the MSDN Documentation this property is not available on the .NET Compact Framework. This is because one of the techniques Microsoft has used to reduce the size of the .NET Compact Framework is to remove methods and properties from the Base Class Library when the same behaviour can be implemented with a couple of lines of code written by the user.

So although the .NET Compact Framework does not provide a TreeNode.Level property we can implement our own, but first we must come up with a suitable algorithm.

General algorithm
Given a node within the tree (represented by the TreeNode class) we can determine the node’s Parent by querying the Parent property. If we repeat this process we will eventually get to a node which has null for it’s parent. This node is called the root (or top) of the tree. If we count the number of nodes we walked over to reach this node we have calculated the depth (or level) of the node we started at. This algorithm is implementable within C#.

Pre C# v3 Implementation
The best we can do with C# version 1 or 2 is to replace calls to missing methods with calls to static helper methods we manually write. For example we could write the following helper class to replace the TreeNode.Level property.

namespace MyProject
{
  public static class Utils
  {
    public static int Level(TreeNode node)
    {
      int i = -1;
 
      // Walk up the tree until we find the
      // root of the tree, keeping count of
      // how many nodes we walk over in
      // the process
      while (node != null)
      {
        i++;
        node = node.Parent;
      }
 
      return i;
    }
  }
}

and make use of it as follows

MessageBox.Show(
  String.Format("Depth of node: {0}",
    Utils.Level(treeView1.SelectedNode)));

C# v3 Implementation
C# version 3 (first available with the .NET 3.5 framework release) introduces a language feature called extension methods. This is basically a compiler trick which allows us to call helper methods such as the one created above with a slightly different syntax, that makes it appear as if the new methods we define are part of the existing objects. Behind the scenes the compiler is simply rewriting our statements to use the old syntax.

To convert our helper method into an extension method we only need to convert the method prototype from

public static int Level(TreeNode node) { ... }

to

public static int Level(this TreeNode node) { ... }

The magical “this” keyword is enough to get the following syntax to work

MessageBox.Show(
  String.Format("Depth of node: {0}",
    treeView1.SelectedNode.Level()));

Notice how our new Level() method can be called as it it was a member of the TreeNode class. This is very close to the original syntax that a desktop developer would utilise. In this example ideally we would create an “extension property”, which would mean we could utilise identical syntax on both platforms, however C# v3 does not support extension properties, only extension methods.

Sample Application

[Download TreeNodeLevelExample.zip - 19KB]

A sample application is available for download. The application shows a simple tree view and allows the user to select different nodes within it. As different nodes are selected a label is updated to show the depth of the currently selected node.

There are two versions of the sample application. The first is designed for .NET CF 2.0 and uses the first technique demonstrated, while the second is for .NET CF 3.5 and demonstrates the cleaner extension method based syntax.

Daniel Moth among others have discussed various techniques to support cross compiling code across both the .NET Compact and Full desktop frameworks. Extension methods are another tool to add to the toolbox, allowing you to provide your own implementations for methods missing from the .NET Compact Framework without requiring code changes to your main application source code.

Is anyone aware of any discussions available online about why it was decided not to support extension properties (or events)? Is this something we can expect to see in C# version 4?

Capture and respond to user input to a notification bubble

Tuesday, October 30th, 2007

In my previous blog entry about notifications I mentioned that we had not covered the ResponseSubmitted event. Subscribing to this event allows you to respond to user input entered within a notification bubble. This blog entry discusses how you can capture and process user input within notifications.

Creating an HTML based form
The contents of a notification bubble is formatted using HTML. To request user input within a notification bubble we can utilise a HTML based form.

A simple form specified within HTML may look like the following example:

<form>
  Name: <input name="name" /><br />
  <input type="submit" />
</form>

Similar to a System.Windows.Forms base application there are a range of controls which can be used within an HTML based form. These controls are typically specified via an <input /> element, although there are some exceptions as shown in the following table:

Name HTML Syntax
Hidden Field
<input type="hidden" name="fieldname" value="default" />
Textbox (single line)
<input type="text" name="fieldname" value="default" />
Textbox (single line password)
<input type="password" name="fieldname" value="default" />
Textbox (multi line)
<textarea name="fieldname" cols="40" rows="5">
    default value
</textarea>
Radio buttons
<input type="radio" name="fieldname" value="1" />
<input type="radio" name="fieldname" value="2" />
<input type="radio" name="fieldname" value="3" />
Checkbox
<input type="check" name="fieldname" checked="true" />
Combobox
<select name="fieldname">
    <option value="1">option 1</option>
    <option value="2">option 2</option>
    <option value="3">option 3</option>
</select>

A sample form with two textbox controls could be specified within C# source code as follows:

Notification notif = new Notification();
notif.Text = @"<form>
    Field 1: <input type=""text"" name=""fieldname1"" /><br />
    Field 2: <input type=""text"" name=""fieldname2"" />
  </form>";

Buttons
Using the controls specified above allows a notification to accept input from the user. However it does not provide the user with a mechanism to submit a completed form to the application for further processing.

A form is typically submitted when the user presses a submit button. A submit button can be specified within HTML via the use of an <input type=”submit” /> element. Whenever the user presses the submit button the ResponseSubmitted event will be triggered, allowing the form to be processed by the application.

Buttons can also be utilised within a notification to temporarily hide or permanently close a notification without submitting a form (useful for cancel or postpone style buttons etc). These actions can be specified via the use of button elements within the HTML as demonstrated below:

<!-- This button will minimise the notification -->
<input type="button" name="cmd:2" value="Hide" />
 
<!-- This button will permanently close the notification -->
<input type="button" name="something" value="Close" />

The value attribute contains the text displayed on the button, while the name (i.e. “cmd:2″) controls the action which occurs when the button is pressed. The name “cmd:2″ is a special value indicating to the operating system that the notification should be minimised and displayed as an icon that can be clicked to redisplay the notification. Having a button with any other name will cause the notification to permiantly be dismissed without the ResponseSubmitted event firing. All other “cmd:n” style button names are reserved by Microsoft for future use.

Hyperlinks
A HTML form can also contain traditional hyperlinks such as the following example:

<a href="help">Display further help</a>

Whenever such a link is pressed within the notification, the ResponseSubmitted event will trigger and the response string will be the string specified as the href attribute (”help” in this example).

Many of the built in operating system notifications utilise hyperlinks to provide access to settings or customisation dialogs.

Processing the response
When a HTML form within a notification is submitted the ResponseSubmitted event will trigger and this is the ideal opportunity for an application to process the contents of a form. TheResponseEventArgs parameter passed to this event handler contains a Response property that includes the current values of all fields within the form encoded in a format known as application/x-www-form-urlencoded.

Section 17.13.4 of the HTML 4.01 standard discusses application/x-www-form-urlencoded form data with the following description of the encoding process.

This is the default content type. Forms submitted with this content type must be encoded as follows:

  • Control names and values are escaped. Space characters are replaced by `+’, and then reserved characters are escaped as described in [RFC1738], section 2.2: Non-alphanumeric characters are replaced by `%HH’, a percent sign and two hexadecimal digits representing the ASCII code of the character. Line breaks are represented as “CR LF” pairs (i.e., `%0D%0A’).
  • The control names/values are listed in the order they appear in the document. The name is separated from the value by `=’ and name/value pairs are separated from each other by `&’.

As an example, if the form specified above contained the strings “Hello World” and “Good Bye” it would be encoded and appear within the Response property as follows:

?fieldname1=Hello+World&fieldname2=Good+Bye

The Microsoft documentation for the Response property contains an example of how to parse such response strings. It does this via some rather brittle string search and replace style operations. The sample code is not very generic, as it will break if you change the structure of your form even a little (such as renaming a field) and it does not deal with decoding hex escaped characters.

Within the sample application mentioned below I have implemented a function calledParseQueryString which performs the application/x-www-form-urlencoded decode process and returns a more easily used Dictionary of field control names to value mappings. This allows you to write a ResponseSubmitted event handler which looks something like the following:

private void notification1_ResponseSubmitted(object sender,
    ResponseSubmittedEventArgs e) 
{ 
  // This dictionary contains a mapping between 
  // field names and field values. 
  Dictionary<string, string> controls = ParseQueryString(e.Response); 
 
  // Make use of the field values, in this case pulling the
  // values out of the textboxes and displaying a message
  // box.
  MessageBox.Show(String.Format("first field = {0}, second field = {1}", 
	controls["fieldname1"], controls["fieldname2"]); 
}

This should make the intention of the ResponseSubmitted event handler easier to determine, and makes for more easily maintained code. The “hard” part of the response parsing logic is now hidden away within the ParseQueryString function, leaving you with an easy to use collection of field values to play with.

Including images within a notification
Sometimes it is helpful to include a small image within a popup notification. This is possible, but as Keni Barwick found out, the syntax of your HTML has to be fairly precise for the notification balloon to locate the image (a similar situation to images within HTML help files).

You should have good success if you use the file:// protocol, and include a full path to your image using backward slashes to separate directories, i.e. use the format:

<img src="file:///path/to/image.bmp" />

For example to include the image \windows\alarm.bmp you would use the following HTML:

<img src="file:///windows/alarm.bmp" />

You could hard-code the path to your image file but this could cause problems if the user decides to install your application in a different location (on an SD card for example). If your images are stored in the same folder as your main executable you can determine the path to your images at runtime by using a function similar to the following code snippet:

using System.Reflection; 
using System.IO;
 
public string GetPathToImage(string fileName)
{
  // Determine the exe filename and path
  Assembly assembly = Assembly.GetExecutingAssembly();
  string executablePath = assembly.GetName().CodeBase;
 
  // Trim off the exe filename from the path
  executablePath = Path.GetDirectoryName(executablePath);
 
  // Add the specified filename to the path
  return Path.Combine(executablePath, fileName);
}
 
string imageURL = GetPathToImage("foo.bmp");

Sample Application

[Download notificationuserresponsesample.zip - 16KB]

A sample application is available for download. The sample demonstrates using a notification to specify the details of a pizza order. It also demonstrates the inclusion of an image within a notification.

When targeting a Windows Mobile 5.0 or above device, you could extend the sample by using thecustom soft keys feature mentioned in a previous blog entry to submit the notification by pressing a subkey instead of pressing a button within the body of the notification.

Please feel free to make use of the ParseQueryString method and any associated functionality within your own applications.

Custom soft keys for Notifications

Thursday, October 4th, 2007

Since my previous posting about Notifications within the .NET Compact Framework I have seen the question of how to provide custom menu items at the bottom of a notification come up a number of times. Today I am going to provide you with one solution to this challenge.

The short answer is that the Microsoft.WindowsCE.Forms.Notification class provided by the .NET Compact Framework does not expose the required functionality. Although the native notification API allows custom menus to be associated with a notification, for some reason this hasn’t be exposed to managed developers. With a little bit of work however (i.e. some PInvoking) you can produce your own managed wrapper around the Notification APIs to expose the required functionality.

I have done this and produced a class called NotificationWithSoftKeys. You can download a copy of this class, along with a sample application which demonstrates it’s various features below.

[Download notificationsoftkeys.zip 32KB]

The rest of this blog entry will demonstrate how you can utilise the class within your own applications. It is designed to be a stand in replacement for the existing class, but adds some additional properties and events.

Adding Spinners
Spinners are the first additional functionality theNotificationWithSoftKeys control exposes. A notification spinner is a little bit of text on the right hand side of a notification which sits in-between a pair of < and > buttons. The user can tap on these buttons to “spin” through a series of related notifications.

Here is a brief example of how to enable this feature within your notification.

private NotificationWithSoftKeys notification;
 
private void btnCreateNotification_Click(object sender, EventArgs e)
{
  notification = new NotificationWithSoftKeys();
  notification.Icon = Properties.Resources.Icon;
  notification.Caption = "This is my notification";
  notification.Text = "Spinner Test\t1 of 5";
  notification.Spinners = true;
  notification.SpinnerClicked +=
      new SpinnerClickEventHandler(notification_SpinnerClicked);
  notification.Visible = true;
}

The main thing you need to do is set the Spinners property to True in order to enable the Spinner functionality. After this any text within the Caption property after the first tab (\t) character will be displayed on the right hand side of the notification’s caption.

When the user presses the < or > buttons the SpinnerClicked event will fire. Within your event handler you should update your Notification’s Caption and Text properties to give the illusion that another notification has been displayed.

Display Current Time on Caption
Displaying the current system time on the caption is very straight forward. All you need to do is set the TitleTime property to true. 

Custom Buttons
This is the feature which will probably generate the most interest. The standard notification has a “Hide” button on the left soft key. Some built in applications however display notifications with alternative softkeys and perform different actions depending upon which softkey was selected. Using the NotificationWithSoftKey class we can achieve the same effect as demonstrated with the following example.

private NotificationWithSoftKeys notification;
 
private void btnCreateNotification_Click(object sender, EventArgs e)
{
  notification = new NotificationWithSoftKeys();
  notification.Icon = Properties.Resources.Icon;
  notification.Caption = "This is my notification";
  notification.Text = "A soft key test";
  notification.LeftSoftKey =
      new NotificationSoftKey(SoftKeyType.Dismiss, "Close");
  notification.RightSoftKey =
      new NotificationSoftKey(SoftKeyType.StayOpen, "View");
  notification.RightSoftKeyClick +=
      new EventHandler(notification_rightSoftKeyClick);
  }
 
  notification.Visible = true;
}

This example will display a notification with two soft keys. The left soft key will be labeled “Close” and will remove the notification, while the right soft key will be labeled “View” and trigger the RightSoftKeyClick event when selected.

Within this event handler you could open up a second form, delete something from a database or perform any other task you would like to in response to the user pressing the soft key.

There are a number of soft key types to choose from as shown below:

Type Description
Dismiss Remove the notification when the soft key is pressed
Hide Hide the notification when the softkey is pressed (but do not dismiss)
StayOpen Do not dismiss or hide the notification when the softkey is pressed.
Submit Submit the HTML form in the notification instead of calling the click event handler
Disabled The softkey is disabled (grayed out)

Backwards Compatibility
The additional features discussed today are only available on devices running Windows Mobile 5.0 or higher. If your application is targeting multiple device types, and you need to run on Pocket PC 2003 devices the new functionality will not work.

The NotificationWithSoftKeys class utilises techniques outlined in my blog posting on device and platform detection to fail gracefully on older devices. When the class detects an older device type, it will simply ignore all the soft key related properties and revert back to the old notification style.

Sometimes you may want to check if this fallback has occurred. For instance you may want to utilise the soft key buttons for user input. In this case you would need to use an alternative approach (such as HTML based buttons) when running on Pocket PC 2003 or older devices which don’t have softkeys. You can do this by checking thePlatformSupportsCustomSoftKeyButtons property and altering the other properties of theNotificationWithSoftKeys class as required.

Summary
This is still only scratching the surface of what is possible with the native notification APIs. There are a number of notification features which are not exposed by this wrapper. For example there are the following flags which could easily be exposed as properties.

  • SHNF_DISPLAYON - the display is forced to turn on for the notification
  • SHNF_SILENT - the notification is forced to be silent and not vibrate, regardless of system settings

Please feel free to download the sample project and have a play around with it. I would be keen to hear from anyone who attempts to use it or modifies it to expose additional functionality etc.

Add Cut/Copy/Paste functionality to a Textbox

Tuesday, October 2nd, 2007

Earlier I discussed how you could manually get the software keyboard (SIP) to display whenever a TextBox control gained focus. There was potentially a lot of event handlers to write, two for every control on a form. Today I will show you an alternative approach that utilises less code but also has some additional benefits.

A common thing I do while testing new Windows Mobile applications, is to tap-and-hold on a text field. Very well behaved applications should popup a context sensitive menu containing cut/copy/paste style options for the current control. Surprisingly, very few applications actually pass this test, even though it is a feature that has been built into the operating system for a while.

Within Windows CE the SIPPREF control can be used to automatically implement default input panel behavior for a dialog. It provides the following features:

  • The Input Panel is automatically shown/hidden as controls gain and loose focus.
  • Edit controls have an automatic context menu with Cut, Copy, Paste type options.
  • The SIP state is remembered if the user switches to another application and later returns to this form.

In my mind this has three advantages over the process I previously discussed.

  1. You add the SIPPREF control once and it automatically hooks up event handlers for each of your controls. With the manual event handler approach it’s easy to add a new control and forget to hook up the events required to handle the SIP.
  2. You get free localisation. Although you could create a custom context menu for cut/copy/paste, you would need to localise the text into multiple languages yourself (if you are concerned with true internalisation that is) and it’s another thing thing to hook up for each control.
  3. You get standardised behavior. By using functionality provided by the operating system you are ensuring that your application has a natural and expected behavior to it. If the platform ever changes the conventions of SIP usage, your application will automatically be updated.

For the rest of this blog entry I will discuss how to go about utilising the SIPPREF control within your application. I have split my discussion into two sections. The first section will be of interest to native developers developing in C or C++, while the second section is intended for .NET Compact Framework developers.

Each section contains a small example application which demonstrates the behaviour of the SIPPREF control within the respective environment. When you run the sample applications you will notice that the SIP does not popup up when you click within a text box. And a tap-and-hold operation yields nothing. This behaviour changes when a SIPPREF control is added to the dialog, which can be achieved by clicking the sole button.

Native Developers

[Download sipprefcontrolnativeexample.zip 16KB]

In order to use the SIPPREF control we must first request the operating system to register the SIPPREF window class. We do this by calling the SHInitExtraControls function. This step only needs to be done once, so is typically done during your application’s start up code. It is very easy to call, as the following example demonstrates:

#include <aygshell.h>
 
SHInitExtraControls();

Since SHInitExtraControls lives within aygshell.dll, we also need to modify our project settings to link with aygshell.lib, otherwise the linker will complain that it can not find the SHInitExtraControls function.

Once we have registered the SIPPREF window class, we simply create a SIPPREF control as a child of our dialog. When the SIPPREF control is created it will enumerate all sibling controls andsubclass them in order to provide the default SIP handling behaviour. The SIPPREF control must be the last control added to your dialog, as any controls added after the SIPPREF control will not be present when the SIPPREF control enumerates its siblings, and hence will not be subclassed to provide the proper SIP handling.

If dynamically creating the SIPPREF control, a good place to do this is within the WM_CREATE or WM_INITDIALOG message handler, as the following code sample demonstrates:

case WM_INITDIALOG:
  // Create a SIPPREF control to handle the SIP. This
  // assumes 'hDlg' is the HWND of the dialog.
  CreateWindow(WC_SIPPREF, L"", WS_CHILD,
       0,  0, 0, 0, hDlg, NULL, NULL, NULL);

As an alternative to dynamically creating the SIPPREF control, we can place the control within our dialog resource by adding the following control definition to the end of a dialog within the project’s *.rc file.

CONTROL  "",-1,WC_SIPPREF, NOT WS_VISIBLE,-10,-10,5,5

Depending upon your developer environment you may even be able to do this entirely from within the Resource Editor GUI. For example within Visual Studio 2005 you could drag the “State of Input Panel Control” from the Toolbox onto your form to cause a SIPPREF control to be added.

.NET Compact Framework Developers

[Download sipprefcontrolexample.zip 16KB]

The process of using the SIPPREF control for a .NET Compact Framework application is fairly similar to that of a Native application. Since the .NET Compact Framework does not natively support the use of dialog templates, we must use the CreateWindow approach to create a SIPPREF control dynamically at runtime.

The first step is to declare a number of PInvoke method declarations for the various operating system APIs we need to call.

using System.Runtime.InteropServices;
 
[DllImport("aygshell.dll")]
private static extern int SHInitExtraControls();
 
[DllImport("coredll.dll")]
private static extern IntPtr CreateWindowEx(
  uint dwExStyle,
  string lpClassName,
  string lpWindowName,
  uint dwStyle,
  int x,
  int y,
  int nWidth,
  int nHeight,
  IntPtr hWndParent,
  IntPtr hMenu,
  IntPtr hInstance,
  IntPtr lpParam);
 
  private static readonly string WC_SIPPREF = "SIPPREF";
  private static readonly uint WS_CHILD = 0x40000000;

One interesting fact is that we PInvoke a function called CreateWindowEx, while the native example above called CreateWindow. If you dig deeper into the Window Header files you will notice that CreateWindow is actually a macro which expands into a call to CreateWindowEx. At the operating system level the CreateWindow function doesn’t actually exist.

With this boiler plate code out of the way, the solution is very similar to the native one…

protected override void OnLoad()
{
     // Initialise the extra controls library
     SHInitExtraControls();
 
     // Create our SIPPREF control which will enumerate all existing
     // controls created by the InitializeControl() call.
     IntPtr hWnd = CreateWindowEx(0, WC_SIPPREF, "", WS_CHILD,
          0, 0, 0, 0, this.Handle, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
}

In the above example we simply create the SIPPREF control within the OnLoad method of our form. Within the downloadable sample project I have wrapped up this code into a static method called SIPPref.Enable(Form f) to enable to it easily be reused between forms.

Hopefully today I have shown you that having knowledge of the underlying operating system is still a useful skill to have for .NET Compact Framework developers. Knowing the features provided by the operating system can allow you to add some neat functionality to your applications with little additional effort on your behave.

Creating non full screen forms and custom MessageBoxes

Monday, October 1st, 2007

Every now and then someone asks how to create a .NET Compact Framework form which does not cover the fullscreen. Here is my solution to this problem.

This solution is built upon details discussed by other bloggers, including:

The trick is to set the form’s FormBorderStyle property to None. This disables the .NET Compact Framework’s built in functionality which forces a form to become fullscreen (on Windows Mobile devices), but also has the side effect of removing the border around the edge of the form. We can add the border (and a caption) back via the use of some PInvoke calls into the native operating system.

Points of interest

I decided to create my solution as two classes which are designed to be reusable within your own applications. One class enables the non full screen functionality, while the other provides an implementation for a common reason why non full screen forms are requested. These classes are as follows:

  1. NonFullScreenForm - a base class which you can use instead of Form. This base class allows you to have a form which does not cover the entire screen, and will optionally automatically center the form in the middle of the screen.
  2. MessageBoxForm - this is a subclass of NonFullScreenForm which provides a static method called Show. This method behaves in a similiar way to the standardMessageBox.Show API, with a few extensions such as the ability to use custom buttons.

Example Application

[Download nonfullscreendemo.ZIP 32Kb]

The example application available for download demonstrates the use of the NonFullScreenForm and MessageBoxForm classes via a series of buttons.

The first two buttons compare the behaviour of the standard MessageBox.Show API against our custom MessageBoxForm implementation for a number of message box styles. You will notice that the look and feel of our custom message boxes are similiar, but often have a slightly different layout.

The button labeled “Auto Centered Form” demonstrates the effect of setting NonFullScreenForm’s CenterFormOnScreen property to True. Whenever you tap the “Expand” or “Collapse” buttons the form changes size, and the NonFullScreenForm base class automatically changes the location of the form to ensure it is centered at all times. It will even re-center the form when the device switches between landscape and portrait modes.

How to use the NonFullScreenForm class

To use the NonFullScreenForm class within your own applications follow these steps:

  1. Add NonFullScreenForm.cs to your project.
  2. Set the FormBorderStyle property of your form to None.
  3. Set the Size and Location properties of your form to the desired size and position on the screen.
  4. View your form’s source code and change the form to derive from NonFullScreenForm instead of Form.
  5. If you want your form automatically centered on the screen set the CenterFormOnScreen property to true.
  6. If you don’t want an [OK] button in the caption, set the ControlBox property to false.

There are a number of areas where these custom controls could be improved. MessageBoxForm’s compatability could be improved. It does not support displaying an icon within the MessageBox at present for instance. There is also a slight flickering on the navbar (the bar at the top of the device which contains the start menu etc) when a non full screen dialog is created which would be nice to eventually remove. This is caused by the .NET Compact Framework dispaying the form before we have had a chance to change it’s window style to include a caption.

These controls were quickly put together to demonstrate what could be possible with a little bit of work. If anyone is interested in collaborating to improve these controls, I would be keen to hear from them.


Close
  • Social Web
  • E-mail
<FORM action="http://www.christec.co.nz/blog/index.php" method="post"> </FORM>
2009/01/15 00:08 2009/01/15 00:08

Visual studio 2008 설치시 문제점-지금은 해결됬을 수도 있음

Posted by 빵빵빵
2009/01/15 00:04 전산(컴퓨터)/PC-Windows



Visual Studio 2008 추가 정보

최신 버전의 Visual Studio 2008 추가 정보를 보려면 여기를 클릭하십시오.

목차

1. 시스템 요구 사항

1.1. 지원되는 아키텍처

  • x86
  • x64(WOW)

    1.2. 지원되는 운영 체제

  • Microsoft Windows XP
  • Microsoft Windows Server 2003
  • Windows Vista

    1.3. 하드웨어 요구 사항

  • 최소: CPU 1.6GHz, RAM 384MB, 1024x768 디스플레이, 하드 디스크 5400RPM
  • 권장: CPU 2.2GHz 이상, RAM 1024MB 이상, 1280x1024 디스플레이, 하드 디스크 7200RPM 이상?
  • Windows Vista: CPU 2.4GHz, RAM 768MB

    2. 알려진 문제

    2.1. 설치

    2.1.1. Visual Studio SharePoint 워크플로 기능에 특정 설치 요구 사항이 있습니다.

    Visual Studio Tools for Office에서 SharePoint 워크플로 개발 도구를 사용하려면 다음 설치 단계를 지정된 순서로 수행하십시오.

    1. Windows Server 2003을 설치합니다.

    2. IIS(인터넷 정보 서비스)를 설치합니다. 제어판에서 Windows 구성 요소 추가/제거, 응용 프로그램 서버, 자세히, 인터넷 정보 서비스(IIS)를 차례로 선택합니다.

    3. .NET Framework 2.0과 .NET Framework 3.0을 설치합니다.

    4. IIS 관리자에서 ASP.NET 2.0.5727을 활성화합니다.

    5. Microsoft Office SharePoint Server 2007을 설치합니다. 구성 마법사를 실행해야 합니다.

    6. Visual Studio 2008을 설치합니다. 기본 설치를 사용하거나, 설치 마법사의 사용자 지정 설치 페이지에서 Visual Studio Tools for Office가 선택되어 있는지 확인하십시오.

    7. (선택 항목) SMTP 서비스. 이 서비스를 설치하면 SharePoint 전자 메일 지원 기능을 사용할 수 있습니다. 이러한 기능에 대한 자세한 내용은 SharePoint 제품 설명서를 참조하십시오.

    이 문제를 해결하려면

    사용 가능한 해결 방법이 없습니다.

    2.1.2. SQL Server Compact 3.5 CTP 또는 SQL Server Compact 3.5 베타에서 SQL Server Compact 3.5의 릴리스 버전으로 업그레이드할 수 없습니다.

    SQL Server Compact 3.5의 CTP 및 베타 버전에서 릴리스 버전으로 업그레이드할 수 없습니다.

    이 문제를 해결하려면

    SQL Server Compact 3.5나 Visual Studio 2008의 릴리스 버전을 설치하기 전에 SQL Server Compact 3.5, SQL Server Compact 3.5 for Devices 및 SQL Server Compact 3.5 Design Tools의 CTP 및 베타 버전을 모두 제거합니다.

    2.1.3. "설치 구성 요소를 로드하는 동안 문제가 발생했습니다. 설치를 취소합니다."라는 오류 메시지가 나타납니다.

    "설치 구성 요소를 로드하는 동안 문제가 발생했습니다. 설치를 취소합니다."라는 오류 메시지가 나타난 다음 설치가 취소됩니다. 이 문제는 시스템에 Windows Installer 3.1이 설치되어 있지 않은 경우에만 발생합니다. Windows Installer 3.1을 설치한 다음 설치를 다시 시도해야 합니다.

    이 문제를 해결하려면

    1. 프로그램 추가/제거에서 설치된 프로그램 목록에 Windows Installer 3.1이 있는지 확인합니다.

    2. Windows Installer 3.1이 없으면 다음 단계를 수행하십시오.

      a. Windows Installer 3.1 Redistributable (v2)로 이동한 다음 Windows Installer 3.1을 설치합니다.

      b. Visual Studio 2008 설치를 다시 시도합니다.

    2.1.4. 설치가 중지되고 "Windows Installer 서비스를 중지하지 못했습니다. 설치하기 전에 Windows Installer 서비스를 실행하는 다른 모든 응용 프로그램을 중지하거나 컴퓨터를 다시 시작해야 합니다."라는 오류 메시지가 표시됩니다.

    설치가 중지되고 "Windows Installer 서비스를 중지하지 못했습니다. 설치하기 전에 Windows Installer 서비스를 실행하는 다른 모든 응용 프로그램을 중지하거나 컴퓨터를 다시 시작해야 합니다."라는 오류 메시지가 표시됩니다.

    이 문제를 해결하려면

    다음과 같은 옵션을 사용해 보십시오.

    - 이 메시지가 나타나면 컴퓨터에서 Visual Studio 2008 설치 프로그램이 아닌 설치 프로그램이 이미 실행 중일 수 있습니다. 다른 설치가 완료되면 컴퓨터를 다시 시작한 다음 Visual Studio 2008 설치 프로그램을 실행합니다.

    - 컴퓨터에 Windows 업데이트가 설치되는 중일 수도 있습니다. Windows Update가 완료되면 컴퓨터를 다시 시작한 다음 Visual Studio 2008 설치 프로그램을 실행합니다.

    - 작업 관리자에서 msiexec.exe를 확인합니다. msiexec.exe가 실행 중이면 종료될 때까지 기다렸다가 컴퓨터를 다시 시작하고 Visual Studio 2008 설치 프로그램을 실행합니다.

    - 이러한 옵션이 모두 문제에 적용되지 않으면 컴퓨터를 다시 시작한 다음 Visual Studio 2008 설치 프로그램을 실행합니다.

    2.1.5. Visual Studio 2008을 Visual Studio 2005가 설치된 컴퓨터에 설치하면 Visual Studio 2005에서 .NET Framework 2.0을 복구하지 못합니다.

    Visual Studio 2008을 Visual Studio 2005와 동일한 컴퓨터에 설치하면 Visual Studio 2005 복구 프로그램에서 .NET Framework 2.0을 복구하지 못합니다.

    이 문제를 해결하려면

    프로그램 추가/제거를 사용하여 .NET Framework 2.0을 개별적으로 복구합니다.

    2.1.6. Visual Studio 2008 설치 프로그램에서 실행 중인 응용 프로그램을 닫아야 한다는 메시지를 표시할 수 있습니다.

    Visual Studio 2008 설치 프로그램에서 실행 중인 응용 프로그램을 닫아야 한다는 메시지를 표시할 수 있습니다. 이 메시지에서 일부 응용 프로그램에는 숫자 식별자가 지정되어 있고 다른 응용 프로그램에는 빈 식별자가 지정되어 있을 수 있습니다. 응용 프로그램의 이름은 표시되지 않습니다.

    이 문제를 해결하려면

    설치 프로세스에 영향을 주지 않도록 해당 응용 프로그램을 닫는 것이 좋습니다.

    작업 관리자에서 프로세스 ID를 조회하여 해당 응용 프로그램의 이름을 확인할 수 있습니다.

    1. Ctrl+Alt+Delete를 누른 다음 작업 관리자를 클릭합니다.

    2. 보기 메뉴에서 열 선택을 클릭합니다.

    3. PID(프로세스 식별자)를 선택한 다음 확인을 클릭합니다.

    4. 작업 관리자에서 PID를 클릭하여 PID별로 항목을 정렬합니다.

    5. 메시지에 표시된 프로세스 ID를 검색합니다.

    메시지 상자에서 무시를 클릭한 후 설치를 계속할 수도 있습니다. 이렇게 하려면 설치가 끝난 후 컴퓨터를 다시 부팅해야 할 수 있습니다.

    2.2 제거

    2.2.1. 이전 버전의 Visual Studio가 있는 컴퓨터

    2.2.1.1. Windows SDK를 제거하면 Visual Studio 2008에 영향을 미칠 수 있습니다.

    Windows Vista용 Windows SDK나 Windows Vista용 Windows SDK Update를 Visual Studio 2008과 함께 설치한 다음 Windows SDK를 제거하면 Visual Studio에서 Windows 헤더, 라이브러리 및 도구를 찾는 데 필요한 레지스트리 키가 제거됩니다.

    이 문제를 해결하려면

    다음 작업 중 하나를 수행하십시오.

    - Windows Server 2003 및 Windows XP의 경우 프로그램 추가/제거를 사용하거나, Windows Vista 및 Windows Server 2008의 경우 프로그램 및 기능을 사용하여 Visual Studio 2008을 복구합니다.

    - .NET Framework 3.5 및 Windows Server 2008용 Windows SDK를 설치합니다.

    2.2.1.2. Visual Studio 2005를 제거하면 Load Agent에 필요한 레지스트리 항목이 지워집니다.

    Visual Studio 2005 Team System Edition for Testers 또는 Visual Studio 2005 Team Suite Edition이 있는 컴퓨터에 Visual Studio 2008 Team Test Load Agent를 설치한 다음 Visual Studio 2005를 제거하면 로드 생성에 필요한 다음 레지스트리 항목이 지워집니다.

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters]

    "MaxUserPort"=dword:0000FFFE

    "TcpTimedWaitDelay"=dword:0000001e

    이 문제를 해결하려면

    Visual Studio 2005를 제거한 후 해당 항목을 레지스트리에 다시 삽입합니다.

    2.2.2. 이전 버전의 Visual Studio가 없는 컴퓨터

    2.2.2.1. 한 Visual Studio 버전이 side-by-side 구성에서 제거된 후 워크플로를 더 이상 디버깅할 수 없습니다.

    두 Visual Studio 2008 버전(예: 영어 및 일본어 버전)이 컴퓨터에 설치되어 있는 경우 한 버전이 제거되면 나머지 버전에서 워크플로를 더 이상 디버깅할 수 없습니다. 설치 중 하나가 컴퓨터에서 제거되면 워크플로 디버거의 일부인 WDE.dll이 제거됩니다.

    이 문제를 해결하려면

    Visual Studio 2008 설치 프로그램에서 나머지 Visual Studio 버전을 복구하거나 제거합니다.

    2.2.2.2. Visual Studio 2008 설치 프로그램에서 실행 중인 응용 프로그램을 닫아야 한다는 메시지를 표시할 수 있습니다.

    Visual Studio 2008 설치 프로그램에서 실행 중인 응용 프로그램을 닫아야 한다는 메시지를 표시할 수 있습니다. 이 메시지에서 일부 응용 프로그램에는 숫자 식별자가 지정되어 있고 다른 응용 프로그램에는 빈 식별자가 지정되어 있을 수 있습니다. 응용 프로그램의 이름은 표시되지 않습니다.

    이 문제를 해결하려면

    설치 프로세스에 영향을 주지 않도록 해당 응용 프로그램을 닫는 것이 좋습니다.

    작업 관리자에서 프로세스 ID를 조회하여 해당 응용 프로그램의 이름을 확인할 수 있습니다.

    1. Ctrl+Alt+Delete를 누른 다음 작업 관리자를 클릭합니다.

    2. 보기 메뉴에서 열 선택을 클릭합니다.

    3. PID(프로세스 식별자)를 선택한 다음 확인을 클릭합니다.

    4. 작업 관리자에서 PID를 클릭하여 PID별로 항목을 정렬합니다.

    5. 메시지에 표시된 프로세스 ID를 검색합니다.

    메시지 상자에서 무시를 클릭한 후 설치를 계속할 수도 있습니다. 이렇게 하려면 설치가 끝난 후 컴퓨터를 다시 부팅해야 할 수 있습니다.

    2.3. 제품 문제

    2.3.1. 일반적인 문제

    2.3.1.1. Windows SDK의 사용자 지정 설치를 실행하면 존재하지 않는 파일을 가리키도록 파일 링크 경로가 변경될 수 있습니다.

    Windows SDK의 사용자 지정 설치를 실행하면 존재하지 않는 파일을 가리키도록 파일 링크 경로가 변경될 수 있습니다. Visual Studio 2008을 설치한 다음 Windows SDK를 설치하면 중요한 레지스트리 키가 변경됩니다. 이 키는 Windows 헤더 및 라이브러리뿐만 아니라 SDK 도구를 가리킵니다. 그러나 도구나 헤더 및 라이브러리가 포함되지 않은 Windows SDK의 사용자 지정 설치를 실행하면 해당 파일에 대한 링크가 끊어지고 일부 Visual Studio 기능이 손상됩니다.

    이 문제를 해결하려면

    Visual Studio 2008을 복구하거나 .NET Framework 3.5 및 Windows Server 2008용 Windows SDK와 함께 설치된 Windows SDK 구성 도구를 사용합니다.

    2.3.1.2. T-SQL을 사용한 Windows Workflow 디버깅이 지원되지 않습니다.

    워크플로 디버깅과 T-SQL 디버깅을 모두 사용하여 워크플로를 디버깅하는 경우 예기치 않은 결과가 발생할 수 있습니다.

    이 문제를 해결하려면

    사용 가능한 해결 방법이 없습니다.

    2.3.1.3. 64비트 버전의 Windows Vista에서 지역 창이 작동하지 않습니다.

    64비트 버전의 Windows Vista에서 Visual Studio가 실행되고 있을 때 지역 창이 표시되지 않습니다.

    이 문제를 해결하려면

    사용 가능한 해결 방법이 없습니다.

    2.3.1.4. 워크플로 프로젝트에 새 데이터베이스 단위 테스트를 추가하면 오류가 표시됩니다.

    워크플로 프로젝트에 새 데이터베이스 단위 테스트를 추가하면 다음과 같은 메시지가 표시됩니다.

    "워크플로를 로드하는 동안 오류가 발생했습니다. 워크플로를 보려면 다음 오류를 수정하고 문서를 다시 로드하십시오.
    이 파일에 디자인할 수 있는 클래스가 없으므로 디자이너에서 이 파일을 표시할 수 없습니다.
    디자이너에서 검사한 파일의 클래스는 다음과 같습니다. DatabaseUnitTest1. 이 클래스의 기본 클래스 DatabaseUnitTest1은(는) Activity이어야 합니다."

    이 메시지는 잘못 표시되는 것입니다. 새 데이터베이스 단위 테스트는 실제로 유효합니다. 메시지를 닫으면 메시지가 다시 나타나지 않습니다.

    이 문제를 해결하려면

    오류 메시지를 닫습니다. 이렇게 하면 메시지가 다시 나타나지 않습니다.

    2.3.1.5. Visual Basic Workflow Designer를 사용하려면 Visual Web Developer가 설치되어 있어야 합니다.

    Visual Studio 2008을 Visual Basic 전용 모드로 설치한 후 Workflow Foundation Designer가 제대로 작동하지 않습니다. 워크플로 프로젝트에서 필수 필드를 지정할 수 없으며 이로 인해 솔루션을 빌드할 수 없습니다.

    이 문제를 해결하려면

    Visual Studio 2008 설치 프로그램을 사용하여 Visual Web Developer를 설치합니다.

    2.3.1.6. Expression Blend에서 Visual Studio 2008 프로젝트를 빌드할 수 없습니다.

    Visual Studio 2008에서 만든 솔루션과 프로젝트는 Expression Blend에서 열고 편집할 수 있지만 빌드할 수는 없습니다. 또한 Visual Studio 2008에서 Expression Blend 프로젝트를 열면 해당 프로젝트가 Visual Studio 2008 형식으로 업그레이드됩니다. 프로젝트가 업그레이드된 후에는 Expression Blend에서 프로젝트를 더 이상 빌드할 수 없습니다. 하지만 Expression Blend에서 프로젝트를 계속 열고 편집할 수 있습니다.

    이 문제를 해결하려면

    가용성에 대한 자세한 내용과 설치 지침을 보려면 여기 Microsoft Expression 웹 사이트를 참조하십시오.

    2.3.1.7. Visual Studio 2008에서 이미 설치된 Windows Mobile 6 SDK를 인식하지 못합니다.

    Windows Mobile 6 SDK가 이미 설치된 컴퓨터에 Visual Studio 2008을 설치하면 Visual Studio 2008에서 SDK를 인식하지 못합니다. 이 경우 Windows Mobile 6 SDK를 복구하는 것만으로는 이 문제가 해결되지 않습니다.

    이 문제를 해결하려면

    1. Windows Mobile 6 SDK를 제거합니다.

    2. Windows Mobile 6 SDK를 다시 설치합니다.

    2.3.1.8. SQL Server Compact 3.5에서 SqlCeConnection 클래스의 Encrypt 속성을 사용하지 않습니다.

    SqlCeConnection 클래스의 Encrypt 속성은 사용하면 안 됩니다. 이 속성은 이전 버전과의 호환성을 위해서만 SQL Server Compact 3.5에서 유지됩니다.

    이 문제를 해결하려면

    SqlCeConnection 클래스의 암호화 모드 속성을 사용하여 SQL Server Compact 3.5 데이터베이스 파일을 암호화합니다. 코드 샘플과 함께 다음과 같이 암호화 모드를 사용할 수 있습니다.

    1. 암호화된 SQL Server Compact 3.5 데이터베이스를 새로 만들려면

    SqlCeEngine engine = new SqlCeEngine("Data Source=Northwind.sdf;encryption mode=platform default;Password=passw0rd;");
    engine.CreateDatabase();

    2. SQL Server 2005 Compact Edition(버전 3.1) 또는 SQL Server 2005 Mobile Edition(버전 3.0) 데이터베이스를 암호화된 SQL Server Compact 3.5 데이터베이스로 업그레이드하려면

    SqlCeEngine engine = new SqlCeEngine("Data Source=Northwind.sdf;Password=passw0rd;");
    engine.Upgrade ("Data Source=Northwind.sdf;encryption mode=platform default;Password=passw0rd;");

    3. 기존 SQL Server Compact 3.5 데이터베이스의 암호화 모드를 변경하려면

    SqlCeEngine engine = new SqlCeEngine("Data Source=Northwind.sdf;Password=passw0rd;");
    engine.Compact("Data Source=Northwind.sdf;encryption mode=ppc2003 compatibility;Password=passw0rd;");

    4. 암호화되지 않은 SQL Server Compact 3.5 데이터베이스를 암호화하려면

    SqlCeEngine engine = new SqlCeEngine("Data Source=Northwind.sdf");
    engine.Compact("Data Source=Northwind.sdf;encryption mode=platform default;Password=passw0rd;");

    2.3.1.9. SSC 3.1 데이터베이스를 대상으로 하는 경우 스마트 장치 프로그램의 디자인 타임 환경을 사용할 수 없습니다.

    스마트 장치 프로그래머는 SQL Server Compact Edition 3.1 데이터베이스를 대상으로 프로그래밍하는 경우 데이터 소스 추가, 새 연결 추가, 데이터베이스 만들기, 데이터 폼 생성 및 폼 디자이너에 데이터 소스 개체 끌어서 놓기와 같은 디자이너 기능을 모두 사용할 수 없습니다. 스마트 장치 디자이너 기능은 기본적으로 SQL Server Compact 3.5 데이터베이스를 대상으로 합니다.

    이 문제를 해결하려면

    Visual Studio 2005 서비스 팩 1을 사용하여 SQL Server Compact Edition 3.1 데이터베이스를 대상으로 스마트 장치 프로그램을 프로그래밍합니다. SQL Server Compact Edition 3.1 데이터베이스와 함께 Visual Studio 2008을 사용하는 방법에 대한 자세한 내용은 http://go.microsoft.com/fwlink/?LinkID=101885를 참조하십시오.

    2.3.1.10. Visual Studio 2005 프로젝트를 Visual Studio 2008로 업그레이드하는 동안 암호화된 SQL Server Compact 데이터베이스가 업그레이드되지 않고 ClickOnce 응용 프로그램을 다시 게시해야 합니다.

    이전 버전의 SQL Server Compact에서 만들어진 데이터베이스 파일(*.sdf)은 SQL Server Compact 3.5와 호환되지 않습니다. 이전 버전의 SQL Server Compact에서 암호화되지 않은 데이터베이스 파일은 Visual Studio 2005 프로젝트가 Visual Studio 2008에서 업그레이드될 때 업그레이드됩니다. 암호화된 데이터베이스 파일은 수동으로 업그레이드해야 합니다. Visual Studio 2005 프로젝트에서 ClickOnce를 사용하여 응용 프로그램을 게시하는 경우 Visual Studio 2008에서 프로젝트가 업그레이드된 후 해당 응용 프로그램을 다시 게시해야 합니다.

    이 문제를 해결하려면

    다음 단계를 수행하여 암호화된 데이터베이스 파일을 업그레이드합니다.

    1. 데이터를 클릭합니다.
    2. 새 데이터 소스 추가를 클릭합니다.
    3. 연결 추가를 클릭합니다. 이전 버전의 데이터베이스 파일이 열려 있으면 메시지가 나타납니다. 확인을 클릭하면 SQL Server Compact 3.5 데이터베이스(으)로 업그레이드 대화 상자가 나타납니다.

    또는 프로그래밍 시나리오에서는 다음 코드 예제와 같이 SqlCeEngine.Upgrade API를 사용할 수도 있습니다.

    SqlCeEngine engine = new SqlCeEngine("Data Source=Northwind.sdf;Password=passw0rd;");
    engine.Upgrade ("Data Source=Northwind.sdf;encryption mode=platform default;Password=passw0rd;");

    프로젝트에서 ClickOnce를 사용하여 응용 프로그램을 게시하는 경우 Visual Studio 2008에서 프로젝트가 업그레이드된 후 해당 응용 프로그램을 다시 게시해야 합니다. Visual Studio 2008에서 ClickOnce 응용 프로그램을 다시 게시하면 부트스트래핑에 필요한 SQL Server 2005 Compact Edition 필수 구성 요소를 찾을 수 없다는 경고가 표시될 수 있습니다. 이 경고는 무시해도 됩니다.

    2.3.1.11. SqlDbType 또는 DbType과 같은 매개 변수에 대한 SQL Server Compact 3.5 데이터 형식은 명시적으로 설정해야 합니다.

    SqlDbType 또는 DbType과 같은 매개 변수에 대한 데이터 형식을 명시적으로 설정하지 않으면 예외가 throw됩니다.

    이 문제를 해결하려면

    SqlDbType 또는 DbType과 같은 매개 변수에 대한 데이터 형식을 명시적으로 설정합니다. BLOB 데이터 형식(이미지 및 ntext)의 경우 반드시 이렇게 설정해야 합니다. 코드 예제는 다음과 같습니다.

    SqlCeEngine engine = new SqlCeEngine(connString); 
    engine.CreateDatabase(); 
    engine.Dispose(); 
    SqlCeConnection conn = new SqlCeConnection(connString); 
    conn.Open(); 
    SqlCeCommand cmd = conn.CreateCommand(); 
    cmd.CommandText = "CREATE TABLE BlobTable(name nvarchar(128), blob ntext);"; 
    cmd.ExecuteNonQuery(); 
    cmd.CommandText = "INSERT INTO BlobTable(name, blob) VALUES (@name, @blob);"; 
    SqlCeParameter paramName = cmd.Parameters.Add("name", SqlDbType.NVarChar, 128); 
    SqlCeParameter paramBlob = cmd.Parameters.Add("blob", SqlDbType.NText); 
    paramName.Value = "Name1"; 
    paramBlob.Value = "Name1".PadLeft(4001); 
    cmd.ExecuteNonQuery();

    2.3.1.12. Visual Studio의 UI가 흐리게 나옵니다.

    Visual Studio 2008은 맑은 고딕을 기본 환경 글꼴로 사용합니다. Windows XP나 Windows Server 2003에서 이 글꼴을 선명하게 보려면 ClearType을 사용해야 합니다. ClearType을 사용하려면,

    1. 제어판 에서 디스플레이를 선택합니다.
    2. 화면 배색 탭에서 효과 버튼을 클릭합니다. 
    3. 화면 글꼴의 가장자리를 다듬는 데 다음 방법 사용 확인란을 선택한 다음 목록에서ClearType을 선택합니다. 확인 버튼을 클릭합니다. 
    4. 확인 버튼을 클릭합니다. 

    또는, ClearType Tuner(영문)을 이용하여 ClearType을 사용하도록 설정합니다.

    2.3.1.13. MSDN Library에서 "Microsoft에 이 항목에 대한 사용자 의견 보내기" 링크를 통해 전자 메일을 보낼 경우 제목 혹은 본문이 깨질 수 있습니다.

    MSDN Library 도움말의 하단의 Microsoft에 이 항목에 대한 사용자 의견 보내기 링크를 통해 메일을 보낼 때 제목 혹은 본문이 한국어 Microsoft Office Outlook 및 Windows Mail(Outlook Express)에서 깨지는 경우가 발생할 수 있습니다. 도움말의 본문에 사용된 [한국어] 인코딩과, 메일 프로그램에서 메일을 내보낼 때 사용 하는 인코딩이 다를 경우 발생합니다.

    이 문제를 해결하려면

    Microsoft Office Outlook에서 본문이 깨지는 문제점을 해결하려면, Microsoft Office Outlook의 다음 설정을 변경하십시오.

    1. 도구 메뉴에서, 옵션을 선택합니다.
    2. 메일 형식 탭을 선택한 후, 국가별 옵션을 선택합니다. 
    3. 인터넷 프로토콜 아래 mailto: 프로토콜에 UTF-8 지원 사용 확인란의 선택을 해제하여 사용하지 않도록 합니다. 

    참고: 제목이 깨진 경우, 깨진 문자열은 선택하신 도움말의 제목입니다. 

    2.3.2. ADO.NET

    2.3.2.1. Visual Studio 2008을 업그레이드한 후, MDAC 2.8 필수 구성 요소가 없거나 빌드된 응용 프로그램이 Windows 2000에 설치된 후 실행되지 않는다는 경고가 표시됩니다.

    다음 문제 중 하나가 발생할 수 있습니다.

    - Visual Studio 2005 프로젝트를 Visual Studio 2008로 업그레이드했고 이제 필수 구성 요소가 없다는 빌드 경고가 나타납니다.

    - MDAC를 사용하는 빌드된 응용 프로그램이 Windows 2000에서 실행되지 않습니다.

    - MDAC가 없기 때문에 Windows 2000 사용자가 ClickOnce 응용 프로그램을 실행할 수 없습니다.

    이 문제를 해결하려면

    - MDAC가 필요하지 않은 경우 빌드 경고가 나타나면 필수 구성 요소 대화 상자를 연 다음 MDAC 필수 구성 요소를 지웁니다.

    - Windows 2000 클라이언트를 대상으로 하는 경우 MDAC 필수 구성 요소가 필요하면 다음과 같이 인터넷에서 부트스트래퍼 패키지를 다운로드합니다.

    1. 필수 구성 요소 대화 상자를 연 다음 '재배포 가능 구성 요소에 대한 자세한 내용은 Microsoft Update를 참조하십시오.'를 클릭합니다. 이렇게 하면 http://go.microsoft.com/fwlink/?linkid=40981이 열립니다.

    2. 웹 페이지에서 MDAC 부트스트래퍼 패키지를 다운로드하고 \Program Files\Microsoft SDKs\Windows\v6.0A\Bootstrapper\Packages\의 새 폴더에 저장합니다.

    - Visual Studio 2005에서 부트스트래퍼 패키지를 가져옵니다.

    1. Visual Studio 2005가 같은 컴퓨터에 설치되어 있으면 \Program Files\Microsoft Visual Studio 8\SDK\v2.0\BootStrapper\Packages\의 MDAC28 폴더를 복사한 다음 \Program Files\Microsoft SDKs\Windows\v6.0A\Bootstrapper\Packages\에 붙여 넣을 수 있습니다.

    2.3.3. 언어

    알려진 문제가 없습니다.

    2.3.4. LINQ

    2.3.4.1. Visual Studio 2008 베타 2를 사용하여 만든 .dbml 파일을 열면 O/R 디자이너(개체 관계형 디자이너)에서 "유니코드 바이트 순서 표시가 없습니다. 유니코드로 전환할 수 없습니다."라는 메시지를 표시합니다.

    Visual Studio 2008 베타 2에서 O/R 디자이너는 실제 파일에 UTF-16 인코딩이 지정된 경우에도 .dbml 파일을 UTF-8 바이트 순서로 만듭니다. 베타 2를 사용하여 만든 .dbml 파일을 열면 "유니코드 바이트 순서 표시가 없습니다. 유니코드로 전환할 수 없습니다."라는 오류가 발생할 수 있습니다.

    이 문제를 해결하려면

    솔루션 탐색기에서 .dbml 파일을 마우스 오른쪽 단추로 클릭하고 XML 편집기를 사용하여 연 다음 저장합니다. 이렇게 하면 .dbml 파일의 실제 내용이 영향을 받지 않으며 데이터가 손실되지 않습니다.

    2.3.5. Visual Studio Tools for Office

    2.3.5.1. Office InfoPath 2007 폼 템플릿을 미리 보려면 Office 2007 서비스 팩 1이 필요합니다.

    InfoPath 2007 서비스 팩 1 또는 QFE가 설치되어 있지 않은 경우 Visual Studio 2008에서 F5 키를 누르거나 미리 보기 단추를 클릭하여 Office InfoPath 2007 폼 템플릿을 미리 보려고 하면 미리 보기가 실패하고 오류가 표시됩니다.

    이 문제를 해결하려면

    QFE는 http://go.microsoft.com/fwlink/?LinkId=102084에서 사용할 수 있습니다.

    2.3.5.2. 64비트 운영 체제에서 Office SharePoint 워크플로 템플릿을 사용할 수 없으며 사용하려고 하면 예외가 발생합니다.

    64비트 컴퓨터에 SharePoint 워크플로 프로젝트(SharePoint 2007 순차 워크플로 또는 SharePoint 2007 상태 시스템 워크플로)를 만들려고 하면 Visual Studio 2008에서 두 예외를 throw합니다. 첫 번째 예외 메시지는 "개체 참조가 개체의 인스턴스로 설정되지 않았습니다."이고, 두 번째 메시지는 "입력된 SharePoint 사이트 위치가 잘못되었습니다. http://에 SharePoint 사이트가 없습니다. URL을 올바르게 입력했는지 확인하십시오."입니다.

    이 문제를 해결하려면

    64비트 운영 체제를 실행하는 컴퓨터에서 Visual Studio SharePoint 워크플로 템플릿을 사용하지 마십시오. 자세한 내용은 도움말 항목 "SharePoint 워크플로 솔루션 문제 해결"을 참조하십시오.

    2.3.5.3. Visual Studio 2008 베타 2에서 Visual Studio 2008의 최종 버전으로 VSTO(Visual Studio Tools for Office) 프로젝트 마이그레이션

    Visual Studio의 최종 릴리스 버전에서 베타 2 Office 프로젝트를 빌드하고 실행하면 빌드 및 런타임 오류가 발생할 수 있습니다. 많은 VSTO 참조 어셈블리가 변경되었습니다.

    이 문제를 해결하려면

    이름이 바뀐 어셈블리: 다음 참조 어셈블리에 대한 오류가 발생하면 이전 참조 어셈블리를 삭제하고 해당하는 새 참조 어셈블리를 프로젝트에 추가한 다음 다시 빌드합니다.

    이전 참조                                                                                    새 참조

    Microsoft.VisualStudio.Tools.Applications.ServerDocument.dll                Microsoft.VisualStudio.Tools.Applications.ServerDocument.v9.0.dll

    Microsoft.VisualStudio.Tools.Office.dll                                                  Microsoft.Office.Tools.v9.0.dll

    Microsoft.VisualStudio.Tools.Office.Common.dll                                    Microsoft.Office.Tools.Common.v9.0.dll

    Microsoft.VisualStudio.Tools.Office.Excel.dll                                         Microsoft.Office.Tools.Excel.v9.0.dll

    Microsoft.VisualStudio.Tools.Office.Outlook.dll                                      Microsoft.Office.Tools.Outlook.v9.0.dll

    Microsoft.VisualStudio.Tools.Office.Word.dll                                          Microsoft.Office.Tools.Word.v9.0.dll

    2.3.6. 웹 개발

    알려진 문제가 없습니다.

    2.3.7. WCF(Windows Communication Foundation) Tools

    2.3.7.1. Biztalk Service SDK가 설치된 경우 WcfTestClient에서 예외를 throw할 수 있습니다.

    Biztalk Service SDK는 machine.config 파일에 있는 <system.serviceModel> 요소의 <client> 섹션에서 MEX(메타데이터 교환) 끝점을 도입합니다. 이 설정으로 인해 WcfTestClient에서 서비스가 호출될 때 다음과 같은 예외가 생성됩니다.

    System.NullReferenceException: "개체 참조가 개체의 인스턴스로 설정되지 않았습니다."

    이 문제를 해결하려면

    WcfTestClient를 실행할 때 <system.serviceModel> 요소에 중첩된 <client> 섹션을 주석으로 처리하여 \WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG\에 있는 machine.config 파일을 수정합니다. Biztalk Service SDK를 사용할 때 해당 섹션을 다시 활성화합니다.

    2.3.7.2. WCF 샘플의 Setupvroot.bat 설치 스크립트가 Windows Vista에서 작동하지 않을 수 있습니다.

    Windows Vista에서 NetMsmqActivator 서비스가 활성화되어 있고 메시지 큐(MSMQ)가 설치되어 있지 않으면 iisreset 유틸리티가 작동하지 않고 WCF 샘플 설치 스크립트 Setupvroot.bat가 실행되지 않습니다.

    이 문제를 해결하려면

    WCF 샘플 설치 스크립트 Setupvroot.bat를 실행하기 전에 Windows Vista에서 MSMQ가 설치되어 있거나 NetMsmqActivator 서비스가 비활성화되어 있는지 확인합니다.

    2.3.7.3. WcfTestClient에서 WCF의 일부 기능을 지원하지 않습니다.

    다음과 같은 WCF 기능은 이 릴리스의 WcfTestClient에서 지원되지 않습니다.

    - 메시지 계약 및 XML serialization, WCF가 아닌 웹 서비스

    - 세션/컨텍스트 바인딩

    - 트랜잭션

    - 이중 계약

    - Windows CardSpace, 인증서, 사용자 이름/암호, Windows 인증

    - 형식: 스트림, IDictionary 컬렉션 및 데이터 집합

    이 문제를 해결하려면

    사용 가능한 해결 방법이 없습니다.

    2.3.7.4. Service Model Metadata 유틸리티 도구(SvcUtil.exe)를 통해 실행 중인 서비스에서 데이터 계약을 생성할 수 없습니다.

    Svcutil.exe 도움말 출력 끝 부분에 나와 있는 예제에서는 /dataContractOnly(/dconly) 옵션을 사용하여 실행 중인 서비스에서 데이터 계약을 생성할 수 있음을 보여 줍니다.

    svcutil.exe /dconly http://service/metadataEndpoint 
    - 실행 중인 서비스 또는 온라인 메타데이터 문서에서 데이터 계약 형식을 생성합니다.

    하지만 이 사용법은 올바르게 작동하지 않습니다. /dconly 옵션은 로컬 메타데이터 파일에서 데이터 계약을 생성하는 데에만 사용할 수 있습니다.

    이 문제를 해결하려면

    1. 다음 명령을 실행하여 실행 중인 서비스에서 메타데이터를 다운로드합니다.

    svcutil.exe /target:metadata http://service/metadataEndpoint

    2. 다음과 같이 다운로드한 메타데이터 파일에 대해 /dconly 옵션을 사용하여 Svcutil.exe를 실행합니다.

    svcutil.exe /dconly *.wsdl *.xsd

    2.3.7.5. Service Model Metadata 유틸리티 도구(Svcutil.exe)의 코드 생성 언어 지원

    Svcutil.exe 도구를 통해 관리 코드 공급자가 있는 언어의 메타데이터에서 웹 서비스 클라이언트 및 데이터 형식에 대한 코드를 생성할 수 있습니다. Svcutil.exe는 C#, Visual Basic 및 C++ 관리 코드 공급자를 사용하여 테스트를 거쳤습니다. 하지만 다른 코드 공급자는 테스트를 거치지 않았으며 컴파일되지 않거나 사용할 수 없는 코드를 생성할 수도 있습니다.

    이 문제를 해결하려면

    지원되는 관리 코드 공급자 중 하나를 사용하거나, 생성된 코드를 수동으로 편집하여 컴파일 문제를 해결합니다.

    2.3.7.6. Service Model Metadata 유틸리티 도구(Svcutil.exe)를 사용하여 생성된 Managed C++ 코드를 컴파일할 수 없습니다.

    Svcutil.exe 도구를 사용하면 메타데이터에서 웹 서비스 클라이언트 및 데이터 형식에 대한 코드를 생성할 수 있습니다. 그러나 Visual Studio 2008의 C++ 코드 공급자에는 Svcutil.exe에서 컴파일할 수 없는 Managed C++ 코드를 생성하게 할 수 있는 알려진 문제가 있습니다.

    이 문제를 해결하려면

    생성된 코드를 수동으로 변경하여 컴파일러 오류를 해결합니다.

    2.3.8. WPF(Windows Presentation Foundation) Designer for Visual Studio

    2.3.8.1. 속성 브라우저에서 미국 형식을 사용하여 날짜 및 숫자와 같은 값을 표시합니다.

    WPF 디자이너의 속성 브라우저에서는 미국 형식을 사용하여 값을 표시하고 편집합니다. 이는 en-US CultureInfo를 사용하는 XAML 규칙과 일치합니다. 예를 들어, 날짜와 숫자는 항상 미국 형식입니다. 날짜는 항상 mm/dd/yy로 표시됩니다. 속성 브라우저에서 날짜 값을 입력하면 날짜가 mm/dd/yy 형식으로 간주되어 변환됩니다.

    이 문제를 해결하려면

    사용 가능한 해결 방법이 없습니다.

    2.3.8.2. 코드 리팩터링을 통해 XAML 파일이 변경되지 않습니다.

    코드 리팩터링을 사용하여 형식이나 멤버를 수정하는 경우 리팩터링이 XAML 파일로 전파되지 않습니다.

    예를 들어, MyCustomControl이라는 UserControl이 있는 경우 리팩터링을 사용하여 코드 파일에서 해당 UserControl의 이름을 FancyControl로 변경하면 이 이름 변경이 코드 파일에만 영향을 미치고 XAML 파일에 있는 MyCustomControl의 인스턴스가 업데이트되지 않습니다. 또한 프로젝트나 솔루션을 다시 빌드하거나 정리할 때까지 빌드가 오류 없이 잘못 성공할 수 있습니다.

    이 문제를 해결하려면

    직접적인 해결 방법이 없습니다. 찾기 및 바꾸기를 사용하여 수정해야 합니다.

    2.3.8.3. XAML 파일을 변경하면 코드 파일이 리팩터링되지 않습니다.

    XAML 파일에서 형식이나 멤버를 변경하는 경우 해당 변경이 코드 파일로 전파되지 않습니다.

    예를 들어, XAML 편집기를 사용하여 이벤트 처리기와 연결된 Button의 이름을 변경하는 경우 숨김 코드가 업데이트되지 않습니다.

    이 문제를 해결하려면

    직접적인 해결 방법이 없습니다. 찾기 및 바꾸기를 사용하여 수정해야 합니다.

    2.3.8.4. 솔루션 탐색기에서 이름을 바꾸면 WPF 프로젝트에서 이름 바꾸기 리팩터링에 대한 메시지가 표시되지 않습니다.

    솔루션 탐색기에서 XAML 파일을 마우스 오른쪽 단추로 클릭한 다음 이름 바꾸기를 클릭하면 파일 이름이 변경되지만 XAML이나 숨김 코드에서 클래스 이름을 리팩터링하라는 메시지가 표시되지 않습니다. 특히 응용 프로그램 XAML 파일에서 StartupUri 속성이 참조하는 XAML 파일의 이름을 바꾸는 경우(예를 들어, Window1.xaml을 MainWindow.xaml로 바꾸는 경우) StartupUri 속성을 수동으로 변경해야 합니다.

    이 문제를 해결하려면

    직접적인 해결 방법이 없습니다. 찾기 및 바꾸기를 사용하여 수정해야 합니다.

    2.3.9. WF(Windows Workflow Foundation) Tools

    2.3.9.1. Visual C++ 개발 설정을 사용할 때 Visual Studio 2008 도구 상자에 사용자 지정 작업이 나타나지 않습니다.

    Visual C++ 개발 설정을 사용할 때 Visual Studio 2008 도구 상자에 사용자 지정 작업이 나타나지 않습니다.

    이 문제를 해결하려면

    Visual Basic 또는 C#과 같은 다른 개발 설정을 사용합니다.

    2.3.10. Windows SDK 통합

    알려진 문제가 없습니다.

    3. 관련 링크

    3.1. Visual Studio Team Foundation Server 추가 정보: http://go.microsoft.com/fwlink/?LinkId=102510

    3.2. Visual Studio Express Edition 추가 정보: http://go.microsoft.com/fwlink/?LinkId=102509

    3.3. .NET Framework 추가 정보: http://go.microsoft.com/fwlink/?LinkId=1102511

    3.4. MSDN Library for Visual Studio 추가 정보: http://go.microsoft.com/fwlink/?LinkId=102512

    3.5. http://go.microsoft.com/fwlink/?LinkID=96191에서 SQL Server Compact 3.5 온라인 설명서 및 샘플을 다운로드하고 http://go.microsoft.com/fwlink/?LinkId=80742에 서 Synchronization Services for ADO.NET v1.0 온라인 설명서 및 샘플을 다운로드합니다. 이러한 온라인 설명서와 샘플을 Visual Studio 전체 도움말 컬렉션에 추가하려면 다음 단계를 수행하십시오.

    1. 시작을 클릭하고 모든 프로그램, Microsoft Visual Studio 2008을 차례로 가리킨 다음 Microsoft Visual Studio 2008 설명서를 클릭합니다.
    2. Visual Studio 전체 도움말 컬렉션에서 도움말을 클릭한 다음 색인을 클릭합니다.
    3. 찾을 대상 상자에 컬렉션 관리자를 입력한 다음 색인에서 컬렉션 관리자 아래의 도움말 항목을 클릭합니다.
    4. 전체 도움말 컬렉션 관리자 항목에서 SQL Server Compact 3.5를 선택한 다음 VSCC 업데이트를 클릭합니다.
    5. 나타나는 두 대화 상자에서 요구 사항을 읽은 다음 확인을 클릭합니다.
    6. Visual Studio 전체 도움말 컬렉션을 닫은 다음 다시 엽니다. 이제 SQL Server Compact 온라인 설명서를 목차, 색인, 검색 및 F1 도움말에서 사용할 수 있습니다.

    3.6. Visual Studio 2008에서 WPF 디자이너를 사용할 때의 문제에 대한 최신 정보는 Channel9,http://go.microsoft.com/fwlink/?LinkId=83541의 Cider wiki를 참조하십시오.

    3.7. Visual J# MSDN 개발자 센터: http://go.microsoft.com/fwlink/?LinkId=102513

    3.8. http://go.microsoft.com/fwlink/?LinkId=102514에서 XML to Schema 도구를 다운로드할 수 있습니다.

    XML to Schema 도구는 원하는 수의 XML 문서에서 XML 스키마 집합을 자동으로 만드는 무료 프로젝트 항목 템플릿입니다. Visual Basic 2008에서 LINQ to XML로 작업하는 경우 이 유틸리티를 사용하면 XML 속성에 대한 IntelliSense를 제공하는 XML 스키마(.xsd 파일)를 프로젝트에 추가하여 편집 기능을 크게 개선할 수 있습니다. 이 도구를 사용하여 기존 XML 문서의 집합에서 XML 스키마 집합을 만들 수도 있습니다.

    ⓒ 2007 Microsoft Corporation. All rights reserved. 사용 약관  | 상표  | 개인 정보 보호 정책

  • 2009/01/15 00:04 2009/01/15 00:04

    .Net framework 전체 소스 다운로드 받기

    Posted by 빵빵빵
    2009/01/15 00:03 전산(컴퓨터)/PC-Windows



    출처 : http://blog.jeidee.net/313

    얼마전에 .NET Framework library 소스가 공개되었다는 포스팅을 했었죠.
    해당 포스트에서 직접 Visual Studio 2008에서 MS의 심볼파일 리소스 경로를 지정해 디버깅 환경을 설정하는 방법을 소개했었습니다.
    하지만 위의 방법은 항상 온라인 상태여야 한다는 점과 디버깅시 해당 심볼파일이 캐쉬에 없을 경우 내려받아야 하기 때문에 느려지는 문제가 있었는데,
    반갑게도 전체 소스를 내려받아 로컬에 저장해 놓을 수 있는 방법이 공개되었습니다.

    원문 포스트 링크는 다음과 같습니다.
    Download All the .NET Reference Source Code at Once with Net Mass Downloader

    .NET Mass Downloader를 사용해 전체 소스를 다운로드 받을 수 있는 방법에 대해 설명하고 있습니다.
    .NET Mass Downloader는 오픈소스로서 CodePlex에 프로젝트가 호스팅되어 있습니다.
    CodePlex .NET Mass Downloader Home

    그럼 .NET Mass Downloader의 최신 릴리즈를 다운로드 받아 .NET Framework 2.0 소스를 다운로드 받아 보도록(3.0과 3.5 프레임워크 라이브러리 소스 다운로드하기는 이 곳을 참조하세요.) 하지요.

    1. .NET Mass Downloader 구하기

    최신 릴리지는 CodePlex의 .NET Mass Downloader 프로젝트 Release 페이지에 있습니다.
    Version 1.1 Release 페이지

    2. 다운로드 받은 ReleaseVersion11.zip 파일의 압축을 풉니다.

    3. 명령프롬프트를 열고 압축이 해제된 폴더로 경로를 이동합니다.

    4. 다음 명령을 입력합니다.

    netmassdownloader -d "c:\windows\microsoft.net\framework\v2.0.50727" -output c:\cachetest -v

    5. 정상적으로 다운로드 될 경우 다음과 같이 다운로드 과정이 출력됩니다.


    다운로드 받은 소스를 사용해서 Visaul Studio 2008에서 디버깅 환경을 설정하는 방법은 이전 포스트를 참조하시고,
    이번에는 Visual Studio 2005에서 디버깅 환경을 설정하는 방법을 설명하겠습니다.

    1. 다운로드 받은 경로는 c:\cachetest 폴더입니다.

    2. Visual Studio 2005의 도구->옵션 메뉴를 선택합니다.

    3. 옵션 다이얼로그에서 디버깅->기호 항목을 선택합니다.


    기호파일(.pdb) 위치 리스트박스에 c:\cachetest 경로를 추가합니다.

    4. 옵션 다이얼로그에서 디버깅->일반 항목을 선택합니다.

    <내 코드만 사용(관리 전용)> 항목을 체크 해제합니다.
    <소스파일이 원래 버전과 정확하게 일치해야 함> 항목을 체크 해제합니다.

    5. 새 프로젝트를 하나 생성한 후 솔루션 탐색기에서 솔루션 속성 다이얼로그를 엽니다.
    소스 코드가 포함되어 있는 디렉터리 리스트 박스에 c:\cachetest 경로를 제일 상단에 추가합니다.

    6. 폼 위에 버튼을 생성하고 버튼의 Click 이벤트 핸들러에 MessageBox.Show() 문장을 입력합니다.

    7. MessageBox.Show(...)문장에 중단점을 걸고 디버깅을 시작합니다.
    버튼을 클릭한 후 실행이 정지되면 디버그 메뉴에서 <한 단계씩 코드 실행> 메뉴를 선택합니다.
    정상적으로 설정이 완료되었다면 다음과 같이 다운로드 받은 프레임워크 소스로 디버깅 위치가 이동하는 것을 볼 수 있습니다.


    이상으로 .NET Framework 2.0 소스를 다운로드 받아 Visual Studio 2005에서 디버깅 환경을 설정하는 방법까지 살펴보았습니다.
    2009/01/15 00:03 2009/01/15 00:03