Blog
Archive
<October 2009>
SunMonTueWedThuFriSat
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567
Monthly
Go
Search
  |  
Author: Created: Tuesday, September 09, 2008 1:58:59 PM RssIcon
News and updates about code4ward.net
By Stefan Koell on Thursday, October 29, 2009 3:48:44 PM

This is a step-by-step guide in multiple parts:

Part 1 will cover the Probe Actions Module Types: Part 1 is available here on SCC or here on code4ward 
Part 2 will be about creating a Data Source
Part 3 will cover creating a Monitor Type
Part 4 will cover the Unit Monitor itself

As always be careful with the samples provided here. Always use a test environment first to try those examples!

Will only work with OpsMgr 2007 R2 !

Part 2: Data Source

What do we need a data source for?

The data source we create will be needed in out monitor type (which will be explained in Part 3 of this series). So far we only defined a module which is returning a property bag with our state information and a wrapped up module we use for a (diagnostic-)task later on. In the latter case, the trigger for our module will be the operator launching the task. For our monitor we need a scheduler to trigger our probe – so for this we will create a simple data source.

Creating the Data Source

image

Change to the Data Sources node and right-click to create a New->Composite Data Source…

The ID will be: code4ward.Sample.PowerShellMonitor.DataSource.CheckFileContent
Name will be: Check File Content Data Source

image Now change to the Member Modules tab and click on Add…

Look for the System.Scheduler, select it and give it an ID like: Scheduler
Remember, the ID we choose here needs only to be unique within the Member Modules scope, it doesn’t need to be unique for the whole MP. Therefore you can also choose the ID Scheduler for another data source in this MP.

Hit OK.
image We will configure this module that all the configuration will be passed on from its consumer. You can use the fly-out button and select Promote… to fill in the appropriate $Config values.
image Now let’s add another module, our Check File Content Probe we created in the first part. We ID it Probe
image The configuration of our Check File Content probe is also straight forward. All parameters (except the last one) will be populated by its consumer. The last parameter will be set to false. We know that the module in this data source will never be used with the additional information we provide when we execute it as task.
image Before we move on to the next tab, we need to define the order our modules are executed:
The Scheduler is our first module, which is basically triggering the workflow. So, in the Next Module column we set Probe as our next module to be executed.
the Probe module will provide the Module Output
image In the Configuration Schema tab we need to verify (again) that all the data types are set accordingly. The authoring console tends to always use String as type, so we need to correct them to set Interval to Integer and Debug to Boolean.

Also keep in mind that optional parameters will not be shown here by default. In case you have modules with optional parameters you need to add them explicitly. It is also important the the order of the parameters are correct!

In our case we do not have and use any optional parameters, so nothing to do for us here. But if we would have defined an optional boolean parameter named “Bob” in our CheckFileContent probe after the ErrorText and we want to use it, we must add this parameter manually to this list right after the ErrorText parameter and set it to boolean. The arrows next to the list allows to reorder the list.
image In the Overridable Parameters tab we add all our parameters to the list.

As mentioned in Part 1, if you want to seal you MP and want others to use this data source in their own MP you need to mark this data source Public in the Options tab.

That’s it for part 2. The next step will be creating the monitor type.

cheers,
Stefan Koell
http://www.code4ward.net

By Stefan Koell on Friday, October 23, 2009 9:48:12 AM

This is a step-by-step guide in multiple parts:

Part 1 will cover the Probe Actions Module Types
Part 2 will be about creating a Data Source
Part 3 will cover creating a Monitor Type
Part 4 will cover the Unit Monitor itself

As always be careful with the samples provided here. Always use a test environment first to try those examples!

Will only work with OpsMgr 2007 R2 !

Part 1: Probe Action Modules

In the following example we will use a PowerShell script to check for a string in a file. If the string is found we alter the health state to “Unhealthy”, otherwise the health state is “Healthy”.

param([string]$file, [string]$errorText, $debug, $executedAsTask)
 
if ($debug -ne "true"){$debug = [bool]$false}else{$debug = [bool]$true}
if ($executedAsTask -ne "true"){$executedAsTask = [bool]$false}else{$executedAsTask = [bool]$true}
 
$Script:API             = new-object -comObject "MOM.ScriptAPI"
$Script:Bag             = $Script:API.CreatePropertyBag()
$Script:LOG_ERROR       = 1
$Script:LOG_WARNING     = 2
$Script:LOG_INFORMATION = 4
$Script:ScriptName      = "code4ward.Sample.PowerShellMonitor.ps1"
$Script:Arguments       = "Received Arguments:`rFile = $file`rErrorText = $errorText`rDebug = $debug`rExecutedAsTask = $executedAsTask"
 
function Write-DebugInfo([string] $msg)
{
    if ($debug) 
    {
        $Script:API.LogScriptEvent("$ScriptName",100,$Script:LOG_INFORMATION,"`r$Arguments`r`r$msg")
    }
}
function Write-ErrorInfo([string] $msg)
{
    $Script:API.LogScriptEvent("$ScriptName",500,$Script:LOG_ERROR,"`r$Arguments`r`r$msg")
}
 
Write-DebugInfo "Script started..."
 
if ($file.Trim().Length -gt 0)
{
    $FileExists = (Test-Path $file)
}
else
{
    Write-ErrorInfo "No file was specified."
    return
}
        
if (-not $FileExists) 
{
    Write-ErrorInfo = "File '$file' not found."
    return
}
    
$File = Get-Item $file
[string]$FileContent = @()
foreach ($Line in Get-Content $File)
{
    $FileContent += "`r$Line"
}
    
 
if ($errorText.Trim().Length -gt 0)
{
    if ($FileContent.Contains($errorText))
    {
       $Script:Bag.AddValue("Status","ERROR")
       $Script:Bag.AddValue("MessageText","Error text '$errorText' found in file '$file'.")
    }
    else
    {
       $Script:Bag.AddValue("Status","OK")
       $Script:Bag.AddValue("MessageText","Error text '$errorText' not found in file '$file'.")
    }
    if ($executedAsTask)
    {
        $Script:Bag.AddValue("AdditionalStuff","goes here")
    }
}
else
{
    Write-ErrorInfo "No error text specified"
}
 
#$Script:API.Return($Bag)
$Script:Bag
 
Write-DebugInfo "Script ended..."

Note that at the very end of the script we just write $Script:Bag and NOT $Script:API.Return($Bag) as you might expect. However, I left this line commented in the script for testing because only the return command will generate the property bag data in the console which is useful for testing and debugging but the Module we are using soon will not work with the Return method.

How will this script be used?

We create one module holding the script and it’s configuration. This module will be used for our data source (scheduled) and the monitor type for “On Demand Detection” (enabling the recalculate health functionality). We create a second module wrapped around our first module with a different configuration to use the same script as a diagnostic or agent task. The reason for the second module is to illustrate the concept of wrapping modules providing the same functionality but with different configuration. In our case, the overridable parameters and the configurable parameters will be different in the second module.

The documentation on Technet is getting better and better. For a module reference visit: http://technet.microsoft.com/en-us/library/dd391800.aspx

What are the parameters for?

File: specify the full path to the file to check for
ErrorText: the string we are looking for and generate an alert
Debug: can be “true” or “false”. If true additional information will be published to the event log.
ExecutedAsTask: in this example only used to illustrate that we can use the same script for different modules/tasks. In a real world script you may use this to provide an extended property bag to pass more information to your operator.

There’s no error handling in this script, therefore it is far from production quality and only used to show the concepts of a PowerShell 2-state-script-monitor!

Creating the Modules

image

Open up the “Authoring Console” (needs to be installed separately and can be found on the SCOM R2 media) and let’s create a new management pack using File->New…

 

The MP ID is: code4ward.Sample.PowerShellMonitor

The Display Name is: code4ward Sample PowerShell Monitor

Now let’s navigate to the Type Library space, and select Type Library\Module Types\Probe Actions in the tree view.

image Right-click in the Probe Actions and select New->Composite Probe Action.

Type in an ID: code4ward.Sample.PowerShellMonitor.Probe.CheckFileContent
Type in a Name: Check File Content
image Change to the Member Modules tab and click on Add…

Now look for the PowerShellPropertyBagProbe module, select it and specify an ID for the module like Probe

Click OK. Back in the Member Modules tab click on Edit and again in the configuration window click again on Edit and choose an external editor (like Notepad) if not already chosen.

  Replace the XML stuff inside the <Configuration> element with the code below and not that the script body needs to be filled as well with the script at the beginning of this post.

<ScriptName>code4ward.Sample.PowerShellMonitor.ps1</ScriptName>
<ScriptBody>
  <![CDATA[
  SCRIPTBODY GOES HERE !
  ]]>
</ScriptBody>
<Parameters>
  <Parameter>
    <Name>File</Name>
    <Value>$Config/File$</Value>
  </Parameter>
  <Parameter>
    <Name>ErrorText</Name>
    <Value>$Config/ErrorText$</Value>
  </Parameter>
  <Parameter>
    <Name>Debug</Name>
    <Value>$Config/Debug$</Value>
  </Parameter>
  <Parameter>
    <Name>ExecutedAsTask</Name>
    <Value>$Config/ExecutedAsTask$</Value>
  </Parameter>
</Parameters>
<TimeoutSeconds>300</TimeoutSeconds>

After you closed the configuration dialog, select Module Output in the drop down list in the Next Module column.
image Now let’s switch to the Configuration Schema tab. Use the Add… button on the bottom of the dialog to create the parameters as shown in the screenshot. Watch out for the type drop down list and ensure that the type is correct for each parameter.
image Now we move on to the Overridable Parameters tab and add all of our parameters to the list. When you click the Add… button, a menu shows you all available parameters we defined in the previous tab. Just select one after the other and to keep it simple we call them the same as defined in the configuration. (The name you specify here will appear in the override dialog.)

Also, always verify the data type in the Configuration Element column.
image In the Data Types tab we need to check the radio button This module requires input data.
image Last but not least, we change the Accessibility proerty to Public. This is optional and may be useful when you seal your MP and provide these modules to use in other MPs.

Now let’s hit OK and see if we can successfully close this dialog. If you get an exception, you may have a typo or a wrong order of parameters, which is also very important.
image As mentioned before we will create a module based on the just created one to provide a different configuration.
Again, right-click on the Probe Actions pane and select New->Composite Probe Action…

This one gets the ID: code4ward.Sample.PowerShellMonitor.Probe.CheckFileContentAsTask
The name is: Check File Content as Task
image In the Member Modules tab we click on Add… again but this time we choose the module we just created.
image Now we will see the configuration we just created in the previous module. Except for the ExecutedAsTask configuration we use the little arrow button on the right side of each value and hit promote.

This means File, ErrorText and Debug will be passed to the module using our configuration (where we actually use this module) and the ExecutedAsTask will be set to true.

Click on OK and don’t forget to set the Module Output in the Next Module column.
image The Configuration Schema tab should know all your config settings for this module but always check for the right data type! In our case you need to explicitly set Debug to Boolean. I guess this is a bug in the Authoring Console because for some types this works automatically for some others not. Maybe future releases of the Authoring Console will be more reliable in this regard.
image Next tab Overridable Parameters. In this derived module we only allow to override the Debug value.

Because the task will be available in the diagnostics of the monitor, we already know which File and what ErrorText we want to check.
image As in the previous module, we need to set the Input Data right in the Data Types tab.

That’s it for now. The next step will be creating the Data Source.

cheers,
Stefan Koell
http://www.code4ward.net

By Stefan Koell on Tuesday, October 13, 2009 5:15:34 PM

 

This is a step-by-step guide on how to create a PowerShell tasks using the authoring console. This will only work for OpsMgr R2 installations!

I am not exactly a certified-OpsMgr-under-the-hood-specialist – I had the honor to be part of a workshop where Brian Wren (http://blogs.technet.com/brianwren/) revealed some OpsMgr secrets. So this post is for one part storing my gained knowledge in the Interwebz so that Google can index it and I can find it again, another part of course is to give something back to the community. So if you have suggestions for improvements or any questions, go ahead and comment on this post.

For this guide we create a task which allows us to set a registry value on a remote machine.

Why do we want to do this? First of all, it is a great example to show some concepts behind Module Types. Secondly, we use a task like this to set some custom computer attributes. We use some additional computer attributes to mark a computers productive, test, etc. We do that by looking for a registry value and discover these attributes (maybe a topic for another guide). To easily move a computer from test to production we just need to set a registry value.

Here a short overview of this blog post:

  1. We need a PowerShell script: SetRegistryValue.ps1
  2. We will create a generic module type allowing us to set any registry value
  3. We will create a wrapper for this module type to set a registry value in a specific key using our generic module type
  4. We will create an agent task consuming this module and provide two overridable parameters. One for debugging, and one providing the value for the registry

1. The Script:


# Script Name:  SetRegistryValue.ps1
# Parameter 1:  path  (e.g. "HKLM:\Software\Somekey\Somesubkey")
# Parameter 2:  name  (e.g. "SomeValueName")
# Parameter 3:  value (e.g. "SomeValue")
# Parameter 4:  type (e.g. "String", "Binary", "DWord", "MultString", "ExpandString")
# Parameter 5:  debug (e.g. "false", "true")
# -----------------------------------------------------------------------------
# Parameters
param([string]$path,[string]$name,[string]$value,[string]$type,[string]$debug)

if ($debug -ne "true"){$debug = [bool]$false}else{$debug = [bool]$true}
$Script:API = new-object -comObject "MOM.ScriptAPI"
$Script:LOG_ERROR       = 1
$Script:LOG_WARNING     = 2
$Script:LOG_INFORMATION = 4
$Script:ScriptName = "SetRegistryValue.ps1"
$Script:Arguments  = "Received Arguments: `rPath='$path' `rName='$name' `rValue='$value' `rDebug='$debug'"

function Write-DebugInfo
{
    param ([string] $msg)
    if ($debug) 
    {
        $API.LogScriptEvent("$ScriptName",100,$Script:LOG_INFORMATION,"`r$Arguments`r`r$msg")
    }
}
function Write-ErrorInfo
{
    param ([string] $msg)
    $API.LogScriptEvent("$ScriptName",500,$Script:LOG_ERROR,"`r$Arguments`r`r$msg")
}

Write-DebugInfo("Script started.")

# check if registry key exists
if (Test-Path $path)
{
    Write-DebugInfo("Path $path found in registry.") 
}
else
{
    Write-DebugInfo("Path $path doesn't exist. Creating registry keys...")
    New-Item -Path $path -force | Out-Null
}
New-ItemProperty -Path $path -name $name -value $value -Type $type -force | Out-Null
Write-DebugInfo("Registry value $value of type $type in $path $name created/updated.")
Write-Host "Registry value $value of type $type in $path $name created/updated."
Write-DebugInfo("Script ended.")

 

This script will create/set a registry value of a specific type. Disclaimer: Use this at your own risk. Always use a test environment! Writing/Overwriting registry values can harm your system. You really need to know what you are doing! There’s also no error handling in this script and it’s far from production quality! Works on my machine!

2. Generic Module Type to Set a Registry Value

imageNow let’s start up the authoring console and create a new empty management pack using the “File->New…” menu command:

 

In my example the MP ID is “code4ward.Sample”

The friendly name is “code4ward Sample”

Of course you can use your own IDs and names.

 

 

 

image Now let’s navigate to the “Type Library” space and select “Probe Actions” in the “Module Types”:

Right-click in the Probe Actions pane and select “New->Composite Probe Action…” command.

Set the ID to “code4ward.Sample.Action.SetRegistryValue”. Click OK; the property pages for this new module type will open.

Name it “Set Registry Value”

 

Here we are going to create a very generic module of our own, capable of settings registry values on a target machine.

 

 

 

image

Change to the “Member Modules” tab and click on “Add…”.

Look for: “PowerShellProbe”, select the “Microsoft.Windows.PowerShellProbe” and specify a Module ID – in my case the ID is “Script”. Click OK.

 

Some of the modules are documented on Technet already (more to come soon): http://technet.microsoft.com/en-us/library/dd789057.aspx

 

Now the configuration window for the PowerShellProbe opens up. Click on “Edit…” and if not already configured, choose a text editor (notepad.exe) to open the configuration in an external editor.

 

 

image

Now we need to fill in the configuration of this PowerShellModule:

Type a script name “SetRegistryValue.ps1” in the ScriptName tags, copy the script above into the ScriptBody tag, be sure to wrap a “” tag around it (without the quotes), set the TimeoutSeconds to 300 or something.

Note that there’s no Parameters section in the configuration XML when we open it. We need to create our own. Also note that the script on top of this post allows named parameters. For each Parameter in your script create a parameter element containing the Name element which must correspond to the actual name of the parameter (this is not case-sensitive) and a value element like “$Config/SomeValue$. The name of the value element is important when we wrap another module type around it. This basically says, the value will be submitted to the module from its consumer (task or other module, etc.).

It is also very important that the Parameters element is right after the ScriptBody element (see screenshot!).

 

Before we continue, we also need to select “Module Output” in the “Next Module” column.

 

image

Now let’s continue to the “Configuration Schema” tab.

Just add all the parameters of the script using the the “Add…” button in the “Simple Configuration Schema” section.

Verify, that every parameter has the appropriate type selected (in our case Debug must be a boolean, all other parameters are strings (default)).

 

 

 

 

 

 

 

 

 

image

Next stop: Overridable Parameters

Use the “Add… “ button at the bottom to enable overrides for all parameters (I used the same names as the parameters to avoid confusion).

 

 

 

 

 

 

 

image

 

One last step before we close this beast. We need to select the radio button “This module requires input data”.

Additionally you may consider to make your module public (in the Options tab, Accessibility) if you want to allow others to consume your module (your MP needs to be sealed then).

 

 

 

 

 

 

Now we created a very generic module allowing us to set any registry values. Now let’s pretend we need to set in HKLM:\Software\code4ward the value “Environment” to some value. Let’s wrap another module type around the one we just created:

3. The Wrapper Module Type

As explained above, right-click and select “New->Composite Probe Action…” and type in an ID like “code4ward.Sample.SetRegistryEnvironment” and a name like “Set Registry Environment”.

In the “Member Modules” tab we add our previously created module and provide an ID like “Probe”. The configuration of our module looks like this:

image

 

Next to the value and debug field you can use the “Promote” menu item to automatically fill in the $Config/…$

Using this configuration, we tell our new module to consume our previously created module where the Path, Name and Type parameter is pre-set and the value and debug parameter will be set by it’s consumer (later on by the task or by providing an override).

 

Also be sure to select “Module Output” in the “Next Module” column.

 

 

 

 

image

Now we only need to provide two configuration values (all the others are pre-set). Be sure that the Debug type is Boolean.

 

 

 

 

 

 

 

 

image

 

Also create two overridable parameters, only this time we call the $Config/Value$ parameter “Environment”. This is the name presented to you by the override dialog!

In the next tab “Data Types” we also need to check “This module requires input data” again.

Click on “OK” and save your MP.

 

 

 

 

 

 

So far we are ready with our modules.

4. Now let’s put all together to create a Task

Let’s switch to the “Health Model” space and select “Tasks\Agent Tasks”. Right-click on the Agent Task panel and select “New->Custom Task”. Provide an ID like "code4ward.Sample.Task.SetEnvironment” and a display name “Set Environment”. As target we select “Microsoft.Windows.Computer” – this way we can use the task in the computers state view.

image

In the “Configuration” tab, click on the “Browse for a type” link and select the “code4ward.Sample.SetRegistryEnvironment” module type we created before.

 

 

 

 

 

image

After we selected the module type, we can pre-set the parameters. In our case we leave the value blank and should be specified using an override, the debug parameter is set to false by default and can be set to true for debugging using the override parameters dialog.

 

 

 

 

 

 

 

 

Here the result:

image

 

 

You can download this MP here: code4ward.Sample Management Pack

I am also thinking of posting a step-by-step guide like this one on how to set up a 2 state monitor using a powershell script with the “Recalculate Health” ability. If you’re interested in such a guide, please let me know and give me some feedback?

cheers,

Stefan

http://www.code4ward.net

By Stefan Koell on Tuesday, October 13, 2009 10:19:56 AM

I’m happy to announce a new LogSmith release with one new “killer feature”: When you click on an event, you’ll see the event parameters in the details pane.

image

This should speed up authoring rules where you want to check for specific event parameters.

For a complete feature list, go here: http://www.code4ward.net/main/LogSmith/Features.aspx

LogSmith is available for free (Donations are welcome and appreciated), use at your own risk, you can download it here: http://www.code4ward.net/main/LogSmith/Download.aspx

By Stefan Koell on Sunday, July 19, 2009 5:21:52 PM

 

Yesterday was my first (of 30 days) in Seattle/Redmond. I will be in Washington for a month attending some business so there will be some latency in responding to emails and forum posts.

During the weeks we have a lot of work but the weekends are reserved for fun, recreation, theaters,shopping and some hiking. So far the weather is just great here... hopefully it stays that way...

By Stefan Koell on Saturday, June 27, 2009 1:10:00 PM

Managing Windows

  1. [Win+M] – Minimize all open windows
  2. [Win+Shift+M] – Undo all window minimization
  3. [Win+D] :- Toggle showing the desktop
  4. [Windows+Up] – Maximize window
  5. [Windows+Down] – Minimize windows / Restore
  6. [Windows+Left] – Dock window to the left side
  7. [Windows+Right] – Dock window to the right side
  8. [Windows+Shift Up] – Maximize vertical size of window
  9. [Windows+Shift Down] – Restore vertical size
  10. [Windows+Shift Left] – Move window to left monitor
  11. [Windows+Shift Right] – Move window to right monitor
  12. [Win+Spacebar] – Aero desktop peek
  13. [Win+Home] – minimize/maximize all inactive windows
  14. [Alt+F4] - Close the active window
  15. [Alt+Tab] - Switch to previous active window
  16. [Alt+Esc] – Cycle through all open windows
  17. [Win+Tab]- Flip 3D
  18. [Ctrl+Win+Tab]- Persistent Flip 3D

Taskbar

  1. [Win+Any number (1, 2, 3, .., 0)] – open the corresponding taskbar pinned program
  2. [Ctrl+Click a pinned taskbar icon] – cycle through the program’s open windows
  3. [Shift+Click a pinned taskbar icon] -run a new instance of the program
  4. [Ctrl+Shift+Click a pinned taskbar icon] – run a new instance of the program as administrator
  5. [Shift+Right-click on icon] – Show window menu (Restore, Minimize, Move etc)
  6. [Shift+Right-click on grouped icon] - Show window menu (Restore All, Minimize All, Move All etc)
  7. [Win+T] – Cycle through applications on taskbar (showing its live preview)
  8. [Win+Shift+T] – As above, but in reverse order
  9. [Win+R] - Opens Run dialog box

General

  1. [Win+P] – show presentation mode projector options
  2. [Win+G] – show desktop gadgets
  3. [Win+L] – Lock computer
  4. [Win+X] - Mobility Center
  5. [Win++] - Zoom in
  6. [Win+-] – Zoom out
  7. [Win+=] – Magnifier

Windows Explorer

  1. [Alt+P] - Show/hide Preview Pane
  2. [Alt+Up] - Go up one level
  3. [Alt+Let/Right] - Back/forward
By Stefan Koell on Monday, June 22, 2009 1:13:57 PM

It’s actually pretty easy:

msiexec /a filepath to MSI file /qb TARGETDIR=filepath to target folder

By Stefan Koell on Sunday, June 21, 2009 5:53:13 PM

I wasn’t able to blog much lately. Mostly because of piled up work but also family business is keeping me busy.

However, today Version 1.6.7 was released. This update is free for all users with a Royal TS 1.6 license and can be downloaded from here: http://www.code4ward.net/main/RoyalTS/Download.aspx

It’s been a while since the last release and most of the changes in this release are bug fixes. The last refactoring caused some very weird bugs which were hard to find and harder to fix. Here some of my lessons learned:

The tree view and the web browser control from Windows.Forms namespace are buggy as hell and one of the weirdest issues with these controls are focusing issues. Of course there are workarounds for most of the issues but since the dashboard has a web browser control (for displaying the notes) the interaction between the web browser control and the tree view control are causing headaches as hell.

For once, the tree view has some serious focus issues. Trying to move the focus away from the tree view after the selection changed causes the tree view to steal back the focus after the event chain was processed. There are some workarounds for this and I think during all my Royal TS releases I tried every single one available.

The web browser control has similar issues. When you set the contents for the web browser control using the DocumentText property you always get this annoying click sound. As a workaround you can set the contents using the Document.Write() method – which is not causing the click sound. The side effect however is, when you set it this way, the control starts to steal the focus back when it got the focus once (e.g. if you click inside the control or on a link). Now with all the focus stealing there’s no way to predict which control will get the focus after all. 

So I was forced to use a 3rd party tree view control, which unfortunately will blow up the footprint of the installer package a bit. But the good news is, that it’s nicer, not so buggy – at least not with all the ordinary stuff, has plenty of options and provides a very easy approach to implement drag & drop.

imageSo now you can use drag & drop to reorder folders or move connections within or between folders, including a nice drop marker as shown in the screen shot.

Holding down the CTRL key while dragging will duplicate a connection instead of moving it. Watch the icon with the “plus” sign.

You can also drag multiple connections from the list to the tree view as well!

So while I was at it and touched the tree view code, I took the opportunity to make sure that the selected item stays highlighted even when the focus is inside a session. So everybody should be happy now to see very clear which session is active. Another thing I did, was optimizing the code to build the tree and the list. It’s now very fast, even when you have several hundred connections.

Replacing the tree view resolved some of my headaches but, the web browser control still wants to steal the focus. So back to the start. I need to set the content using the DocumentText property, at least I get rid of the focus stealing issue. But how to disable the click sound. Fortunately when we deal with IE7 and IE8 there’s a Win32 API call to disable that very annoying “feature”: CoInternetSetFeatureEnabled().

I haven’t tested it, but my guess is that users with IE6 will have the click sound when changing the selection in the navigation tree. If you get annoyed and want to commit suicide, go to the system sounds and disable the click noise (which will be effective on all IE browsers on your system) or upgrade to IE7 or IE8.

imageWhat else changed? In order to prepare everything for the new document model I changed some terms and menu item names. I also tried to use terms and keyboard shortcuts already well known from the windows shell.

Add and Remove changes to Insert and Delete (Del as the keyboard shortcut). In future Insert will have a sub menu where you can choose Folder, Credential, Task, Remote Desktop Connection, Web Connection, etc.

Edit was changed to Properties (Alt+Enter as keyboard shortcut). I always felt that “Edit->Edit” just doesn’t sound right. “Edit->Properties” is much nicer. I know these are some minor cosmetic changes but as many of you may already know the love and passion to details is driving me.

I should also mention that you can also hit F2 when you just want to change the name of a tree or list item!

imageSpeaking of detail: I already use the Windows 7 / Windows 2008 R2 Remote Desktop Service icon to identify a remote desktop connection in the tree (as usual as black for inactive and green for active connections). Besides that I set the greenish icon as window icon for connections in external window mode. This way you can easily distinguish the main window of Royal TS and all the external windows from Royal TS when you use Alt+Tab for example.

Finally I want to thank all beta users for their support in identifying bugs and for constructive discussion on features. I hope you enjoy the new build.

By Stefan Koell on Friday, March 13, 2009 12:30:03 PM
By Stefan Koell on Sunday, March 08, 2009 7:32:18 PM

I’ve still not shown all new features and improvements for 1.6.5 but starting today I offer to download the beta version (1.6.5.32156). If you are interested to test drive the beta version, create an account on this web site (if you haven’t already) and click on this link: http://www.code4ward.net/main/Default.aspx?rsvp=RTSBETA

After that you should have access to the beta forums. There you’ll find all the instructions…

Now let’s do some screenshot bonanza:

image image image image image image

 

I think the pictures are saying more than thousand words…

cheers

Stefan