foreach loop error message - c#

Anyone know why the following code:
foreach (Word.XMLSchemaReference reference in Globals.ThisDocument.Application.ActiveDocument)
{
}
Gives me:
Error 1 foreach statement cannot operate on variables of type
'Microsoft.Office.Interop.Word.Document' because
'Microsoft.Office.Interop.Word.Document' does not contain a public
definition for 'GetEnumerator' C:\Program Files\Microsoft
Office\Templates\Projects\Project1\Project1\ActionsPaneControl1.cs 1054 13 Project1
I have that code in an actionpane control in a Word document level project which has been created with VS2013 using C# .Net 4.0 for Word 2010.
I am trying to run the following code within that loop:
if (reference.NamespaceURI.Contains("ActionsPane"))
{
reference.Delete();
}
Basically, the documents created with my addin give the user a message when they reopen the created document:
One or more XML expansion packs are available for this file. Choose
one from the list below. No XML expansion pack Microsoft Actions Pane
3
So it seems I need to find the reference and delete it before the user saves the document?

The message is very clear: Globals.ThisDocument.Application.ActiveDocument does not implement IEnumerable. I think you are looking for something in the active document that implements a IEnumerable of XMLSchemaReference. Check the properties from the Globals.ThisDocument.Application.ActiveDocument.

You're trying to enumerate over ActiveDocument. Are you trying to enumerate over the XML schemas?
foreach (var schema In ActiveDocument.XMLSchemaReferences){
schema.dosomething
}

Related

unable to generate BIML for script component

I am trying to create a simple flow using the BIML <ScriptComponentProject> tag, but it does not work for me!
if I create the data flow manually, then it works perfectly fine!
my data flow has: SRC > SCRIPT-COMPONENT > TGT
the only logic that I have added is to calculate a row-number for each incoming row (keeping the logic absolutely simple for now)
when the manual solution is executed:
the sequential row-number is stored in the TGT table (test_np_02)
Great!
however, when I try to create absolutely the same package using the attached BIML, I get the following errors:
SSIS Output log:
Error 0 The namespace '<global namespace>' already contains a definition for 'Input0Buffer'. ...\Designer\BufferWrapper.cs 14 14
Error 0 The namespace '<global namespace>' already contains a definition for 'UserComponent'. ...\Designer\ComponentWrapper.cs 12 14
Error 0 The namespace '<global namespace>' already contains a definition for 'Connections'. ...\Designer\ComponentWrapper.cs 49 14
Error 0 The namespace '<global namespace>' already contains a definition for 'Variables'. ...\Designer\ComponentWrapper.cs 60 14
EmitSsis. Internal Compiler Error: Workflow EmitSsis contains fatal errors. Phase execution halted.
I am unsure what is going wrong when I try to create the PKG using BIML:
these errors never popped up when I created the package manually (with the same code)
I copy-pasted the important C# files from the manual solution into the BIML
Questions / Ideas:
is it something to do with the GUID that has to be used for ProjectCoreName, AssemblyProduct and AssemblyTitle?
is this automatically generated each time the BIML is expanded?
if so, how can I create a GUID in the BIML itself for these items .. so that it works directly after expansion?
is it something to do with the sequence in which I have to create the .cs files in the BIML, within the <Files> tag?
I currently assume that actual sequence of the <File> items within the <Files> tag is not relevant for BIML
could it be that I have to generate "Resources.resx/Resources.Designer.cs" and "Settings.settings/Settings.Designer.cs" as well in the BIML?
is it really important to have the "#region Namespaces" section in each .cs file?
I removed that from the manual soln .. that still worked fine !
Pls help.
Notes:
I am using SSDT 2015 and Varigence BIMLExpress 2017 (Build 5.0.61915.0)
I am aware that this could very easily be done using ROW_NUMBER() within SQLServer in the SRC itself, but:
I am using OleDbSource in the attached example just to keep it simple
finally, I will have to generate hundreds of code PKGs with BIML, which will have the SRC as a flat file, and not OleDB.
and obviously, I would love to have my generated ScriptComponents work immediately after expansion .. without any further manual interventions :)
Thanx,
NP
BIML file: https://drive.google.com/file/d/10O3aSL5IO34ULS44wl7IX4LUmPH_pI6V/view?usp=sharing
The error will disappear if you wrap your classes in a custom namespace.
namespace SomeNamespace {
public class UserComponent: ScriptComponent
{
...
}
public class Connections
{
...
}
public class Variables
{
...
}
}
namespace SomeNamespace {
public class Input0Buffer: ScriptBuffer
{
...
}
}
Also one remark about (dynamically) creating multiple packages from this Biml file: You will have to assign a dynamic namespace name like so:
namespace <#=variableContainingNamespaceName#> {
...
}
About your remarks:
The issue is not related to the ProjectCoreName, but I fear that you may run into issues if you reuse the same ProjectCoreName for multiple packages generated from the same biml (without having actually tested it)
No
Not necessary
No, the section is not necessarily required.

How to output a file from a roslyn code analyzer?

I'm using the roslyn API to write a DiagnosticAnalyzer and CodeFix.
After I have collected all strings and string-interpolations, I want to write all of them to a file but I am not sure how to do this the best way.
Of course I can always simply do a File.WriteAllText(...) but I'd like to expose more control to the user.
I'm also not sure about how to best trigger the generation of this file, so my questions are:
I do not want to hard-code the filename, what would be the best way to expose this setting to the user of the code-analyzer? A config file? If so, how would I access that? ie: How do I know the directory?
If one string is missing from the file, I'd like to to suggest a code fix like "Project contains changed or new strings, regenerate string file". Is this the best way to do this? Or is it possible to add a button or something to visual studio?
I'm calling the devenv.com executable from the commandline to trigger builds, is there a way to force my code-fix to run either while building, or before/after? Or would I have to "manually" load the solution with roslyn and execute my codefix?
I've just completed a project on this. There are a few things that you will need to do / know.
You will probably need to switch you're portable class library to a class library. otherwise you will have trouble calling the File.WriteAllText()
You can see how to Convert a portable class library to a regular here
This will potentially not appropriately work for when trying to apply all changes to document/project/solution. When Calling from a document/project/solution, the changes are precalcuated and applied in a preview window. If you cancel, an undo action is triggered to undo all changes, if you write to a file during this time, and do not register an undo action you will not undo the changes to the file.
I've opened a bug with roslyn but you can handle instances by override the preview you can see how to do so here
And one more final thing you may need to know is how to access the Solution from the analyzer which, Currently there is a hack I've written to do so here
As Tamas said you can use additional files you can see how to do so here
You can use additional files, but I know on the version I'm using resource files, are not marked as additional files by default they are embeddedResources.
So, for my users to not have to manually mark the resource as additonalFiles I wrote a function to get out the Designer.cs files associated with resource files from the csproj file using xDoc you can use it as an example if you choose to parse the csproj file:
protected List<string> GetEmbeddedResourceResxDocumentPaths(Project project)
{
XDocument xmldoc = XDocument.Load(project.FilePath);
XNamespace msbuild = "http://schemas.microsoft.com/developer/msbuild/2003";
var resxFiles = new List<string>();
foreach (var resource in xmldoc.Descendants(msbuild + "EmbeddedResource"))
{
string includePath = resource.Attribute("Include").Value;
var includeExtension = Path.GetExtension(includePath);
if (0 == string.Compare(includeExtension, RESX_FILE_EXTENSION, StringComparison.OrdinalIgnoreCase))
{
var outputTag = resource.Elements(msbuild + LAST_GENERATED_TAG).FirstOrDefault();
if (null != outputTag)
{
resxFiles.Add(outputTag.Value);
}
}
}
return resxFiles;
}
For config files you can use the AdditionalFiles msbuild property, which is passed to the analyzers through the context. See here.

Cloudberry Backup API: Listing Plan Items

I'm trying to list selected folder paths in all backup plans using the Cloud.Backup.API.dll and am not having much luck. I've given up trying to load the dll in powershell (using Add-Type returns 'Unable to load one or more of the requested types') and am instead writing a simple console application in C#. So far I have:
foreach (BackupPlan plan in BackupProvider.GetBackupPlans())
{
Console.WriteLine(plan.PlanItems);
}
However, PlanItems returns:
CloudBerryLab.Backup.API.BackupPlan+d__0
What exactly am I doing wrong?
For C# this will list paths:
foreach (string _item in plan.PlanItems)
{
Console.WriteLine(_item);
}

Get assembly name at compile time and use it in code [duplicate]

Is there a way to find out the assembly name at design-time (i.e. not using reflection or runtime APIs such as System.Reflection.Assembly.GetEntryAssembly) from within Visual Studio?
The scenario requires a tool to get the assembly name that a Visual Studio project will eventually compile into.
This is like parsing the AssemblyName property of the .csproj - I am wondering if there are any APIs that can give this information reliably.
Please do not respond back with runtime APIs that use reflection - there is no assembly file present at the time I need the assembly name - just the metadata of the assembly in the csproj file.
if you are calling the tool via a post/pre-build event, this data is very easy to access.
Just go to the "project properties->Build Events" tab, then select either "edit pre-build" or "edit post-build", depending on when you want the tool to run. This should bring up an edit window with the ever helpful "Macros >>" button. Press this and you will be given a heap of macros to use and should be pretty much everything you need.
The "API" you could use is LINQ to XML after all the .csproj file is just xml. (and you can get the location of the .csproj file if you need from the solution file which for some reason is not XML but can be easily parsed)
You can use "TargetName" available in Macros for Post-build events. It will give you the assembly name for your project.
After a quick run through MSDN I found this article which might be a good start for some further research:
Accessing Project Type Specific Project, Project Item, and Configuration Properties
I think you will need to write some regular expression that will give you the value of "AssemblyTitle" attribute in AssemblyInfo.cs file.
Something like this:
public class Assembly
{
public static string GetTitle (string fileFullName) {
var contents = File.ReadAllText (fileFullName); //may raise exception if file doesn't exist
//regex string is: AssemblyTitle\x20*\(\x20*"(?<Title>.*)"\x20*\)
//loading from settings because it is annoying to type it in editor
var reg = new Regex (Settings.Default.Expression);
var match = reg.Match (contents);
var titleGroup = match.Groups["Title"];
return (match.Success && titleGroup.Success) ? titleGroup.Value : String.Empty;
}
}

Rename classes using Visual Studio Project Template

I have created a Visual Studio template using this link: http://msdn.microsoft.com/en-us/library/ms185301.aspx.
I am able to create a dialog where the user enters a custom message and it gets displayed:
namespace TemplateProject
{
class WriteMessage
{
static void Main(string[] args)
{
Console.WriteLine("$custommessage$");
}
}
}
What I want to do it allow the user to rename the class names so I want to do something like:
But you see I'm getting errors of "Unexpected character $"
How can I do this?
EDIT
I see from this link: http://msdn.microsoft.com/en-us/library/eehb4faa(v=vs.110).aspx that
To enable parameter substitution in templates:
In the .vstemplate file of the template, locate the ProjectItem element that corresponds to the item for which you want to enable parameter replacement.
Set the ReplaceParameters attribute of the ProjectItem element to true.
BUT above I have not yet generated the template yet as I am still defining the classes. I understnad that the above step needs to be done in order to get the parameter substitution enabled for a File-->New Project scenario.
It looks like you have your template file as a cs file, which is causing Visual Studio to attempt to build it directly.
From what I can tell you should create a functioning Project, export it, and then modify the resulting template to add any replacements you need.

Categories