| Today bought me one of those valuable lessons in life. Actually it's an old lesson that was learned some time ago, but then forgotten or ignored.
Earlier I was fixing a problem for a client whose company is a couple of hundred miles away. The problem was a DNS lookup issue and was solved pretty quickly. Whilst I was using RDP to look at the problem I decided that the IPV6 configuration was both unnecessary and possibly causing another relatively minor issue, therefore with the click of a mouse I un-ticked the IPV6 checkbox on the network configuration and clicked OK. This was where my day took a nose dive. The RDP session froze, even though I was connected using IPV4, and firing of pings to the IPV4 address showed that the server was no longer on the network. The local support guy confirmed that all 80 people in the office had all just jumped out of their seats and were waving big sticks. Whoops……
When I asked the local support guy if the IPV6 was being used, he pretty much said that it wasn't. He said that he had seen IPV6 being used when DNS queries looked up the server, but nothing else. Two minutes passed whilst I mulled over what could possibly be going wrong. At this point it has also become obvious that the KVM switch connected to the server has stopped working as well (an unconnected issue). Just as I was about to give up hope that a simple solution could be found, the pings started to come back from the IPV4 address. Quickly I reconnected my RDP session and in only a few seconds I had ascertained that all was well again. Local support confirms that the users were back working, and we all returned to DEFCON 5. Ah, easily explained I thought, taking out IPV6 must have force the network card to reset completely. Problem solved.
Ah, but SBS hasn't finished with you yet. Many hours pass and Friday night is about to begin. Now we get a message that mobile phone users are not getting their mail synchronised to their mobile devices. With little enthusiasm, I used RDP to reconnect to the server. "This has nothing to do with my changes." I was thinking, "Nothing at all…"
A closer look at the event logs showed a series of Active Directory connection failures being reported from Exchange 2007. More compelling evidence came from the fact that these events started just a few minutes after the IPV6 change. How about a quick restart of the affected services I thought. First the Exchange Mail Transport service as it has the most vocal errors in the event log. First it stops, then it starts, and then it stops. Arse! The event log tells us that the service did not start correctly because it cannot access its configuration data from Active Directory, even though SBS is always a domain controller (the only domain controller). Okay, time to pull out the big guns. Get the users out; we're doing a full reboot. We're going to DEFCON 3.
10 minutes pass, the server finally powers off and restarts…
20 minutes passes, the pings have been coming back from the server for several minutes, but RDP isn't yet working. No need to panic yet, eh?
30 minutes pass, still no RDP access. The local support reports that the server is stuck "Applying computer settings". I can attach to the event log of the machine remotely, but the news isn't good. All the services are failing to start or hanging. All have reported problems accessing Active Directory. The decision has already been made that when it finally loads, we're going to put IPV6 back. We're now at DEFCON 2.
50 minutes have passed and the server remains at the "Applying computer settings" screen. Crap! It's not coming back is it? DEFCON 1!!!!!
A quick prayer is offered to the great Google in the cloud. Please Mr Google, don't make me drive 400 miles this weekend to have to rebuild a server. The great Google quickly found others who had fallen into the trap. The only solution was to get the server into safe mode with networking and re-enable IPV6. Local support guy duly hit the power button and booted into safe mode. Another reboot later and the server came back to life. All services returned to normal and Exchange began to work. Another 20 minutes of checks finally allowed a return to DEFCON 5.
As I said, there is a lesson here. It may seem that the lesson is "Don't disable IPV6 on an SBS server", but I think the lesson is older than that. Many years ago, following a similar disaster, I made a pact with myself never to use SBS server unless my very life depended upon it, and somewhere along the way that lesson was forgotten. You may think that I'm writing this blog to help others. You are wrong, there are plenty of other useful articles out there that cover this problem. It is to serve as a reminder to me that we should never forget the lessons of history else we are doomed to repeat them.
Note to self: Leave that SBS rubbish alone once and for all. You'll only end up getting burned. Stick to real servers only!
Finally, all the characters of this story went off into the sunset where they all lived happily ever after…. |
| I've had a couple of instances recently of mail refusing to send from the SMTP Send Connectors on my Edge Transport servers to domains which use the popular MessageLabs spam filtering service. Now, on the first couple of occasions I put this down to a technical fault and just found another way to get the message through. Today, it finally interfered with delivering something I actually needed to be delivered and I had to bring skills to bear on this tricky number.
Firstly, I used NSLOOKUP from the Edge Transport to identify the MX Records for the destination domain. For those of you that don't know how to do this, open and command prompt and type this:-
NSLOOKUP
SET TYPE=MX
TheDomainName.com (Obvious use the correct domain name here.)
You'll get back something like this:
C:\Users\PaulPrior>nslookup
Default Server: strontium.x9000.com
Address: 192.168.129.10
> set type=mx
> oscar-associates.com
Server: strontium.x9000.com
Address: 192.168.129.10
Non-authoritative answer:
oscar-associates.com MX preference = 10, mail exchanger = cluster8.eu.message
labs.com
oscar-associates.com MX preference = 20, mail exchanger = cluster8a.eu.messag
elabs.com
cluster8.eu.messagelabs.com internet address = 85.158.140.179
cluster8.eu.messagelabs.com internet address = 85.158.140.195
cluster8.eu.messagelabs.com internet address = 85.158.140.211
cluster8.eu.messagelabs.com internet address = 194.106.221.19
cluster8.eu.messagelabs.com internet address = 85.158.138.131
cluster8.eu.messagelabs.com internet address = 85.158.138.147
cluster8.eu.messagelabs.com internet address = 85.158.138.179
cluster8.eu.messagelabs.com internet address = 85.158.139.19
cluster8.eu.messagelabs.com internet address = 85.158.139.35
cluster8.eu.messagelabs.com internet address = 85.158.139.163
cluster8.eu.messagelabs.com internet address = 85.158.139.179
cluster8.eu.messagelabs.com internet address = 85.158.139.211 |
Obviously, you don't need to be an email genius to see that this company has two MX records; Cluster8.eu.messagelabs.com and Cluster8a.eu.messagelabs.com.
Being a super resilient SMTP gateway, they've got more DNS record for these addresses than you can shake a proverbial stick at.
Now, as every good engineer will tell you, never fix a problem that's already been fixed by someone else, so I got out the old Bing search engine and started looking for other people with the same problem. It didn't take long to find others, but the solution was a little trickier. Eventually I found a suggestion that we should turn on the ForceHELO setting on the SMTP send connector. Now as I have three Edge Transport servers, you can't do this from those boxes, you have to do it from a Hub Transport server and then wait for an Edge Syncronisation. So off I went to my Hub Transport and looked at the send connector details:-
It's the top connector of the two we are looking at here (Don't try this in the Management console, there's no GUI for it). As you can see the ForceHELO setting is set to false (i.e. It'll use EHLO by default).
now I used the following command to set this value to true:
set-SendConnector -Identity "edgesync - perimeter to internet" -ForceHELO $true
Obviously you should use the name of your own send connector. If like me you have Edge Transports instead of sending directly from the Hub, then you can use the Start-EdgeSynchronization cmdlet to force an immediate sync.
Straight away I started getting back relay messages as my queue of email attempts started flying away. Success!!!
However, this is a slightly botched solution as now HELO will be the default, and this can have some performance effects. For example, you can no longer use the ESMTP extension keyword SIZE to query the server for the maximum message size that will be accepted. Older clients and servers may try to transfer excessively-sized messages that will be rejected by the destination server. It's not a big problem, but not perfect. Therefore, I would suggest creating a second send connector and configure the address space for specific domains that use MessageLabs, and configure that to use HELO. |
| I'm still finding people insisting on installing Exchange 2007, when Exchange 2010 is now many months past RTM. What are you doing? Exchange 2010 in a much better product and much easier to implement, especially if you need to install geographically disperse clusters across multiple datacentre clusters.
Also, there are still companies out there insisting on using a SAN to implement Exchange. Why don't you just take your money out into the back garden and set fire to it? Work out how much a gigabyte of useful storage costs on a SAN (Taking into account mirrored backup space, etc) and multiply it by you're expected maximum database size in five years time. Ouch!!!! I bought a server last year with 14TB of space, a bucket load of RAM and 8 processing cores for less than £5000. Now, forget your crazy SAN, you don't need it and can't afford it!!!
I've even had this week had some company looking to roll out Vista instead of Windows 7. Why not install DOS v6.22 instead??? |
| A couple of days ago I was uploading my 3000+ photos into another SharePoint 2010 instance. I had already moved almost all of the core corporate documents to it, and half way through the picture import I started to get error messages for every photo import. A look at the event logs on the server revealed that the 4GB limit of the SQL-Express that ships with SharePoint 2010 had been reached and breached. Now everything was broken. I couldn't delete the photographs either. I was quickly looking at rebuilding the server and try not to make the same mistake again when it occurred to me that it should be possible up upgrade to SQL 2008 R2, and that with a bit of luck, SharePoint would recover because the database name, instance name, tables, and such like would remain in the same path. Since I had nothing to lose I mounted the SQL ISO file and stated the install. Ten minutes later the install was completed and following a reboot we were back in action. Happy days!!! |
| I've only had this blog system running for a couple of weeks, but it has already begun to be successful enough that it needed to move from its temporary virtual machine at the end of a home broadband connection to the x9000.com Dedicated server that is currently in a Data Centre in Cheltenham where it gets a full 100Mb/s connection to the internet. Ideally I would have built it on that box to start with, but when I started it was just a bit of a training exercise and it didn't seem appropriate to install in straight onto a live system that manages several other key company services.
Anyway, that's all water under the bridge, and one way or another, the data from the original test server needed migration. Now, anyone that knows me can tell you that I'm not a SharePoint expert in the slightest bit, which is the main reason I created this SharePoint site in the first place.
So, what we're the options:-
Backup the Blog Web Application using the Central Administration site, copy this backup to the new server and restore it there.
- This was the obvious solution and seemed relatively easy with the least amount of work.
- Unfortunately this plan failed when it came to the restore. It may have been solvable given enough expert knowledge, but that wasn't available. The log file generated by the restore had scores of errors, and I concluded that the main issue was likely to be as a result of the complexity of moving from a domain member server to a standalone server. This meant that the permissions groups where no longer valid. I couldn't be sure this was the source of the problems, but I wasn't prepared to put any more effort at it.
Create a new Blog site on the new server and make the same changes on this server as the original server and then create new blog posts and copy the text from one site to another.
- This was by real plan all along, but it wasn't going to be a real learning exercise.
- Really, the main blocker on this idea was how boring it was going to be to implement. I could always come back to this if I really have to, but I thought I should give another plan a go first before defaulting to the most basic plan.
A bit by bit export of the lists and WebParts from one server to another.
- Okay, this wasn't actually an option when I started because I didn't even know you could do this. However, in my background research I stumbled across a couple of article than gave me a bit of a steer in this direction.
- There's only a few type of list in the Blog template, including "Posts", "Comments", "Links", "Photos", etc.
- Anyway, enough of the background. Given that this was the system I eventually used, let's get a few details down on how to do it.
Step 1; Install the SharePoint software onto the new server. Install it with template you require (In our case the Blog template).
Step 2; Modify the Site Theme, Title and Description in the Site Actions/Site Settings Menu
Step 3; On the source server, open the Central Administration Site and Click on the Backup And Restore Link on the left hand side. From here you can see the appropriate link title Export a site or list (Shown below).
From here you select the appropriate Site Collection, Site and List from the Orange selection boxes on the right hand side. For the filename choose and location you can easily get to and put a .cmp suffix on the end of the file name. When you are ready, export the list and copy this to the new server.
Once the file is on the new server you need to open the SharePoint 2010 Management Shell, which is the PowerShell console with the SharePoint 2010 extensions installed. From here you can import you list by using the following command:-
Import-SPWeb http://Blogs.x9000.com –Path C:\_Data\Links.cmp –UpdateVersions Overwrite - You should note that the help documentation for this command is slightly wrong and there is no hyphen before the Overwrite parameter.
After a few seconds you list will appear in the new site. In this case we exported the Posts, but you can do this for any List including and comments, Links, etc.
Step 4; Export any customised Web Parts that you have from the old site by clicking on the drop down arrow above the Web Part and choosing Export.
Transfer the .DWP file to the new server and Choose Site Actions/Edit Page. Click on an Add a Web Part link. In the top Menu you can see a small link allowing you to upload a Web Part.
Give it the path to the exported Web Part and it gets imported. It does not actually place it on your page, but this can be done by selecting it out of the list. You may find you have a duplicated entry such as "About this blog (2)" because the original is still on the page, but the original can just be deleted.
Now the job is almost done. There may just be tidying up to do, but the bulk of the work is done.
I did notice one issue. The Archives section which will show you article by month shows only the current month (May). Now some of my article where published in the last days of the previous month (April), but that did not show a link. My solution (or bodge) was just to open each article and change the publishing date to the 1st of May. Obviously if you have a backlog of such post going back several months you're probably going to have to find a better way.
Also, my Categories for each post where all wrong, it had just chosen then at random from the list. This is probably because the order of the Categories was not exactly what it was on the old Server. My solution once again was just to edit each article and update the selected Categories.
All done! Site moved to a new server and some more SharePoint knowledge added to the pile. |
| History of High Availability Design before Exchange 2010
Prior to the release of Exchange 2007, the high availability and disaster recovery features included with the Exchange Server product were quite limited. Previous versions of Exchange (Exchange 2003 and earlier) could take advantage of Microsoft Cluster Services (MSCS), but this only provided redundancy at the hardware level since the nodes shared the same storage subsystem. If the active cluster node suddenly became unavailable, the Exchange Virtual Server (EVS) and any relevant cluster resources would fail over to the passive node and the end users could then continue their work.
In order to achieve redundancy at the storage level, organizations were forced to invest in replication solutions provided by third-party software vendors and/or storage hardware vendors. Since solutions provided by third party are not supported by Microsoft and typically are quite expensive to implement, the Exchange Product group wanted to provide better high availability and disaster recovery features natively in the Exchange Server product.
Exchange 2007 gave us a whole sleeve of brand new high availability and disaster recovery features such as Local Continuous Replication (LCR), which targeted small organizations and Cluster Continuous Replication (CCR) which targeted medium and large organizations. Later on (with Exchange 2007 SP1) came Standby Continuous Replication (SCR), targeted at organizations of pretty much all sizes. All three features used a new asynchronous replication technology, which worked by shipping log files to a passive copy of a storage group and after inspection replaying these into this passive copy.
Although LCR provided redundancy at the storage level, the feature never really got much attention. The reason behind this was that since the storage group copies had to be stored on a volume local to the Mailbox server, it presented a single point of failure at the hardware level. CCR combined the new asynchronous replication technology introduced by Exchange 2007 with Windows Failover Clustering technology, thereby providing redundancy at the hardware level as well as at the storage level, providing a true high availability solution without any single point of failures.
CCR cluster nodes could be located in separate data centres in order to provide site-level redundancy, but since CCR was not developed with site resiliency in mind, there were too many complexities involved with a multi-site CCR cluster solution
With Exchange 2007 SP1 there came a feature called Standby Continuous Replication (SCR) which made it possible to ship log files to another Exchange 2007 Mailbox Server. Because SCR did not require Windows Failover Clustering, the log files could be shipped from both clustered and non-clustered Mailbox servers (the SCR source) to clustered and non-clustered mailbox servers (SCR target). SCR also introduced the idea of a lag in the replaying of log files of up to seven days, which made it possible to revert back to a copy of the database unaffected by any current issues affecting the active mailbox.
Exchange 2010
With Exchange 2010, we no longer have the concept of Local Continuous Replication (LCR), Single Copy Clusters (SCC), Cluster Continuous Replication (CCR) or Standby Continuous Replication (SCR). Microsoft has now introduced the Database Availability Group (DAG) act as the base component. This means that no matter if you are going to deploy a local or site-level highly available or disaster recoverable solution, you use a DAG. With Exchange 2010, the one and only method to protect mailbox databases is by using DAG.
The primary component in a DAG is a new component called Active Manager. Instead of the Exchange cluster resource DLL (exres.dll) and the associated cluster service resources that were required when clustering Exchange 2007 and previous versions of Exchange, Exchange 2010 now relies on the Active Manager to manage switchovers and failovers (Also called *overs) between mailbox servers part of a DAG. Active Manager runs on all Mailbox servers that are members of a database availability group (DAG). There are two Active Manager Roles: Primary Active Manager (PAM) and Standby Active Manager (SAM). PAM is the Active Manager in a DAG that decides which copies will be active and passive. PAM is responsible for getting topology change notifications and reacting to server failures. The DAG member that holds the PAM role is always the member that currently owns the cluster quorum resource (default cluster group). If the server that owns the cluster quorum resource fails, the PAM role automatically moves to a surviving server that takes ownership of the cluster quorum resource. In addition, if you need to take the server that hosts the cluster quorum resource offline for maintenance or an upgrade, you must first move the PAM to another server in the DAG. The PAM controls all movement of the active designations between a database's copies (only one copy can be active at any specified time, and that copy may be mounted or dismounted). The PAM also performs the functions of the SAM role on the local system (detecting local database and local Information Store failures).
The SAM provides information on which server hosts the active copy of a mailbox database to other components of Exchange that are running an Active Manager client component (for example, RPC Client Access service or Hub Transport server). The SAM detects failures of local databases and the local Information Store. It reacts to failures by asking the PAM to initiate a failover (if the database is replicated). A SAM doesn't determine the target of failover, nor does it update a database's location state in the PAM. It will access the active database copy location state to answer queries for the active copy of the database that it receives.
When a failure affecting the active database occurs, Active Manager uses several sets of selection criteria to determine which database copy should be activated. Active Manager attempts to locate a mailbox database copy that has a status of Healthy, DisconnectedAndHealthy, DisconnectedAndResynchronizing, or SeedingSource, and that meets all of the following criteria:
- It has a content index with a status of Healthy.
- It has a copy queue length less than 10 log files.
- It has a replay queue length of less than 50 log files.
If none of the database copies meet all of the preceding criteria, Active Manager tries to locate a database copy that meets the next set of criteria:
- It has a content index with a status of Crawling.
- It has a copy queue length less than 10 log files.
- It has a replay queue length of less than 50 log files.
If none of the database copies meet all of the preceding criteria, Active Manager tries to locate a database copy that meets the next set of criteria:
- It has a content index with a status of Healthy.
- It has a replay queue length of less than 50 log files.
If none of the database copies meet all of the preceding criteria, Active Manager tries to locate a database copy that meets the next set of criteria:
- It has a content index with a status of Crawling.
- It has a replay queue length of less than 50 log files.
If none of the database copies meet all of the preceding criteria, Active Manager tries to locate a database copy that meets the next set of criteria:
- It has a replay queue length of less than 50 log files.
If none of the database copies meet all of the preceding criteria, Active Manager tries to locate a database copy that meets the next set of criteria:
- It has a content index with a status of Healthy.
- It has a copy queue length less than 10 log files.
If none of the database copies meet all of the preceding criteria, Active Manager tries to locate a database copy that meets the next set of criteria:
- It has a content index with a status of Crawling; and
- It has a copy queue length that is less than 10 log files
If none of the database copies meet all of the preceding criteria, Active Manager tries to locate a database copy that meets the next set of criteria:
- It has a content index with a status of Healthy.
If none of the database copies meet all of the preceding criteria, Active Manager tries to locate a database copy that meets the next set of criteria:
- It has a content index with a status of Crawling.
If none of the database copies meet all of the preceding criteria, Active Manager tries to activate any database copy with a status of Healthy, DisconnectedAndHealthy, DisconnectedAndResynchronizing, or SeedingSource. If it can't find any database copies with this status, it isn't able to automatically activate a database copy.
In each of the preceding passes, if more than one database copy meets all of the preceding criteria, the configured value for ActivationPreference is consulted, and the database with the lowest value is activated and mounted.
Exchange 2010 supports up to 16 servers per DAG, theoretically allowing one copy of a database on each of the servers in the same DAG (i.e. One Active mailbox database and 15 Passive mailbox database copies). The maximum limit of mailbox databases per server is now 100 (up from 50 in Exchange 2007), although the maximum database size is not 2TB, so it is easily possible to just use one mailbox database. As a side note, this has taken the maximum mailbox data size for one DAG to be 16(Number of Servers) x 100(Maximum number of databases) x 2TB (Largest database size = 3200TB or 3.2 Petabytes.
Because of the improvement made with Exchange 2010 DAG, we will now experience much quicker switchovers and failovers between mailbox database copies. They will typically occur in less than 30 seconds, compared to several minutes with CCR in Exchange 2007. In addition, because Outlook MAPI clients now connect to the RPC Client Access service on the Client Access Servers, end users will rarely notice a *-over occurred.
Databases in Exchange 2010 have now been moved to the organizational level instead of the server level where they existed in Exchange 2007 and earlier versions. This also means Exchange 2010 does not have the concept of storage groups any longer. Now there are databases and a log stream associated with each database. One drawback of CCR was that if only one database failed on the active node, a fail-over of all active databases existing on the clustered mailbox server were moved to the passive CCR node. This meant that all users on that had a mailbox stored on the respective mailbox cluster were affected.
Data centre Activation Coordination (DAC) mode is a property setting for a database availability group (DAG). DAC mode is specifically designed for DAGs with three or more members that are extended to two Active Directory sites. DAC mode is disabled by default and should only be enabled for DAGs with three or more DAG members that have been deployed in a multi-data centre configuration. DAC mode shouldn't be enabled for:
- 2 member DAGs where each member is in a different Active Directory site
- 2-16 member DAGs where all members are in the same Active Directory site
DAC mode is used to control the activation behaviour of a DAG when a catastrophic failure occurs that affects the DAG (for example, a complete failure of one of the data centres). When DAC mode isn't enabled, and a failure affecting multiple servers in the DAG occurs, when a majority of servers are restored after the failure, the DAG will restart and attempt to mount databases. In a multi-data centre configuration, this behaviour could cause split brain syndrome, a condition that occurs when all networks fail, and DAG members can't receive heartbeat signals from each other. Split brain syndrome also occurs when network connectivity is severed between the data centres. Split brain syndrome is prevented by always requiring a majority of the DAG members (and in the case of DAGs with an even number of members, the DAG's witness server) to be available and interacting for the DAG to be operational. When a majority of the members are communicating, the DAG is said to have a quorum.
For example, consider a scenario where Liverpool contains two DAG members and the witness server, and the Bath contains two other DAG members. If Liverpool loses power and you activate the DAG in Bath, if the Bath is restored without network connectivity to the Liverpool, the DAG may enter a split brain syndrome.
DAC mode is designed to prevent split brain syndrome from occurring by including a protocol called Data centre Activation Coordination Protocol (DACP). After a catastrophic failure, when the DAG recovers, it won't automatically mount databases even though the DAG has a quorum. Instead DACP is used to determine the current state of the DAG and whether Active Manager should try to mount the databases.
Active Manager stores a bit in memory (either a 0 or a 1) that tells the DAG whether it's allowed to mount local databases that are assigned as active on the server. When a DAG is running in DAC mode (which would be any DAG with three or more members), each time Active Manager starts up the bit is set to 0, meaning it isn't allowed to mount databases. Because it's in DAC mode, the server must try to communicate with all other members of the DAG that it knows to get another DAG member to give it an answer as to whether it can mount local databases that are assigned as active to it. The answer comes in the form of the bit setting for other Active Managers in the DAG. If another server responds that its bit is set to 1, it means servers are allowed to mount databases, so the server starting up sets its bit to 1 and mounts its databases.
But when you recover from a primary data centre power outage where the servers are recovered but WAN connectivity has not been restored, all of the DAG members in the primary data centre will have a DACP bit value of 0; and therefore none of the servers starting back up in the recovered primary data centre will mount databases, because none of them can communicate with a DAG member that has a DACP bit value of 1.
To enable internal Exchange communication with the DAG, an IP address has to be assigned to it. In a situation where the DAG is configured across Active Directory sites, it is necessary to configure several IP addresses with at least one address in each IP Subnet. This can be achieved via DHCP, but in an environment without DHCP, this needs to be assigned using the Exchange Management Shell using the Set-DatabaseAvailabilityGroup command with the DatabaseAvailabilityGroupIpAddresses parameter.
Finally, servers that are DAG members don't use Microsoft Update to install update rollups. Instead, you need to download the update rollups from the Microsoft Download Centre and then install them manually. When you install an update rollup on a server that's a DAG member, several services will be stopped during the installation, including all Exchange services and the Windows Cluster service. The general process for installing update rollups on a DAG member is as follows:
- Suspend activation for the databases on the server being updated.
- Perform a server switchover so that all databases on the server are passive copies. During the switchover process, there will be a brief interruption in service for the mailboxes hosted on the active databases.
- Install the update rollup.
- Resume activation for the databases on the updated server.
- Perform database switchovers as needed.
|
| If like me you use the .NET languages as a grown up version of VBScript, and you're not so much interested in doing things properly, just getting them done, then you know the frustration of trying to create multithreaded applications that can communicate with the GUI in real time without having to go through the mind bending nonsense of creating delegates and such like. All I want to do is update my progress bar or write some text into a textbox. Well, as long as you're using basic WinForms, you can just stick this statement into you form's load method.
Control.CheckForIllegalCrossThreadCalls = False
Now, rather wonderfully it doesn't matter which thread you update the form with. Okay, all those serious development dudes will poke fun at you, but it reduces your development time hugely and takes out much of the complexity. Let those people writing applications for the wider masses mess about with the formal methodology for multi-threading, I'll start thinking about it when I start writing user facing programs for real people. Most of my applications are for me and half a dozen other people who can live with its minor eccentricities.
|
| My very good friend and former colleague, Jim Wightman, who recently started working for Microsoft on the Solutions Acceleration team has just launched his new blog. He always has much more interesting stuff than I do and it's well worth checking out for all programming tips, especially C#, C++, Silverlight, XNA, SQL Server with Windows and Windows Phone 7 development. Catch him here: http://blogs.technet.com/jimw/
Here's Jim, although this picture isn't to scale J àààààà
...Late breaking news.... Jim's got another blog here as well: http://blogs.msdn.com/jimwdev/ - Jim, How many blogs do you need dude? You've got work to do as well you know! |
| This is a great new feature. I can't stand all that thumb work required to send even the simplest of text messages to someone.
Now all you need is Exchange 2010 as your mail system, Outlook 2010, and Windows Mobile 6.5.x as your phone OS (yes, iPhone lovers, this doesn't work for you, get your mother to buy you a grown up phone).
Now, once you have configured ActiveSync, you have the option to sync your text messages with Exchange (i.e. text message sent to your phone arrive in you Outlook Inbox as well!). Once this is done and a full sync has taken place, you can now open up Outlook 2010 and a message appears alerting you that you can now send text messages from Outlook or OWA, and that you should restart your client.

Next time you open Outlook you can see a drop down list from the small arrow on the "New Items button" (See below)
Click on this and you can type your message into the nice new Text Message form.
When you click send, the message synchronises to your Windows Mobile and it recognises it as a new text message and the phone sends it. The whole process is near instantaneous. Cool!
Now you don't have to subscribe to an external SMS message service. |
| Microsoft has just announced the release of Windows Embedded 7 Standard. This version obviously based around an ultra-componentised version on the Windows 7 Client OS. Its primary focus is for manufacturers to create embedded hardware applications such as media centre devices, or Point of Sale devices (tills to you and me).
It's always struck me that it would also make a good replacement for WinPE in client build systems since it supports .NET, but I've never had the time to give it a look.
Anyway, find out more here: http://msdn.microsoft.com/en-gb/windowsembedded/standard/default.aspx
|
Manage Subscriptions /_layouts/images/ReportServer/Manage_Subscription.gif /_layouts/ReportServer/ManageSubscriptions.aspx?list={ListId}&ID={ItemId} 0x80 0x0 FileType rdl 350 Manage Data Sources /_layouts/ReportServer/DataSourceList.aspx?list={ListId}&ID={ItemId} 0x0 0x20 FileType rdl 351 Manage Shared Datasets /_layouts/ReportServer/DatasetList.aspx?list={ListId}&ID={ItemId} 0x0 0x20 FileType rdl 352 Manage Parameters /_layouts/ReportServer/ParameterList.aspx?list={ListId}&ID={ItemId} 0x0 0x4 FileType rdl 353 Manage Processing Options /_layouts/ReportServer/ReportExecution.aspx?list={ListId}&ID={ItemId} 0x0 0x4 FileType rdl 354 Manage Cache Refresh Plans /_layouts/ReportServer/CacheRefreshPlanList.aspx?list={ListId}&ID={ItemId} 0x0 0x4 FileType rdl 355 View Report History /_layouts/ReportServer/ReportHistory.aspx?list={ListId}&ID={ItemId} 0x0 0x40 FileType rdl 356 View Dependent Items /_layouts/ReportServer/DependentItems.aspx?list={ListId}&ID={ItemId} 0x0 0x4 FileType rsds 350 Edit Data Source Definition /_layouts/ReportServer/SharedDataSource.aspx?list={ListId}&ID={ItemId} 0x0 0x4 FileType rsds 351 View Dependent Items /_layouts/ReportServer/DependentItems.aspx?list={ListId}&ID={ItemId} 0x0 0x4 FileType smdl 350 Manage Clickthrough Reports /_layouts/ReportServer/ModelClickThrough.aspx?list={ListId}&ID={ItemId} 0x0 0x4 FileType smdl 352 Manage Model Item Security /_layouts/ReportServer/ModelItemSecurity.aspx?list={ListId}&ID={ItemId} 0x0 0x2000000 FileType smdl 353 Regenerate Model /_layouts/ReportServer/GenerateModel.aspx?list={ListId}&ID={ItemId} 0x0 0x4 FileType smdl 354 Manage Data Sources /_layouts/ReportServer/DataSourceList.aspx?list={ListId}&ID={ItemId} 0x0 0x20 FileType smdl 351 Load in Report Builder /_layouts/ReportServer/RSAction.aspx?RSAction=ReportBuilderModelContext&list={ListId}&ID={ItemId} 0x0 0x2 FileType smdl 250 Edit in Report Builder /_layouts/images/ReportServer/EditReport.gif /_layouts/ReportServer/RSAction.aspx?RSAction=ReportBuilderReportContext&list={ListId}&ID={ItemId} 0x0 0x4 FileType rdl 250 Edit in Report Builder /_layouts/ReportServer/RSAction.aspx?RSAction=ReportBuilderDatasetContext&list={ListId}&ID={ItemId} 0x0 0x4 FileType rsd 250 Manage Caching Options /_layouts/ReportServer/DatasetCachingOptions.aspx?list={ListId}&ID={ItemId} 0x0 0x4 FileType rsd 350 Manage Cache Refresh Plans /_layouts/ReportServer/CacheRefreshPlanList.aspx?list={ListId}&ID={ItemId}&IsDataset=true 0x0 0x4 FileType rsd 351 Manage Data Sources /_layouts/ReportServer/DataSourceList.aspx?list={ListId}&ID={ItemId} 0x0 0x20 FileType rsd 352 View Dependent Items /_layouts/ReportServer/DependentItems.aspx?list={ListId}&ID={ItemId} 0x0 0x4 FileType rsd 353 Compliance Details javascript:commonShowModalDialog('{SiteUrl}/_layouts/itemexpiration.aspx?ID={ItemId}&List={ListId}', 'center:1;dialogHeight:500px;dialogWidth:500px;resizable:yes;status:no;location:no;menubar:no;help:no', function GotoPageAfterClose(pageid){if(pageid == 'hold') {STSNavigate(unescape(decodeURI('{SiteUrl}'))+'/_layouts/hold.aspx?ID={ItemId}&List={ListId}'); return false;} if(pageid == 'audit') {STSNavigate(unescape(decodeURI('{SiteUrl}'))+'/_layouts/Reporting.aspx?Category=Auditing&backtype=item&ID={ItemId}&List={ListId}'); return false;} if(pageid == 'config') {STSNavigate(unescape(decodeURI('{SiteUrl}'))+'/_layouts/expirationconfig.aspx?ID={ItemId}&List={ListId}'); return false;}}, null); return false; 0x0 0x1 ContentType 0x01 898 |
|
|
|
|
| Welcome to the x9000.com blog system. The basic idea is for a portal for our development ideas, news alerts, and general rantings that would otherwise just get shouted at the television. |
|
|
|
Here are my contact details. Drop me a line and let me know your ideas, opinions, etc....
Paul Prior
IT Consultant and Company Director
|
|
|
Manage Subscriptions /_layouts/images/ReportServer/Manage_Subscription.gif /_layouts/ReportServer/ManageSubscriptions.aspx?list={ListId}&ID={ItemId} 0x80 0x0 FileType rdl 350 Manage Data Sources /_layouts/ReportServer/DataSourceList.aspx?list={ListId}&ID={ItemId} 0x0 0x20 FileType rdl 351 Manage Shared Datasets /_layouts/ReportServer/DatasetList.aspx?list={ListId}&ID={ItemId} 0x0 0x20 FileType rdl 352 Manage Parameters /_layouts/ReportServer/ParameterList.aspx?list={ListId}&ID={ItemId} 0x0 0x4 FileType rdl 353 Manage Processing Options /_layouts/ReportServer/ReportExecution.aspx?list={ListId}&ID={ItemId} 0x0 0x4 FileType rdl 354 Manage Cache Refresh Plans /_layouts/ReportServer/CacheRefreshPlanList.aspx?list={ListId}&ID={ItemId} 0x0 0x4 FileType rdl 355 View Report History /_layouts/ReportServer/ReportHistory.aspx?list={ListId}&ID={ItemId} 0x0 0x40 FileType rdl 356 View Dependent Items /_layouts/ReportServer/DependentItems.aspx?list={ListId}&ID={ItemId} 0x0 0x4 FileType rsds 350 Edit Data Source Definition /_layouts/ReportServer/SharedDataSource.aspx?list={ListId}&ID={ItemId} 0x0 0x4 FileType rsds 351 View Dependent Items /_layouts/ReportServer/DependentItems.aspx?list={ListId}&ID={ItemId} 0x0 0x4 FileType smdl 350 Manage Clickthrough Reports /_layouts/ReportServer/ModelClickThrough.aspx?list={ListId}&ID={ItemId} 0x0 0x4 FileType smdl 352 Manage Model Item Security /_layouts/ReportServer/ModelItemSecurity.aspx?list={ListId}&ID={ItemId} 0x0 0x2000000 FileType smdl 353 Regenerate Model /_layouts/ReportServer/GenerateModel.aspx?list={ListId}&ID={ItemId} 0x0 0x4 FileType smdl 354 Manage Data Sources /_layouts/ReportServer/DataSourceList.aspx?list={ListId}&ID={ItemId} 0x0 0x20 FileType smdl 351 Load in Report Builder /_layouts/ReportServer/RSAction.aspx?RSAction=ReportBuilderModelContext&list={ListId}&ID={ItemId} 0x0 0x2 FileType smdl 250 Edit in Report Builder /_layouts/images/ReportServer/EditReport.gif /_layouts/ReportServer/RSAction.aspx?RSAction=ReportBuilderReportContext&list={ListId}&ID={ItemId} 0x0 0x4 FileType rdl 250 Edit in Report Builder /_layouts/ReportServer/RSAction.aspx?RSAction=ReportBuilderDatasetContext&list={ListId}&ID={ItemId} 0x0 0x4 FileType rsd 250 Manage Caching Options /_layouts/ReportServer/DatasetCachingOptions.aspx?list={ListId}&ID={ItemId} 0x0 0x4 FileType rsd 350 Manage Cache Refresh Plans /_layouts/ReportServer/CacheRefreshPlanList.aspx?list={ListId}&ID={ItemId}&IsDataset=true 0x0 0x4 FileType rsd 351 Manage Data Sources /_layouts/ReportServer/DataSourceList.aspx?list={ListId}&ID={ItemId} 0x0 0x20 FileType rsd 352 View Dependent Items /_layouts/ReportServer/DependentItems.aspx?list={ListId}&ID={ItemId} 0x0 0x4 FileType rsd 353 Compliance Details javascript:commonShowModalDialog('{SiteUrl}/_layouts/itemexpiration.aspx?ID={ItemId}&List={ListId}', 'center:1;dialogHeight:500px;dialogWidth:500px;resizable:yes;status:no;location:no;menubar:no;help:no', function GotoPageAfterClose(pageid){if(pageid == 'hold') {STSNavigate(unescape(decodeURI('{SiteUrl}'))+'/_layouts/hold.aspx?ID={ItemId}&List={ListId}'); return false;} if(pageid == 'audit') {STSNavigate(unescape(decodeURI('{SiteUrl}'))+'/_layouts/Reporting.aspx?Category=Auditing&backtype=item&ID={ItemId}&List={ListId}'); return false;} if(pageid == 'config') {STSNavigate(unescape(decodeURI('{SiteUrl}'))+'/_layouts/expirationconfig.aspx?ID={ItemId}&List={ListId}'); return false;}}, null); return false; 0x0 0x1 ContentType 0x01 898 |
|
|