Change VS reload files behaviour - json

I am having one VSIX project, which will made some changes in Project.json file of ASPNET5 project. am using the following to edit .json file.
ProjectJson jsonObj = JsonConvert.DeserializeObject<ProjectJson>(jsonContents);
jsonObj = JsonConvert.DeserializeObject<ProjectJson>(jsonContents);
var resultJson = JsonConvert.SerializeObject(jsonObj, Formatting.Indented);
JsonSerializer serializer = new JsonSerializer();
using (StreamWriter sw = new StreamWriter(projectObjects.ProjectJsonPath))
{
var writer = new JsonTextWriter(sw);
serializer.Serialize(writer, resultJson);
}
// File.WriteAllText(projectObjects.ProjectJsonPath, resultJson);
by using both stream writer and writealltext am getting the following message in ASPNET 5 project
The file has unsaved changes inside this editor and has been changed
externally. do you want to reload it?
how to edit .json file without getting the above message?

Its actually the opposite. Since the environment thinks that the file wants to reload with unsaved changes.
You should uncheck the detect file changes. And when you do, it won't detect the external changes and will not warn you, beware though, that if you try to save the file after it has been modified you will lose the external change.(not a problem in your case I guess) and in order to see the changes you will have to close, not save the file and reopen it.
Source : VS2008: Disable asking whether to reload files changed outside the IDE

This is the option you want to check programmatically. I don't know how exactly you can do that but you can find topics about settings at MSDN (Creating an option page and Creating a setting category). Using those topics you can have a sense of how options are created.
Basically what you need to do is to load VS settings file (VS.vssettings) and inject another Xml line. (Have a look at Examining the Settings File section on MSDN)
Update
To be extremely clear the VS settings file is located under
Documents\Your_VS_Version\Settings\CurrentSettings.vssettings
and you need to load the xml and change 'AutoloadExternalChanges' to value 'true'.

You need to tell the environment to ignore file changes. This can be achieved using the IVsFileChangeEx and IVsDocDataFileChangeControl interfaces.
Here is a utility class (derived from the original Visual Studio 2010 SDK Managed Package Framework sample that you can still find here: http://www.getcodesamples.com/src/8641B4F/98B3955E) that should help:
using (SuspendFileChanges suspend = new SuspendFileChanges(site, filePath))
{
// do something with files
suspend.Sync(); // if you optionally want to tell the IDE it has changed
}
The utility class:
public class SuspendFileChanges: IDisposable
{
private readonly IServiceProvider _serviceProvider;
private readonly List<string> _urls;
private readonly IVsDocDataFileChangeControl[] _controls;
public SuspendFileChanges(IServiceProvider serviceProvider, string url)
: this(serviceProvider, new string[] { url })
{
}
public SuspendFileChanges(IServiceProvider serviceProvider, params string[] urls)
{
if (serviceProvider == null)
throw new ArgumentNullException("serviceProvider");
if (urls == null)
throw new ArgumentNullException("urls");
_serviceProvider = serviceProvider;
_urls = new List<string>(urls);
_controls = new IVsDocDataFileChangeControl[_urls.Count];
// or use Package.GetGlobalService ...
IVsRunningDocumentTable rdt = (IVsRunningDocumentTable)serviceProvider.GetService(typeof(SVsRunningDocumentTable));
IVsFileChangeEx fileChange = (IVsFileChangeEx)serviceProvider.GetService(typeof(SVsFileChangeEx));
for(int i = 0; i < _urls.Count; i++)
{
string url = _urls[i];
if (url == null)
continue;
fileChange.IgnoreFile(0, url, 1);
IVsHierarchy hierarchy;
uint itemId;
uint docCookie;
IntPtr docData;
rdt.FindAndLockDocument((uint)_VSRDTFLAGS.RDT_NoLock, url, out hierarchy, out itemId, out docData, out docCookie);
if (docData != IntPtr.Zero)
{
_controls[i] = Marshal.GetObjectForIUnknown(docData) as IVsDocDataFileChangeControl;
if (_controls[i] != null)
{
_controls[i].IgnoreFileChanges(1);
}
Marshal.Release(docData);
}
}
}
public void Sync()
{
IVsFileChangeEx fileChange = (IVsFileChangeEx)_serviceProvider.GetService(typeof(SVsFileChangeEx));
if (fileChange == null)
throw new InvalidOperationException();
foreach (string url in _urls)
{
if (url == null)
continue;
fileChange.SyncFile(url);
}
}
public void Dispose()
{
IVsFileChangeEx fileChange = (IVsFileChangeEx)_serviceProvider.GetService(typeof(SVsFileChangeEx));
if (fileChange != null)
{
foreach (string url in _urls)
{
if (url == null)
continue;
fileChange.IgnoreFile(0, url, 0);
}
}
foreach (IVsDocDataFileChangeControl control in _controls)
{
if (control != null)
{
control.IgnoreFileChanges(0);
}
}
}
}

Related

Automatically generating JSON script files from file name

I'd like to use a JSON file as a template to create new JSON files with a couple of words in the script that change according to the file name.
For example, say I have a JSON file called word1.json, with a script looking like this:
filename: word1.json
script:
{
"name": "word1",
"annotates": "word1.wav",
"sampleRate": 44100
}
I want to automatically generate a new JSON script for every file name I enter, for example:
filename: word2.json
script:
{
"name": "word2",
"annotates": "word2.wav",
"sampleRate": 44100
}
filename: newword.json
script:
{
"name": "newword",
"annotates": "newword.wav",
"sampleRate": 44100
}
and so on.
Is there some software that allows me to do it? I'm currently editing the JSON files with TextEdit - I'm not a programmer as you can probably tell, but I can use R and can do a little bit of programming there.
EDIT: I'm on MacOS
Many thanks.
I'll probably get some hate here, but since you are new, you are not a programmer, and it's a simple request I say 'Everybody gets one'.
This is a C# program that can be run in any compatible IDE. If you do not have one installed, you can run using LinqPad. It's a quick and simple installation. Open LinqPad and run as C# Program. Press the Play button start the program.
You will need to add the NuGet "Newtonsoft.Json".
This program will create a new directory on your hard drive at C:\jsonfiles. It will repeatedly ask you to enter in a file name until you enter in 'exit' at which point the program will exit. Rerun as needed.
void Main()
{
Console.WriteLine("JSON Creator");
Console.WriteLine("For each entered file name a JSON file will be created. The files will be created at C:/jsonfiles. If the file already exists it will be overwritten.");
Console.WriteLine("Enter 'exit' to end the program");
string jsonDirectory = #"C:\jsonfiles";
CreateBaseDirectory(jsonDirectory);
string jsonFileName = GetUserInput();
while (QuitProgram(jsonFileName) == false)
{
string fullJsonPath = System.IO.Path.Combine(jsonDirectory, jsonFileName + ".json");
try
{
DeleteExistingFile(fullJsonPath);
}
catch (IOException ioException)
{
Console.WriteLine("Unable to delete file. The file may be in use. Please close the file or manually delete the file before continuing on.");
jsonFileName = GetUserInput();
continue;
}
try
{
SaveToFile(jsonFileName, fullJsonPath);
}
catch (Exception ex)
{
Console.WriteLine("There was an issue creating the file. Verify the file does not already exist, the file name is valid, the file is not open, and you have privileges to write to the file system");
jsonFileName = GetUserInput();
continue;
}
jsonFileName = GetUserInput();
}
}
private void CreateBaseDirectory(string jsonDirectory)
{
if (System.IO.Directory.Exists(jsonDirectory) == false)
{
System.IO.Directory.CreateDirectory(jsonDirectory);
}
}
private bool InputIsValid(string input)
{
return string.IsNullOrWhiteSpace(input) == false;
}
private bool QuitProgram(string input)
{
string modifiedInput = input?.Trim()?.ToLower();
return modifiedInput == "quit" || modifiedInput == "q" || modifiedInput == "exit";
}
private string GetUserInput()
{
Console.WriteLine("Please enter in the JSON file name");
string input = Console.ReadLine();
while (InputIsValid(input) == false)
{
Console.WriteLine("Please enter valid JSON file name. An empty or space-only file name is not valid.");
}
return input.Trim().Replace(".json", "");
}
private void DeleteExistingFile(string fullJsonPath)
{
if (System.IO.File.Exists(fullJsonPath))
{
File.Delete(fullJsonPath);
}
}
private void SaveToFile(string jsonFileName, string fullJsonPath)
{
StringBuilder builder = new StringBuilder();
JsonTemplate template = new JsonTemplate();
template.name = jsonFileName;
template.annotates = jsonFileName + ".wav";
System.IO.File.WriteAllText(fullJsonPath, Newtonsoft.Json.JsonConvert.SerializeObject(template));
Console.WriteLine(jsonFileName + " has been created");
}
private class JsonTemplate
{
public string name { get; set; }
public string annotates { get; set; }
public int sampleRate { get; set; } = 44100;
}
Edit
I just noticed that you are on MacOS. I do not have access nor much knowledge on programming through MacOS. At minimum, you will need to update the location as to where the directory is saved.

Exception on readerNew.GetEnumerator(), ResX file Could not find a part of the path

I have an app using windows forms that goes through all the resource files in a new release writes the name value and comment to a csv file. I am ResXResourceReader and the method GetEnumerator to create a IDictionaryEnumerator and go through each resource and add the key and value to a dictionary. Im getting exceptions on some files, for example:
{[System.ArgumentException: ResX file Could not find a part of the path 'C:\ibml\SoftTrac CaptureSuite\Utilities\TranslationUtility\TranslationUtility\bin\resources\accept.png'. Line 12017, position 5. cannot be parsed. ---> System.Xml.XmlException: Could not find a part of the path 'C:\ibml\SoftTrac CaptureSuite\Utilities\TranslationUtility\TranslationUtility\bin\resources\accept.png'. Line 12017, position 5. ---> System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\ibml\SoftTrac CaptureSuite\Utilities\TranslationUtility\TranslationUtility\bin\resources\accept.png'.
My code for this is below:
private List<object> GetNewResxStrings(List<object> NewlyAddedResxFiles)
{
bool breaker = true;
Dictionary<string, int> Exceptionslist = new Dictionary<string, int>();
foreach (var resxfile in NewlyAddedResxFiles)
{
breaker = true;
while (breaker)
{
using (FileStream fsNew = File.Open(resxfile.ToString(), FileMode.Open, FileAccess.ReadWrite, FileShare.None))
{
ResXResourceReader readerNew = new ResXResourceReader(fsNew);
try
{
IDictionaryEnumerator dictNew = readerNew.GetEnumerator();
while (dictNew.MoveNext())
{
NewFilesAddedToCurrentVersion.Add(dictNew.Key, dictNew.Value);
}
Dictionary<object, object> temp = new Dictionary<object, object>(NewFilesAddedToCurrentVersion);
NewUtilityResxDictionary.Add(fsNew.Name.ToString(), temp);
NameOfChangeNew.Clear();
NameOfChangeOld.Clear();
NewFilesAddedToCurrentVersion.Clear();
breaker = false;
}
catch (Exception E)
{
Exceptionslist.Add(E.ToString(), 1);
breaker = false;
break;
}
}
}
}
return NewlyAddedResxFiles;
}
I once had this error after I c/p a path from explorer. Turned out there was a hidden char in the path. Between C and : if I recall. Could that be the problem? Check in excel with MID or LEN.

How to direct an EDI file down a certain path in Control flow task

So I have an SSIS package that I am working on right now that requires something that I have yet to do. The package currently just has a For Each Loop container that stores the value of the file name it finds in the User::WatchFolder to a variable and then moves that file to another folder for a process to pick up. What I have been tasked with is augmenting this so that the process remains unchanged for .837 file that does not contain a certain set of character but redirecting the files that come through with the word 'RELAY' in them. From there I also need to open up this EDI file and replace the string '5010' with '5010R', save it and move to a separate folder.
I have moved data in a Data flow task based on certain criteria using a Conditional Split, but this is not data from a table or database, so I'm not sure if this can be accomplished in a Control Flow task. Also, I'm assuming that the string can be replaced via a Script Task, but I'm not sure (again) if this is something that would live in the Control flow or in some sort of Data Flow task.
This is what the package looks like thus far.
SSIS Package so far
EDIT: So far I have created a script task using C# to find and replace the values using ReadFile(FilePath) into a variable called FileContent and then doing a FileContent.Replace("someText","someOtherText")
and then writing the contents back to the file using StreamReader and StreamWriter. That part seems to work fine, but I'm not sure now how to move the file depending on whether it contains a certain value in the FileName.
public void Main()
{
String ErrInfo = "";
String FilePath = Dts.Variables["User::FileName"].Value.ToString();
try
{
String FileContent; //Variable to store File Contents
FileContent = ReadFile(FilePath, ErrInfo);
if (ErrInfo.Length > 0)
{
Dts.Log("Error while reading File " + FilePath, 0, null);
Dts.Log(ErrInfo, 0, null);
Dts.TaskResult = (int)ScriptResults.Failure;
return;
}
//FileContent Before Replace;
MessageBox.Show(FileContent);
//Find and Replace --> Modify WHERE clause
FileContent = FileContent.Replace(
"Relay5010 ",
"Relay5010R"
);
//FileContent After Replace;
MessageBox.Show(FileContent);
Dts.Variables["User::FileContent"].Value = FileContent;
//Write the contents back to File
WriteToFile(FilePath, FileContent, ErrInfo);
if (ErrInfo.Length > 0)
{
Dts.Log("Error while writing File " + FilePath, 0, null);
Dts.Log(ErrInfo, 0, null);
Dts.TaskResult = (int)ScriptResults.Failure;
return;
}
}
catch (Exception e)
{
Dts.Log(e.Message, 0, null);
Dts.TaskResult = (int)ScriptResults.Failure;
}
}
public String ReadFile(String FilePath, String ErrInfo)
{
String strContents;
StreamReader sReader;
try
{
sReader = File.OpenText(FilePath);
strContents = sReader.ReadToEnd();
sReader.Close();
return strContents;
}
catch (Exception e)
{
MessageBox.Show(ErrInfo);
ErrInfo = e.Message;
return "";
}
}
public void WriteToFile(String FilePath, String strContents, String ErrInfo)
{
StreamWriter sWriter;
try
{
sWriter = new StreamWriter(FilePath);
sWriter.Write(strContents);
sWriter.Close();
}
catch (Exception e)
{
MessageBox.Show(ErrInfo);
ErrInfo = e.Message;
}
}
#region ScriptResults declaration
/// <summary>
/// This enum provides a convenient shorthand within the scope of this class for setting the
/// result of the script.
///
/// This code was generated automatically.
/// </summary>
enum ScriptResults
{
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
};
#endregion
}
}
Truth is, I'd love to leave the existing files alone and let them run down their normal path and just divert the ones containing the "R" value and those can have the script task applied to them. Is there possibly a way other than another script task? I am just trying to see if SSIS lends me another tool so that this can be done in the most straight forward way possible
This is my first question posted as well so if there is something else I missed here, I won't be offended if it is pointed out!

View SharePoint 2010 list in JSON format

I am preparing to using Timeglider to create a timeline. One requirement is the data has to be in JSON format. One requirement for me is it needs to be client side as I do not have access to the servers or central admin.
When I try to do http://webname/_vti_bin/ListData.svc/listname I get an error for access permissions however when I issue it http://webname/subsite/_vti_bin/ListData.svc/listname I have no problem pulling data.
My situation is the list is on the TLD. I tried to follow this post How to retrieve a json object from a sharepoint list but it relates to SP 2007.
To implement pure JSON support in SharePoint 2007, 2010 and so on have a look at this project, http://camelotjson.codeplex.com/. It requires the commercial product Camelot .NET Connector to be installed on the server.
If you don't like to go commercial you can resort to the sp.js library, here is a small example I wrote, enjoy!
// Object to handle some list magic
var ListMagic = function () {
/* Private variables */
var that = this;
var clientContext = SP.ClientContext.get_current();
var web = clientContext.get_web();
var lists = web.get_lists();
/**
* Method to iterate all lists
*/
that.getLists = function () {
clientContext.load(lists);
clientContext.executeQueryAsync(execute, getFailed);
function execute() {
var listEnumerator = lists.getEnumerator();
while (listEnumerator.moveNext()) {
var l = listEnumerator.get_current();
// TODO! Replace console.log with actual routine
console.log(l.get_title());
}
}
function getFailed() {
// TODO! Implement fail management
console.log('Failed.');
}
};
/**
* Method to iterate all fields of a list
*/
that.getFields = function (listName) {
// Load list by listName, if not stated try to load the current list
var loadedList = typeof listName === 'undefined' ? lists.getById(SP.ListOperation.Selection.getSelectedList()) : that.lists.getByTitle(listName);
var fieldCollection = loadedList.get_fields();
clientContext.load(fieldCollection);
clientContext.executeQueryAsync(execute, getFailed);
function execute() {
var fields = fieldCollection.getEnumerator();
while (fields.moveNext()) {
var oField = fields.get_current();
// TODO! Replace console.log with actual routine
var listInfo = 'Field Title: ' + oField.get_title() + ', Field Name: ' + oField.get_internalName();
console.log(listInfo);
}
}
function getFailed() {
// TODO! Implement fail management
console.log('Failed.');
}
};
/**
* Method to get a specific listitem
*/
that.getListItem = function (itemId) {
var loadedList = lists.getById(SP.ListOperation.Selection.getSelectedList());
var spListItem = loadedList.getItemById(itemId);
clientContext.load(spListItem);
clientContext.executeQueryAsync(execute, getFailed);
function execute() {
// TODO! Replace console.log with actual routine
//spListItem.get_fieldValues()
console.log(spListItem.get_fieldValues()["Title"]);
}
function getFailed() {
// TODO! Implement fail management
console.log('Failed.');
}
};
/**
* Method to fake an init (optional)
*/
that.init = function () {
// Run any init functionality here
// I.e
that.getFields("Tasks");
};
return that;
};
// In case of no jquery use window.onload instead
$(document).ready(function () {
ExecuteOrDelayUntilScriptLoaded(function () {
var sp = new ListMagic();
sp.init();
}, 'sp.js');
});
Personally, I make HttpHandlers. I install them in the SharePoint isapi folder and the GAC and I can call them just like you might the owssvr.dll. http://servername/_vti_bin/myhttphandelr.dll
Pass it querystring variables or call it from jquery ajax. You can use the httpcontext and make a spcontext from it and have access to all sorts of information from the current location in SharePoint. Then you can javascriptserialize the objects and pass them as JSON. Looking for some code... Hang on... I can't put all the code but this should get you close. I use this to add a submenu to the context menu to allow a user to delete or rename a file if they uploaded it to a library and it is version 1.0 and to collect a file from a library and create a eml file with the selected file(s) as an attachment(s). We don't give our users delete privileges normally. Point being, you can now create a class with just the information you need from SharePoint and pass it as JSON. The only downfall I have with this, is iisreset is required if you make any changes to the dll.
I task schedule a iisreset every night at midnight anyway to keep it fresh and free from memory bloat. I come in the next day and my changes are there. The cool thing is, the spcontext has information about the current location in SharePoint from where it is called. So, http://servername/_vti_bin/myhttphandelr.dll vs http://servername/subsite/library/_vti_bin/myhttphandelr.dll
I might add. Don't try to serialize SharePoint objects. One they are huge, complex objects. Two, I don't think they are marked serializable. Just make you own class and populate it with the values you need from the SharePoint objects.
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices.ComTypes;
using System.Web;
using System.Web.Script.Serialization;
using ADODB;
using interop.cdosys;
using Microsoft.SharePoint;
namespace owssvr2
{
public class OWSsvr2 : IHttpHandler, System.Web.SessionState.IRequiresSessionState
{
private string cmd;
ctx ctx = new ctx();
private string currentuser;
private SPContext SPcontext;
private HttpContext cntx;
public bool IsReusable
{
get { return false; }
}
public void ProcessRequest(HttpContext context)
{
SPcontext = SPContext.GetContext(context); <-- Gets spcontext from the httpcontext
cntx = context;
ctx = GetData(context.Request); <-- I parse some information from the request to use in my app
cmd = ctx.Cmd;
ctx.User = context.User.Identity.Name;
currentuser = context.User.Identity.Name;
switch (cmd)
{
case "Delete":
Delete();
context.Response.Redirect(ctx.NextUsing);
break;
case "HasRights":
HasRights();
JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
string serEmployee = javaScriptSerializer.Serialize(ctx);
context.Response.Write(serEmployee);
context.Response.ContentType = "application/json; charset=utf-8";
break;
case "Rename":
Rename(context);
//context.Response.Redirect(context.Request["NextUsing"]);
break;
case "SendSingleFile":
try
{
context.Response.Clear();
context.Response.ClearHeaders();
context.Response.BufferOutput = true;
ADODB.Stream stream = SendSingleFile(context.Request["URL"]);
stream.Type = StreamTypeEnum.adTypeBinary;
stream.Position = 0;
context.Response.ContentType = "application/octet-stream";
context.Response.AddHeader("content-disposition", "attachment;filename=Email.eml");
IStream iStream = (IStream)stream;
byte[] byteArray = new byte[stream.Size];
IntPtr ptrCharsRead = IntPtr.Zero;
iStream.Read(byteArray, stream.Size, ptrCharsRead);
context.Response.BinaryWrite(byteArray);
context.Response.End();
}
catch(Exception ex) {context.Response.Write(ex.Message.ToString()); }
break;
case "SendMultiFile":
try
{
//SendMultiFile(context.Request["IDs"]);
context.Response.Clear();
context.Response.ClearHeaders();
context.Response.BufferOutput = true;
ADODB.Stream stream = SendMultiFile(context.Request["IDs"]);
stream.Type = StreamTypeEnum.adTypeBinary;
stream.Position = 0;
context.Response.ContentType = "application/octet-stream";
context.Response.AddHeader("content-disposition", "attachment;filename=Email.eml");
IStream iStream = (IStream)stream;
byte[] byteArray = new byte[stream.Size];
IntPtr ptrCharsRead = IntPtr.Zero;
iStream.Read(byteArray, stream.Size, ptrCharsRead);
context.Response.BinaryWrite(byteArray);
context.Response.End();
}
catch(Exception ex) {context.Response.Write("There was an error getting the files. </br>" + ex.Message.ToString()); }
break;
case "FileInfo":
JavaScriptSerializer javaScriptSerializer1 = new JavaScriptSerializer();
string serEmployee1 = javaScriptSerializer1.Serialize(FileInfo(context));
context.Response.Write(serEmployee1);
context.Response.ContentType = "application/json; charset=utf-8";
break;
case "UsersInGroups":
UsersInGroups ug = new UsersInGroups(context, context.Request["job"],context.Request["groups"]);
break;
}
}

SSIS, EzAPI, Template

I am using the EzAPI to create SSIS packages via .NET, but when I load an existing package as a template that has existing components (sequence containers and execute SQL tasks etc) the EzExec collection is empty, while the DTS Executables collections has many members. I need to reference some of these existing components as parents and precedents to tasks I want to add to the package via the EzAPI.
Am I missing something in the initalization of the package, or is this even possible?
Below is a edited sample of the code I am attempting with the removal of layout info, this is still not working, count of Executables is 7, count of EzExexs is 0.
Thanks,
Andrew
public static EzPackage loadPackageTemplate(string templateLocation)
{
EzPackage ezPackage = new EzPackage();
try
{
StreamReader s = new StreamReader(templateLocation);
string templateContents = s.ReadToEnd();
s.Close();
templateContents = removeLayoutInformation(templateContents);
ezPackage.LoadFromXML(templateContents);
}
catch (Exception)
{
throw;
}
//need to remove layout from template
return ezPackage;
}
public static string removeLayoutInformation(string strXML)
{
try
{
//Remove the layout information.
while (strXML.IndexOf("<DTS:PackageVariable>") > -1)
{
strXML = strXML.Remove(strXML.IndexOf("<DTS:PackageVariable>"), strXML.IndexOf("</DTS:PackageVariable>") - strXML.IndexOf("<DTS:PackageVariable>") + 22);
}
}
catch (Exception)
{
throw;
}
return strXML;
}
public static EzExecutable GetExecutable(EzPackage ezPac, string identifier)
{
EzExecutable toReturn = null;
foreach (EzExecutable ezEx in ezPac.EzExecs)
{
if (ezEx.EzName == identifier)
{
toReturn = ezEx;
break;
}
}
return toReturn;
}
EzPackage pac = SSISGen.loadPackageTemplate(#"C:\Temp\SSISPackageTemplates\LoadFact.dtsx");
The problem is the layout data throws off the API. There's a discussion on the Codeplex site covering this problem. The poser, Josh Robinson, also blogged about his experience.
Anyways, the crazy thing about SSIS, the layout stuff BIDS/SSDT presents is bolted on to the actual package markup. That interferes with the ezapi stuff so the fix is to strip it out as Josh demonstrates.
Code copied here for future preservation
//Save the package object to XML
string strXML = null;
strXML = TestPackage.SaveToXML();
//Count instances of existing SSIS layout code in package.
int LayoutCount = Regex.Matches(strXML, "<DTS:PackageVariable>").Count;
//Remove the layout information.
for (int i = 0; i < LayoutCount; i++)
{
strXML = strXML.Remove(strXML.IndexOf("<DTS:PackageVariable>"), strXML.IndexOf("</DTS:PackageVariable>") - strXML.IndexOf("<DTS:PackageVariable>") + 22);
}