//***************************************************************************
//
//    Copyright (c) 2008 Microsoft Corporation. All rights reserved.
//    This code is licensed under the Visual Studio Tools for Applications SDK 
//    license terms. THIS CODE IS PROVIDED “AS IS” WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//***************************************************************************

// *******************************************************************
// SetupShapeAppMacroRecordingCSharp.js
//
// This script can be used to setup ShapeAppMacroRecordingCSharp to run
// with Visual Studio Tools for Applications and with Visual Studio.
// 
// If, when the sample was extracted from the original zip file,
// no changes were made to the location of any files or directories
// with respect to the root sample directory, then this script may
// be run as is. Otherwise, change the variables in the "Installation
// parameters" section to indicate the new location of the moved files.

// *******************************************************************
// Create standard objects

var fso = new ActiveXObject("Scripting.FileSystemObject");
var wshShell = new ActiveXObject("WScript.Shell");

// *******************************************************************
// Installation parameters

var hostID = "ShapeAppCSharp";
var manufacturer = "Microsoft";

var sampleRootPath = fso.GetParentFolderName(WScript.ScriptFullName);
var installPath = fso.BuildPath(sampleRootPath, "integration\\MacroRecording\\bin\\debug");
var templatesPath = fso.BuildPath(sampleRootPath, "Templates");
var csAppAddInTemplatePath = fso.BuildPath(templatesPath, "CSharp\ShapeAppCSharp-AppLevel-dt-only-has-host-item.zip");
var vbAppAddInTemplatePath = fso.BuildPath(templatesPath, "VisualBasic\\ShapeAppCSharp-AppLevel.zip");



// *******************************************************************
// Verify there's at least one template to install

if (!fso.FileExists(csAppAddInTemplatePath) &&
    !fso.FileExists(vbAppAddInTemplatePath))
{
    WScript.Echo("Error: At least one template file must be present. " + 
        "Please verify the template locations before running this script.");
    WScript.Quit(-1);
}

// *******************************************************************
// Locate VSTA

var setupVSTA = false;
var vstaPath = "";
var vstaExeLocation = "";

try
{
    vstaPath = wshShell.RegRead("HKLM\\SOFTWARE\\Wow6432Node\\Microsoft\\VSTA\\9.0\\InstallDir");
    setupVSTA = true;
}
catch(ex)
{
    // Ignore Exception
}

if (setupVSTA)
{
    vstaExeLocation = fso.BuildPath(vstaPath, "vsta.exe");

    if (vstaPath == "" || !fso.FileExists(vstaExeLocation))
    {
       setupVSTA = false;
    }
}



// *******************************************************************
// Setup the registry for VSTA setup

if (setupVSTA)
{
WScript.Echo("Setup the registry for VSTA setup");

    try
    {
        var delCommand = "reg delete HKLM\\Software\\Wow6432Node\\Microsoft\\VSTAHost\\" + hostID + " /f";
        var delExec = wshShell.Exec(delCommand);
        while (delExec.Status == 0)
        {
            WScript.Sleep(100);
        }

        wshShell.RegWrite("HKLM\\Software\\Wow6432Node\\" + manufacturer + "\\" + 
            hostID + "\\", "");
        wshShell.RegWrite("HKLM\\Software\\Wow6432Node\\" + manufacturer + "\\" + 
            hostID + "\\InstallPath", installPath, "REG_SZ");

        wshShell.RegWrite("HKLM\\Software\\Wow6432Node\\Microsoft\\VSTAHostConfig\\" + 
            hostID + "\\", "");
        wshShell.RegWrite("HKLM\\Software\\Wow6432Node\\Microsoft\\VSTAHostConfig\\" + 
            hostID + "\\2.0\\", "");

        wshShell.RegWrite("HKLM\\Software\\Wow6432Node\\Microsoft\\VSTAHostConfig\\" + 
            hostID + "\\2.0\\AppName", hostID, "REG_SZ");
        wshShell.RegWrite("HKLM\\Software\\Wow6432Node\\Microsoft\\VSTAHostConfig\\" + 
            hostID + "\\2.0\\ProjectTemplatesLocation", templatesPath, "REG_SZ");
        wshShell.RegWrite("HKLM\\Software\\Wow6432Node\\Microsoft\\VSTAHostConfig\\" + 
            hostID + "\\2.0\\VSTAVersion", "9.0", "REG_SZ");
    }
    catch(ex)
    {
        // An error happened when writing to the registry, so 
        // block setting up VSTA
        setupVSTA = false;
    }
}

// *******************************************************************
// Run VSTA setup

if (setupVSTA)
{
    var vstaCommand = "\"" + vstaExeLocation + "\" /HostID " + hostID + " /setup";

    var vstaExec = wshShell.Exec(vstaCommand);
    while (vstaExec.Status == 0)
    {
        WScript.Sleep(100);
    }
    
    // We need to set AllThreadsRunOnFuncEval to 1 to resolve issues during third-proc debugging.
    // Please see documentation for more information.
    try
    {
        wshShell.RegWrite("HKLM\\Software\\Wow6432Node\\Microsoft\\VSTAHost\\" + 
            hostID + "\\9.0\\AD7Metrics\\Engine\\{449EC4CC-30D2-4032-9256-EE18EB41B62B}\\AllThreadsRunOnFuncEval", "1", "REG_DWORD");

    }
    catch(ex)
    {
        WScript.Echo("Warning: fail to write AllThreadsRunOnFuncEval key. " + ex.message);
    }
}

// *******************************************************************
// Locate VS and ProjectTemplates directory

var setupVS = false;
var vsPath = "";
var vsExeLocation = "";
var vsProjectTemplatesPath = "";

try
{
    vsPath = wshShell.RegRead("HKLM\\SOFTWARE\\Wow6432Node\\Microsoft\\VisualStudio\\9.0\\InstallDir");
    vsProjectTemplatesPath = 
        wshShell.RegRead("HKLM\\SOFTWARE\\Wow6432Node\\Microsoft\\VisualStudio\\9.0\\VSTemplate\\Project\\UserFolder");
    setupVS = true;
}
catch(ex)
{
    // Ignore Exception
}

if (setupVS)
{
    vsExeLocation = fso.BuildPath(vsPath, "devenv.exe");

    if (vsPath == "" || !fso.FileExists(vsExeLocation))
    {
       setupVS = false;
    }
}

// *******************************************************************
// Copy templates to ProjectTemplates

if (setupVS)
{
    var templateCount = 0;
    try
    {

        if (fso.FileExists(csAppAddInTemplatePath))
        {
            var destination = 
                fso.BuildPath(vsProjectTemplatesPath, 
                "CSharp\\ShapeAppCSharp\\1033\\");
            if (EnsureFolder(destination))
            {
                fso.CopyFile(csAppAddInTemplatePath, destination);
                templateCount++;
            }
        }
        if (fso.FileExists(vbAppAddInTemplatePath))
        {
            var destination = 
                fso.BuildPath(vsProjectTemplatesPath, 
                "VisualBasic\\ShapeAppCSharp\\1033\\");
            if (EnsureFolder(destination))
            {
                fso.CopyFile(vbAppAddInTemplatePath, destination);
                templateCount++;
            }
        }
        if (templateCount == 0)
        {
            setupVS = false;
        }
    }
    catch(ex)
    {
        setupVS = false;
    }
}

// *******************************************************************
// Run VS setup

if (setupVS)
{
    var vsCommand = "\"" + vsExeLocation + "\" /setup";

    var vsExec = wshShell.Exec(vsCommand);
    while (vsExec.Status == 0)
    {
        WScript.Sleep(100);
    }
}

// *******************************************************************
// If nothing was setup, notify the user.

if (!setupVSTA && !setupVS)
{
    WScript.Echo("Error: Neither VSTA nor VS setup was run. " + 
        "Is at least one installed? Is at least one template available?");
    WScript.Quit(-1);
}

// *******************************************************************
// Helper Methods

function EnsureFolder(folderSpec)
{
    if (fso.FolderExists(folderSpec))
        return true;

    var parentFolder = fso.GetParentFolderName(folderSpec);
    if (!fso.FolderExists(parentFolder))
    {
        if (!EnsureFolder(parentFolder))
            return false;
    }
    try
    {
        fso.CreateFolder(folderSpec);
    }
    catch(ex)
    {
        return false;
    }
    return true;
}

