I have written a custom dialog (form) that I can use in a C# program that behaves much like a "File - Open" menu command and brings up a window where a user can select a file or directory.
The question I have is this. It has "My Computer" as its root. How can I have it so that it searches on a Network? If the file or directory is located on a network.
Or better yet, in Visual Studio 2010, is there some sort of canned FileOpenDialog that I can use right away?
I tried calling the OpenFileDialog as described in the example code at
http://msdn.microsoft.com/en-us/library/system.windows.forms.openfiledialog.aspx
but the compiler does not seem to like DialogResult.OK as used in this line of code:
if(openFileDialog1.ShowDialog() == DialogResult.OK)
The compiler says:
Error 1 'System.Nullable' does not contain a definition for 'OK' and no extension method 'OK' accepting a first argument of type 'System.Nullable' could be found (are you missing a using directive or an assembly reference?)
I tried using the namespace Microsoft.Win32 instead of System.Windows.Forms and neither worked. They both produced this error.
Looks like you are trying to use a WinForms (System.Windows.Forms) dialog.
Here is the MSDN page for WPF dialog boxes from the Microsoft.Win32 namespace.
An excerpt:
Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
dlg.FileName = "Document"; // Default file name
dlg.DefaultExt = ".txt"; // Default file extension
dlg.Filter = "Text documents (.txt)|*.txt"; // Filter files by extension
// Show open file dialog box
bool? result = dlg.ShowDialog();
EDIT: missed the WPF tag. My bad. What Henk Holterman said.
Have you added the namespace that the example tells you to: System.IO?
I might be wrong, but it sounds like you have created a variable called DialogResult which is of type System.Nullable
Related
I've exhausted every resource possible and can not figure out what the issue is. Button images won't show & keep getting this message when I try to use the command.
Failed to initialize the [add-in name] because the assembly [path to an add-in DLL file] does not exist
when launching Revit. Here's my code that I'm using.
#region Namespaces
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.CSharp;
using System.Media;
using System.Reflection;
using System.IO.Packaging;
using System.Windows.Media.Imaging;
using System.Drawing.Imaging;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.Revit.UI.Selection;
using Autodesk.Revit.DB.Architecture;
#endregion
namespace TpMechanical
{
internal class App : IExternalApplication
{
public Result OnStartup(UIControlledApplication a)
{
String tabname = "TpMechanical";
String panelname = "Tools";
//Option 1
BitmapImage b1Image = (System.Windows.Media.Imaging.BitmapImage)TpMechanical.Properties.Resources.ResourceManager.GetObject("_design3_fhY_icon.ico");
BitmapImage b2Image = (System.Windows.Media.Imaging.BitmapImage)TpMechanical.Properties.Resources.ResourceManager.GetObject("_design3_fhY_icon.ico");
BitmapImage b3Image = (System.Windows.Media.Imaging.BitmapImage)TpMechanical.Properties.Resources.ResourceManager.GetObject("_design3_fhY_icon.ico");
//Option 2
//Bitmap b1Image = (System.Drawing.Bitmap)(TpMechanical.Properties.Resources.ResourceManager.GetObject("Icon1.ico"));
//Bitmap b2Image = (System.Drawing.Bitmap)(TpMechanical.Properties.Resources.ResourceManager.GetObject("Image1.jpg"));
//Bitmap b3Image = (System.Drawing.Bitmap)(TpMechanical.Properties.Resources.ResourceManager.GetObject("Image2.bmp"));
//Option 3
//BitmapImage b1Image = new BitmapImage(new Uri("pack:application:,,,/TpMechanical/Resources/Icon1.ico"));
//BitmapImage b2Image = new BitmapImage(new Uri("pack:application:,,,/TpMechanical/Resources/Image1.jpg"));
//BitmapImage b3Image = new BitmapImage(new Uri("pack:application:,,,/TpMechanical/Resources/Image2.bmp"));
a.CreateRibbonTab(tabname);
var Tools = a.CreateRibbonPanel(tabname, panelname);
var button1 = new PushButtonData("TpButton1", "Button1", Assembly.GetExecutingAssembly().Location, "TpMechanical.command");
button1.ToolTip = " This is a short description";
button1.LongDescription = "This is a long description \n " +
"this is the second line";
var btn1 = Tools.AddItem(button1);
button1.Image = b1Image;
var button2 = new PushButtonData("TpButton2", "Button2", Assembly.GetExecutingAssembly().Location, "TpMechanical.command2");
button2.ToolTip = " This is a short description";
button2.LongDescription = "This is a long description \n " +
"this is the second line";
button2.Image = b2Image;
var button3 = new PushButtonData("TpButton3", "Button3", Assembly.GetExecutingAssembly().Location, "TpMechanical.command3");
button3.ToolTip = " This is a short description";
button3.LongDescription = "This is a long description \n " +
"this is the second line";
button3.Image = b3Image;
Tools.AddStackedItems(button2, button3);
return Result.Succeeded;
}
public Result OnShutdown(UIControlledApplication a)
{
return Result.Succeeded;
}
}
}
I also have my manifest code below.
<?xml version="1.0" encoding="utf-8"?>
<RevitAddIns>
<AddIn Type="Command">
<Text>Command TpMechanical</Text>
<Description>Some description for TpMechanical</Description>
<VisibilityMode>AlwaysVisible</VisibilityMode>
<Assembly>C:\My Revit- Custom Files\01-Revit 2021\Revit 2021 Repos\TpMechanical\bin\Debug\TpMechanical.dll</Assembly>
<FullClassName>TpMechanical.Command</FullClassName>
<ClientId>9EDCBEA6-942A-4D9A-932D-612B5E02DC9C</ClientId>
<VendorId>com.typepad.thebuildingcoder</VendorId>
<VendorDescription>The Building Coder, http://thebuildingcoder.typepad.com</VendorDescription>
</AddIn>
<AddIn Type="Command">
<Text>Command TpMechanical</Text>
<Description>Some description for TpMechanical</Description>
<VisibilityMode>AlwaysVisible</VisibilityMode>
<Assembly>C:\My Revit- Custom Files\01-Revit 2021\Revit 2021 Repos\TpMechanical\bin\Debug\TpMechanical.dll</Assembly>
<FullClassName>TpMechanical.Command2</FullClassName>
<ClientId>1A164A1B-8B02-499A-8ADB-94A75557CD66</ClientId>
<VendorId>com.typepad.thebuildingcoder</VendorId>
<VendorDescription>The Building Coder, http://thebuildingcoder.typepad.com</VendorDescription>
</AddIn>
<AddIn Type="Command">
<Text>Command TpMechanical</Text>
<Description>Some description for TpMechanical</Description>
<VisibilityMode>AlwaysVisible</VisibilityMode>
<Assembly>C:\My Revit- Custom Files\01-Revit 2021\Revit 2021 Repos\TpMechanical\bin\Debug\TpMechanical.dll</Assembly>
<FullClassName>TpMechanical.Command3</FullClassName>
<ClientId>C5CEC594-E407-40A8-B1B0-163DAA179CDD</ClientId>
<VendorId>com.typepad.thebuildingcoder</VendorId>
<VendorDescription>The Building Coder, http://thebuildingcoder.typepad.com</VendorDescription>
</AddIn>
<AddIn Type="Application">
<Name>Application TpMechanical</Name>
<Assembly>C:\My Revit- Custom Files\01-Revit 2021\Revit 2021 Repos\TpMechanical\bin\Debug\TpMechanical.dll</Assembly>
<FullClassName>TpMechanical.App</FullClassName>
<ClientId>C12635D2-96E2-4DF4-B172-7BD9487F7AE9</ClientId>
<VendorId>com.typepad.thebuildingcoder</VendorId>
<VendorDescription>The Building Coder, http://thebuildingcoder.typepad.com</VendorDescription>
</AddIn>
</RevitAddIns>
enter image description here
Rereading your question a third time over, it sounds as if your add-in is trying to reference a .NET assembly DLL that cannot be found when Revit tries to load it. Looking at the list of namespaces that you reference in your source code using statements, I see nothing but standard Autodesk Revit, Microsoft and .NET assemblies listed. So, they should all be present and accessible. Are you using anything else elsewhere in your code that is not obvious from that list? You might be able to use tools like fuslogv to analyse your add-in dependencies during load time, as suggested in the note on Exploring Assembly Reference DLL Hell with Fuslogvw.
I suggest you try again with a minimal one-liner external command and a minimal one-liner add-in manifest.
Follow these steps: Revit developers guide add-in registration.
Ensure that Revit has read access to its AddIns folder.
Look at the Hello world walkthrough.
Do not say you exhausted all resources. That would take too long and probably exceed your life span. New resources are being added faster than you can consume them, so any attempt is doomed to fail.
The error message is telling you that the problem is not in the internal implementation code, but just in the basic registration.
Why do you add internal to the IExternalApplication implementation? Isn't that a contradiction? What does that mean?
Why do you use The Building Coder VendorId? That is incorrect. You are not The Building Coder.
Your Assembly path is complex and littered with spaces. In general, I try to avoid such complex paths and all spaces in folder names. I also prefer forward slashes to backward ones. You can omit the folder name entirely if you place the DLL in the same place as the add-in manifest in the AddIns folder.
I am being inundated with similar questions these days. Here is another similar one, a summary of a recent email thread:
[Q] I have dived into the Getting Started with Revit platform API, following the DevTV tutorial by Augusto Goncalves. None of my commands appear on the Revit UI > Add Ins > external commands.
[A] One thing you ought to read is the introductory section of the Revit API developers guide. It tells you exactly what to do to install and launch your add-in. It is shocking of that information is not clear and does not work in the tutorial, though. Thank you for bringing it up!
Installing a Revit add-in is really simple, but people run into difficulties like you describe anyway.
There are only two relevant components:
Add-in manifest file *.addin
.NET class library assembly DLL
These are the important steps:
The DLL must implement IExternalCommand; that means, it must implement the Execute method.
The add-in manifest must point to the DLL and must be placed in the Revit Add-Ins folder for Revit to find and load it.
If the DLL and add-in manifest both reside in the Revit AddIns folder, the full DLL path can be omitted; otherwise it must be specified.
That is really all.
There are thousands of places explaining it; they all say the same thing.
Good luck and lots of fun with the Revit API :-)
[R] I have not had any luck since yesterday about my add-in not appearing in the Revit external commands.
I have carefully structured my code correctly. The add-in manifest file is pointing to my project .dll file. My project class explicitly implements the IExternalCommand interface and fires up the Execute method just fine.
I don't understand what the issue could be, not sure it could be the revit version am using am trying to figure out all possibilities.
[R2] I managed to debug my code. Kindly, ignore previous message.
The location of my manifest add-in file was locked. I guess that was done when my account was set up. The location needed permission to be accessed. This path:
C:\ProgramData\Autodesk\Revit\Addins\2022\
I utilised the try and catch exception to see the issue.
Once I gave access permission, the add-in file is now visible; it worked!
I have a project written by someone else with .NET framework 4
I have a problem with one of the forms (others opening correctly).
When I try to open Form1 in "Design mode" Visual Studio 2017 shows the error screen and returns
"Failed to parse method 'InitializeComponent'. The parser reported the following error 'Invalid symbol kind: NamedType'. Please look in the Task List for potential errors."
with Call Stack
at Microsoft.VisualStudio.Design.Serialization.CodeDom.VSCodeDomParser.OnMethodPopulateStatements(Object sender, EventArgs e)
at System.CodeDom.CodeMemberMethod.get_Statements()
at System.ComponentModel.Design.Serialization.TypeCodeDomSerializer.Deserialize(IDesignerSerializationManager manager, CodeTypeDeclaration declaration)
at System.ComponentModel.Design.Serialization.CodeDomDesignerLoader.PerformLoad(IDesignerSerializationManager manager)
at Microsoft.VisualStudio.Design.Serialization.CodeDom.VSCodeDomDesignerLoader.PerformLoad(IDesignerSerializationManager serializationManager)
at System.ComponentModel.Design.Serialization.BasicDesignerLoader.BeginLoad(IDesignerLoaderHost host)
To add to the body of knowledge, I was getting this same error. My situation was I was upgrading a solution created by JetBrains dotPeek. Its solution versioned as 10.0 (VS2008) and converted to 15.0 (VS2015) for VS2017, and is a .NET 3.5 target class library. After opening the form up (in the old style with no designer file) it always threw the error when opening the designer (but running the class library was fine). On carefully reviewing every line of InitializeComponent, I found a "this.Name = nameof(formname)". Looking at another form that worked, I saw "this.Name = "formname"". Once I changed the line over to the other approach, the designer opened perfectly!
Go to InitializeComponent() function and search for nameof(). If found just replace value part to accurate value.
In my case it was
this.Text = nameof (Form1);
Changed to:
this.Text = "Page1";
This may also due to missing type(s) referred to in a not referenced assembly
Corrupt assembly (false signing or public key token mismatch of assemblies referred to). This is mostly due to version mismatches (strongly named assemblies) or patches of assemblies.
Please check the assemblies, clean, rebuild and see, if this error still shows up. Maybe restart Visual Studio.
Cheers
Make sure the correct System namespace is being referenced.
In my case I had a System folder in my project (so project.system namespace) that was confusing namespaces and causing these errors because System references inside InitializeComponent() were failing.
Another possible cause: the designer parser doesn't seem to recognize the C# curly braces initializer syntax:
Changed this:
this.myLabel = new Label { Name = "myLabel", Text = "My Label", Anchor = AnchorStyles.Left, AutoSize = true };
To this:
this.myLabel = new System.Windows.Forms.Label();
this.myLabel .Anchor = System.Windows.Forms.AnchorStyles.Left;
this.myLabel .AutoSize = true;
this.myLabel .Location = new System.Drawing.Point(3, 30);
this.myLabel.Name = "myLabel";
this.myLabel.Size = new System.Drawing.Size(38, 15);
this.myLabel.TabIndex = 1;
this.myLabel.Text = "My Label";
I am trying to run the following example from MSDN:
using System.Printing;
public class PrintTest {
public static void Main(string[] args)
{
// Create the printer server and print queue objects
LocalPrintServer localPrintServer = new LocalPrintServer();
PrintQueue defaultPrintQueue = LocalPrintServer.GetDefaultPrintQueue();
// Call AddJob
PrintSystemJobInfo myPrintJob = defaultPrintQueue.AddJob();
// Write a Byte buffer to the JobStream and close the stream
Stream myStream = myPrintJob.JobStream;
Byte[] myByteBuffer = UnicodeEncoding.Unicode.GetBytes("This is a test string for the print job stream.");
myStream.Write(myByteBuffer, 0, myByteBuffer.Length);
myStream.Close();
}
}
but the compiler is complaining
The type or namespace Printing does not exist in the namespace
System(are you missing an assembly reference) ?
How do I solve this issue ?
EDIT: How do I add a reference for command line compiled application ( Not Visual Studio)
From the command line something like csc /reference:lib\System.Printing.dll
Original Answer
Project > Add Reference, then under 'Assemblies > Framework'.
Choose System.Printing.
You can find out which Assembly you need to add a reference to by Googling the namespace followed by the word 'assembly'. In your case:
System.Printing assembly
The second result is from MSDN and indicates which assembly System.Printing can be found in.
From Command prompt
Create a public reference
/reference:[alias=]filename
/reference:filename
Where
Arguments
filename
The name of a file that contains an assembly manifest. To import more than one file, include a separate /reference option for each file.
alias
A valid C# identifier that will represent a root namespace that will contain all namespaces in the assembly.
Microsoft documentation page for cmd
From Visual Studio Community 2013 (Free version)
Right click References folder in your solution and browse for it there.
You are missing an assembly reference. Add a reference to System.Printing.dll.
You need to add the System.Printing assembly to your project.
You can find this by right clicking on your project and clicking "Add Reference". (You can search for it in the Assemblies > Framework tab)
Additionally, you must add using System.IO; in order to use Stream.
In your Solution Explorer right click on References click on Add Reference click on the .NET tab and scroll to System.Drawing. It should work.
Original answer found here:
https://social.msdn.microsoft.com/Forums/vstudio/en-US/0648fdc4-f67b-476e-b434-998efec14b89/class-systemprintingprintcapabilities-not-found?forum=wpf
However, you'll need to add the Assembly called ReachFramework
I make a ListView control (with some column header) in my window form but when I run this code then it gives me error just like that
Line in my Form.cs file:
string packagename =
File.ReadAllText(Program.ProjectLocation + "\\" +
Program.ProjectName + ".aProj");
Error 'System.Windows.Forms.ColumnHeader'
does not contain a definition for
'ReadAllText' and no extension method
'ReadAllText' accepting a first
argument of type
'System.Windows.Forms.ColumnHeader'
could be found (are you missing a
using directive or an assembly
reference?)
So please help me remove this error.
I think that the problem could be this: did you call your listview or a column File?
If so, correct: System.IO.File.ReadAllText(...);
It seems that File refers to a variable of type ColumnHeader and not the File class in System.IO
What you need to do is right click the word file and choose "Go to Definition", most probably you will find something like ColumnHeader File = new ColumnHeader();
Either
Program.ProjectLocation OR
Program.ProjectName
is type of System.Windows.Forms.ColumnHeader, Add
replace
Program.ProjectLocation.ToString()
Program.ProjectName.ToString()
I don't know which one is System.Windows.Forms.ColumnHeader so make changes according to that
EDIT ANSWER:
Either
Program.ProjectLocation
OR
Program.ProjectName
is type of System.Windows.Forms.ColumnHeader,
Reeplace it with
Program.ProjectLocation.ToString()
Program.ProjectName.ToString()
Reason: ReadAllText("A valid file path as string"); But here you are trying to generate a file path by using column header so its throwing that error
I don't know which one is System.Windows.Forms.ColumnHeader so make changes according to that
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;
}
}