Hi guys,
Just wanted to share my hack to get debugging working in Visual Studio for Sound Forge.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using SoundForge;
using EnvDTE;
using Process = System.Diagnostics.Process;
#region readme
// BASIC C# Solution
// Demonstrates how to create a C# DLL that can be run from Sound Forge
// (scripting available in Sound Forge 8.0 or higher)
//
// Last Modified: 2016/10/19
// --------------------------------------------------------------------
// Environment used
// Windows 10 Version 1607 (OS Build 14393.321)
// Visual Studio Pro 2015 Version 14.0.25425.01 Update 3
//
//Use Visual Studio for debugging:
// SETUP
// Project properties
// Application
// Target framework
// .NET Framework 3.5 (newer frameworks weren't supported)
// Debug
// Start Action
// Start external program
// full path to Forge110.exe, including .exe
// i.e. "C:\Program Files (x86)\Sony\Sound Forge Pro 11.0\Forge110.exe"
// Start Options
// Working directory
// Your Visual Studio Debug folder
// i.e. C:\Users\<username>\Music\<solutionname>\bin\Debug\
//
// Project References
// Add References to project:
// Forge110.Script
// C:\Program Files (x86)\Sony\Sound Forge Pro 11.0\Forge110.Script.dll
// EnvDTE
// C:\Windows\assembly\GAC\EnvDTE\8.0.0.0__b03f5f7f11d50a3a\envdte.dll
// DEBUGGING
// 1. Rebuild your solution
// 2. Add breakpoints as desired
// 3. Start Debug (F5) to launch Sound Forge
// 4. Visual Studio will run to your first breakpoint
// 5. Exit Sound Forge to finish debugging
//-------------------------------------------------------------
#endregion
/// <summary>
/// Entry Point for Sound Forge
/// In order for Forge to run the C# DLL, the class EntryPoint MUST exist outside of the namespace
/// </summary>
public class EntryPoint
{
#region fieldDeclarations
public static IScriptableApp ForgeApp;
public const string SoundForgeProcessName = "Forge110";
public const string VisualStudio2015ProgId = "VisualStudio.DTE.14.0";
#endregion
public string Begin(IScriptableApp app)
{
#region HackToDebugSoundForgeInVisualStudio
// Get Visual Studio instance.
object dt = Marshal.GetActiveObject(VisualStudio2015ProgId);
DTE dte = (DTE) dt;
// Detach debugger from Visual Studio instance.
dte.Debugger.DetachAll();
// Wait for process to detach.
System.Threading.Thread.Sleep(1000);
// Get SoundForge process ID.
Process[] processes = Process.GetProcesses();
int? soundForgeProcessId = null;
foreach (Process process in processes)
{
if (!process.ProcessName.Equals(SoundForgeProcessName))
continue;
soundForgeProcessId = process.Id;
}
// Get SoundForge process.
EnvDTE.Process forgeProcess = null;
if (soundForgeProcessId != null)
{
forgeProcess = GetProcess((int) soundForgeProcessId);
}
// Visual Studio attach to SoundForge process.
forgeProcess?.Attach();
#endregion
// Set a breakpoint on the line below and run in debug.
Print("hello world");
return null;
}
#region HackToDebugSoundForgeInVisualStudioMethods
private static EnvDTE.Process GetProcess(int processID)
{
DTE dte = (DTE) Marshal.GetActiveObject(VisualStudio2015ProgId);
IEnumerable<EnvDTE.Process> processes = dte.Debugger.LocalProcesses.OfType<EnvDTE.Process>();
return processes.SingleOrDefault(x => x.ProcessID == processID);
}
#endregion
public static void Print(string output)
{
ForgeApp.OutputText(output);
}
public void FromSoundForge(IScriptableApp app)
{
ForgeApp = app;
app.SetStatusText(string.Format("Script '{0}' is running.", Script.Name));
string msg = Begin(app);
app.SetStatusText(msg != null ? msg : string.Format("Script '{0}' is done.", Script.Name));
}
}