Microsoft hacks away at TechNet membership benefits (again)

TechNet Professional (formerly TechNet Plus) subscriptions are one of the best ideas to come from Redmond – allow IT Pros to pay a subscription, and evaluate pretty much all Microsoft software without time limits and expirations. Why is this such a good idea? Because Microsoft gets a significant portion of its revenue from business licensing, and making evaluation as easy as possible can only encourage adoption of new versions.

Last year, Microsoft silently dropped the number of licenses per application from 10 down to 5, arguing that for evaluation, there was no need for so many licenses. Perhaps, perhaps not. I create new VMs to evaluate software fairly regularly, and having 10 keys makes it much less likely to encounter activation issues.

But ok, we only get 5 – so we adjust.

Well, for some reason Microsoft has decided that they want to scale things back further – as seen on the subscription home page,


Beginning on January 26, 2012, individual subscribers to TechNet Professional Subscriptions may access a maximum allocation of 3 product keys for Microsoft Office and Windows Client products in connection with their subscription. The allotted keys may only be used for software evaluation purposes. Once the maximum keys have been activated no more keys will be made available. Additional product keys may be acquired through the purchase of an additional subscription.

Unfortunately, I just saw this today, so I’m doing like any reasonable person would and requesting all 5 keys for any Office or Windows related products before they drop it down again – until I hit the daily key request limit…

First of all, making software evaluation more difficult is only going to hurt Microsoft. But then again, Windows 8 doesn’t appear to be geared toward business AT ALL, so maybe it is indicative of a shift in strategy.
(It is odd that Windows 8 preview still isn’t on TechNet, nor is the System Center 2012 RC…)

If only TechNet members had the time to protest…

How to embed an application manifest in a CodeDom generated assembly

When using CodeDom to generate executables (using CodeCompileUnit.CompileAssemblyFromDom for example), you can easily embed your custom application manifest using the CompilerParameters.CompilerOptions string, like so:

            CompilerParameters cp = new CompilerParameters();
            cp.GenerateExecutable = true;
            cp.GenerateInMemory = false;
            cp.TreatWarningsAsErrors = false;
            cp.OutputAssembly = "RandomFileName.exe";
            cp.CompilerOptions = "/optimize+ /debug- /win32manifest:RandomFileName.exe.manifest";

The relevant option being /win32manifest. Make sure you create the manifest before attempting to compile, obviously.

And use the CompileParameters in CompileAssemblyFromDom();

FYI – There are other ways to do this, but they would involve finding and running some command line utilities. This is by far the easiest, and most elegant way I could find.

DIRECTV2PC activation key usage limit error

I have been trying to install DIRECTV2PC for a week or so (off and on of course) and I get the error “Activation Failed” with a reason of “activation key usage limit reached”

For some reason, nobody had a solution – on satelliteguys.us or dbstalk.com (or directv forums, or the internet as a whole).
I had already requested two keys, and I had only used them once – it seems ridiculous to me that I cannot use the key again if I, say, reinstall Windows (which I tend to a couple times a year)…

I found a workaround – use a different email address to request a new key. (Many email providers allow you to insert arbitrary periods in your email address…)

DIRECTV2PC is made by cyberlink for Directv. Nobody seems to know why it requires a product key – probably some accounting thing. Rumor has it that it may be going away soon anyway.

Good luck!

Outlook 2010 Check Names ignores Contacts

After my most recent reinstall of windows, for some reason Outlook 2010 stopped looking in my Contacts when I would hit Check Names. It was only looking in the Global Address Book. I would have to look up the person in my contacts, and Outlook would autocomplete until it was restarted.

Lame.

The solution is here: Outlook 2010: How to change your default Contacts Address Book

I changed mine to be custom so it would look in both the global address book (containing the employee list) AND my contacts. And it’s working.

Now to figure out why the autocomplete gets reset every time I close and reopen…

Paragraph formatting, new lines and bullet lists in Word Rich Text Content Controls

Every since who knows when, Microsoft Word has had Form Fields that allow you to create a fill-in form using Word. Trouble is, unless you protect the document, people rarely end up placing the text in the correct box – or they might delete the field altogether.

So you protect the document. Now spell checking doesn’t work, the arrow keys don’t work right, it is difficult to select text, no formatting, and… well it’s just plain bad.

As of Word 2007 and Word 2010, there is a better solution called Content Controls – accessed from the Developer tab. The Rich Text content countrol allows for formatted text without messing up the surrounding document, and (if you do it right) supports spell checking. The trick is to use grouping instead of document protection. (Create your document, select everything, and group it from the developer tab. The document cannot be edited, except for the content controls)

This is great, but we ran into a mystifying problem with the Rich Text content control – in our existing document, it was not creating new lines when you pressed the return / enter key. You could hold shift-enter to get a new line, but then you could not create bulleted lists. We tried creating a new word document and adding a rich text control, and it worked fine – it seemed to be a problem with our existing document.

The solution: The rich text control does not allow sub-paragraphs when it is not the only thing in a paragraph. Place the content control in it’s own paragraph in the word document, and it will allow bulleted lists, new paragraphs, formatting, etc.

Uninstalling Windows 8 when using UEFI

So you went ahead and dual booted the Windows 8 Developer Preview with your Windows 7 machine, but decided you don’t want it anymore. There are lots of instructions online for how to remove it when you are using a standard boot, but if you are using UEFI your life is much simpler. (I’m not going into detail since if you figured out how to dual boot, you probably can handle a partition or two)

Using Disk Management, delete the volume for your windows 8 installation. Optionally, expand the volume for your Windows 7 install to get the space back.

If you want to speed up the boot process a bit, Open the Advanced System Settings (rt click Computer, Properties, Advanced System Settings), click Settings… under Startup and recovery, and make sure the check box next to “Time to display list of operating systems” is unchecked, (and that Windows 7 is the default operating system).

 

All done! No need to edit the BCD when using EFI boot, it appears that windows automatically removes the windows 8 entry when you delete the partition. (I ran bcdedit just to check)

Microsoft tool for creating bootable USB drive

Not sure when this happened, but MS has a tool on Codeplex that will copy a bootable iso to a USB flash drive and make it bootable. I haven’t tried it, but it’s nice to finally have a purpose-built tool for the job..

Have a look here:
Windows 7 USB/DVD Download Tool

Note: the comments say it works with windows 8 as well – probably works with server 2008 r2 as well.

Using dsamain to browse disconnected ntds.dit

If you want to peek into the past contents of your Active Directory, you used to have to perform a complete server restore. (By used to, I mean server 2003)

Server 2008 has a tool that allows you to mount the ntds.dit file from your backup as an LDAP server, which can then be browsed using ADSI Edit. Once you get it to work, it is much quicker than a full backup if you are able to extract just the database files. The first step is to install the AD DS role on a member server – I would not recommend doing this on a domain controller proper. This will get you the tools you need to proceed.

As usual, I am posting this because the internet demonstrated epic fail when it came to debugging the process.
When I first attempted to use dsamain.exe on the ntds.dit file, I received the following errors:

dsamain /dbpath ntds.dit /ldapport 1492
EVENTLOG (Error): NTDS General / Internal Processing : 1168
Internal error: An Active Directory Domain Services error has occurred.
Error value (decimal): -550
Error value (hex): fffffdda
Internal ID: 40878
EVENTLOG (Error): NTDS General / Internal Processing : 1003
Active Directory Domain Services could not be initialized.
The directory service cannot recover from this error.

Because my AD database copy was taken in a “naughty” manner, the solution to this issue is to use the esentutl utility to recover the database (apply the log files) then repair the database.
I had a heck of a time with esentutl not working at first – it complained about missing references and such. The solution:
1. Make sure you have the database file AND the log files. Sometimes these are placed on separate volumes
2. the ESENTUTL recovery command takes a 3-character logfile prefix as the parameter, NOT the database file name
3. The utility determines the database file path from the logfiles. You need to place all the files from your original Domain Controller into the same folder on your member server (eg: C:\windows\NTDS). If esentutl complains, you may need to check your paths.
4. Open an elevated command prompt, change the folder containing your files, and run “esentutl /r edb” It should just work

Next, check the integrity of the database. It will probably find some errors
“esentutl /g ntds.dit”

Finally, run a repair on the database, and be sure to click “Yes” (or OK) on the prompt
“esentutl /p ntds.dit”

Now you can use dsamain to try mounting the database:
“dsamain /dbpath ntds.dit /ldapport 1492”

If you are like me, you will get an error along the lines of 1809 JET_errPermissionDenied, Permission denied
(meta note: the phrase “JET_errPermissionDenied” was painfully absent from any meaningful pages in the internet before now.)

The solution to this error: use the allowupgrade option when running dsamain. (I’m guessing this is happening because the member server is not running the same exact version of AD DS as the Domain Controller).

Using this command:
“dsamain /dbpath ntds.dit /ldapport 1492 /allownonadminaccess /allowupgrade”

It updated the database, and mounted the sucker. (I do receive an error about exclusive access to a port – haven’t resolved it, but as long as your LDAP port is ok, you should be fine)

Now run ADSI Edit, connect to localhost:1492 (or your port of choice) select your desired naming context, and enjoy the time travelling experience!

Creating a Custom Tool (Single File Generator) for Visual Studio 2010

A Single File Generator or “Custom Tool” is a COM “extension” for Visual Studio that takes a project file as input, and spits out some code. (One example is the .settings files) Visual Studio automatically includes the code in your project, and updates it every time you save.

I developed a tool that reads an Office 2010 Ribbon XML file and produces an interface will all the callbacks in your file (because implementing callback signatures is a bear).

Unfortunately, Microsoft’s documentation on the subject is incomplete and obsolete. If you search the web, you will find contradictory information…
I didn’t want my assembly in the GAC, nor did want to have to register the COM object globally. I didn’t want to create a setup project, or use any fancy generated code… I just wanted it to work.

So here are some tips that should get you going.

  1. First of all, there is no need to use the Visual Studio extensibility project template for this. Just create a standard Class Library in the .NET language of your choice.
  2. Add a reference to Microsoft.VisualStudio.Shell.10.0 and Microsoft.VisualStudio.Shell.Interop to your project. (If you do not have these, you probably need to download the Visual Studio 2010 SP1 SDK)
  3. In the Project Properties, in the Application tab, click “Assembly Information…” and check the “Make Assembly COM Visible” box.
  4. Do NOT select “Register for COM interop” on the Build tab
  5. On the signing tab, check sign the assembly, and select or create a key
  6. Add the following using statements to your class file:
    using System.Runtime.InteropServices;
    using Microsoft.VisualStudio.Shell.Interop;
    using Microsoft.VisualStudio;
    
  7. Add the ComVisible attribute
  8. Add a Guid to the class (use the Tools Menu-> Create GUID and select Item 5 for c#, item 6 for vb.net, hit copy)
  9. Make your class implement the IVsSingleFileGenerator interface.
  10. It should look like this:
        [ComVisible(true)]
        [Guid("FAKEGUID-FFF6-4FF3-FFF7-FFFFRFRFRF45")]
        public class Generator : IVsSingleFileGenerator
        {
    
  11. DO NOT USE THIS GUID. YOU MUST GENERATE YOUR OWN
  12. Implement the IVsSingleFileGenerator interface’s two methods – Generate and DefaultExtension (see the documentation for more details)
  13. Build it!
  14. Now for the part where the documentation falls apart – registering and using this bad boy.

  15. The easiest way to register this is using the Visual Studio local registry at HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0
    Note: on 32-bit systems, this may be at HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\10.0 – I am using the 64-bit
    There should be plenty of sub-keys under this key. If there are not, perhaps you need to look in a different version, or bit-ness
  16. First, you need to add the COM information like so
    Windows Registry Editor Version 5.00
    
    [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0\CLSID\{FAKEGUID-FFF6-4FF3-FFF7-FFFFRFRFRF45}]
    "InprocServer32"="C:\\Windows\\SysWOW64\\mscoree.dll"
    "ThreadingModel"="Both"
    "Class"="DemoSFGen.Generator"
    "Assembly"="DemoSFGen, Version=1.0.0.0, Culture=neutral, PublicKeyToken=faketokenfffff88"
    "CodeBase"="file:///C:\\Users\\username\\Documents\\Visual Studio 2010\\Projects\\sfgen\\sfgen\\bin\\Debug\\sfgen.dll"
    

    Replace the GUID after CLSID with the GUID you generated earlier; replace the Class with your Namespace.ClassName; replace Assembly with the information from your dll (I used ILSpy – I’m sure there’s an easier way); replace CodeBase with the full path to your dll.

  17. Next, add the registry info to tell Visual Studio about the Generator:
    Windows Registry Editor Version 5.00
    
    [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0\Generators\{FAE04EC1-301F-11D3-BF4B-00C04F79EFBC}\DemoSFGen]
    "CLSID"="{FAKEGUID-FFF6-4FF3-FFF7-FFFFRFRFRF45}"
    "GeneratesDesignTimeSource"=dword:00000001
    @="Nice Name For your Generator"
    

    The GUID after \Generators\ corresponds to the languages in Visual Studio. See the docs for registering single file generators for a couple (or have a look in the registry).
    The Key name under the language guid (DemoSFGen in this case) is (I believe) how you will refer to the Custom Tool
    The value of CLSID needs to match your generated GUID

  18. Run Visual Studio, open a (different) project, and select an appropriate input file (text, xml, etc) In the properties for the file, add the name of the Custom Tool (“DemoSFGen”).
  19. Right click on the file, and select “Run Custom Tool”
  20. If everything worked, you will now be able to expand the file, and see your generated source underneath it. If there was a problem, Visual Studio may or may not display an error…

I know that Custom Tools aren’t the most often created things in the world, but hopefully these steps can at least get you up and running when you do try.

Undocumented behavior of Office 2010 Word Save As dialog with Sharepoint

Here’s another Office 2010 undocumented “feature”.

First a little background regarding required fields in sharepoint:
In Office 2007, in order to attach the Sharepoint properties to a document you had to first Save it into the document library. Word would allow you to save, but the document would remain checked-out to you until you filled in the necessary required properties, and checked it in.

If you were developing a system that automated adding documents to SharePoint, you could not even present the Document Information Panel to the user until the document was already in SharePoint. If the user decided to cancel… you had hanging files.

With Office 2010, Word (and I imagine other apps) will not actually complete the Save operation to a SharePoint Document Library when there are required fields. You get a warning and the document is _not_ placed in SharePoint, but the Fields from the Document Library are attached to your Word document.

In Word, if you want to display the “Save As” dialog box pre-populated to a SharePoint library you do something like this:

dynamic dlg = Application.Dialogs[Word.WdWordDialog.wdDialogFileSaveAs];
dlg.Name = "http://sharepointserver/doclib/filename.docx";
dlg.Show();

This will act the same as the normal “Save As” dialog.

If you want to handle the save process yourself, instead of dlg.Show(), use dlg.Display. This *should* take no action regardless if the user presses Ok or Cancel. If the destination happens to be SharePoint – intsead of doing nothing like it is supposed to – Word happily retreives the Sharepoint properties and attaches them to your document.

In addition to being handy, Word will attach the document properties to Read-Only and Protected files – which is something you cannot do using CustomXMLParts.
And it’s a heck of a lot easier than trying to build and attach them yourself.

While it is undocumented (and therefore subject to change), it is kind of impossible to work around — Word WILL attach the sharepoint properties, so you might as well take advantage of it.

UPDATE 3/20/2012: Unfortunately, I have discovered that this method is unreliable. On one of our user’s machines, the Save As dialog refuses to display the sharepoint folder at all. I don’t know why, but I wouldn’t recommend relying on this.