Query for property CurrentEdition of Visio Application Object - c#

The visio application object can be controlled in c# programs via the assembly Microsoft.Office.Interop.Visio. The documentation of the visio application object 2010 is showing the property CurrentEdition:
http://office.microsoft.com/en-us/visio-help/HV080350129.aspx
However in my small c# application the property does not exist - although a reference to Microsoft.Office.Interop.Visio has been created. Now my question is how this property can be made accessible for an external application? In case the Interop assemblies are restricted do you know another assembly to get this done? Thanks!
using System;
namespace VisioTest
{
class Program
{
static void Main(string[] args)
{
Microsoft.Office.Interop.Visio.Application visioApp;
visioApp = new Microsoft.Office.Interop.Visio.Application();
if (visioApp.Application.CurrentEdition == Microsoft.Office.Interop.Visio.VisEdition.visEditionStandard)
{
// standard edition etc.
}
}
}
}

Related

Determine if library loaded into Console, Desktop, or UWP app

I have a libary which needs to behave differently for console applications, desktop application (e.g. WPF), and for UWP apps.
How can I determine at run-time into which application type my libary is loaded?
Determining if it is a console application seems easy: How to tell if there is a console
For UWP, I can probably determine if WinRT is loaded. But how?
What distinguishing attributes do desktop applications have?
I ended up defining following enum:
public enum ExecutionMode
{
Console,
Desktop,
UniversalWindowsPlatform
}
which is passed to the constructor of the main class of my libary. Not a new idea, but very reliable (if used correctly).
Create a CustomAttribute in an assembly that is available to all of the applications like so
using System;
namespace MyNamespace.Reflection {
[System.AttributeUsage(AttributeTargets.Assembly)]
public class ApplicationTypeAttribute : Attribute {
public enum ApplicationTypes {
Console,
Desktop,
UWP,
ClassLibrary
}
public ApplicationTypeAttribute(ApplicationTypes appType) {
ApplicationType = appType;
}
public ApplicationTypes ApplicationType { get; private set; } = ApplicationTypes.Console;
}
}
Then add this attribute to your AssemblyInfo.cs file for a console application
using MyNamespace.Reflection;
[assembly: ApplicationType(ApplicationTypeAttribute.ApplicationTypes.Console)]
or a Desktop application
[assembly: ApplicationType(ApplicationTypeAttribute.ApplicationTypes.Desktop)]
etc.
Then wherever you want to check the calling type of the application that was started, use this
using MyNamespace.Reflection;
var assy = System.Relection.Assembly.GetEntryAssembly();
var typeAttribute = assy.GetCustomAttribute(typeof(ApplicationTypeAttribute));
if (typeAttribute != null) {
var appType = ((ApplicationTypeAttribute)typeAttribute).ApplicationType;
}
There is one caveat to this method. .NET Core apps have a different project structure and the AssemblyInfo.cs file is auto-generated at build time by default. You can override this behavior by specifying the following in the .csproj file in the Project node.
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
To match the old project file structure, you can create a Properties directory in the project directtory and then you can add an AssemblyInfo.cs file to that directory. Otherwise you can place the Custom Attribute definition in any file (after the usings and before the namespace declaration).

How to SetTransObject to Sybase DataWindow in Visual Studio .NET WPF C# Application

I have a WPF C# Application. I'm using a Sybase.PowerBuilder.WPF.Controls.DataWindow, but I don't know how to use SetTransObject.
This is some of my code:
using Sybase.PowerBuilder.WPF.Controls;
partial class xxx
{
public xxx()
{
Sybase.PowerBuilder.WPF.Controls.DataWindow DW_1 =
new Sybase.PowerBuilder.WPF.Controls.DataWindow();
DW_1.DataObject = "eee";
DW_1.SetTransObject();
}
}
That control really isn't intended to be used outside of the PowerBuilder.Net environment. I can imagine that you'd run into a number of issues trying to use it directly from VS.Net. In this particular instance, SetTransObject takes a PowerBuilder.Net database connection object. You might be best service by creating a visual user object in PowerBuilder.Net and then using that from VS.Net.

Using Reflection to use a namespace on certain OSs

I'm creating a program that uses the CodeProject CoreAudioApi (pretty popular framework for manipulating audio), but the problem is the CoreAudioApi uses system calls that aren't available in any versions of Windows earlier than Vista. If I run a program with CoreAudioApi compiled with it (using a using statement as normal), the program will crash on anything earlier than Vista.
I've created this function to get the version number of the current environment:
win_version = Environment.OSVersion.Version.Major;
That returns the major version number I need. '6' is Vista/7, anything else is not, which is all I need to determine. Utilizing this, I need to determine whether or not to include the CoreAudioApi namespace if the OS is over or equal to '6'. From research, usings need to be compiled with the program, but I've also read about something called Reflection - which might be what I need.
Once I get the CoreAudioApi namespace using'd (sorry for the lack of terminology), the rest is easy. How can I do this?
TL;DR
I need some form of code that would effectively do this:
using System;
using System.Text;
//etc
if(currentWindowsVersion>=6) using CoreAudioApi;
Except control structures won't work outside of a class, and all namespaces are compiled with the program, not controlled individually.
Thanks!
EDIT: So far, I'm using this to load the CoreAudioApi namespace as a compiled assembly:
if(win_version>=6){
CoreAudioApi = Assembly.LoadFrom("CoreAudio.dll");
CoreAudioApi.GetLoadedModules();
CoreAudioApi.GetTypes();
MessageBox.Show("Loaded CoreAudioApi");
}
From here, what I need to do is actually use the types, and methods from the API. My code that works on Windows Vista/7 is this:
public static MMDeviceEnumerator devEnum;
public static MMDevice defaultDevice;
//later in a mute method:
defaultDevice.AudioEndpointVolume.Mute = true/false;
I don't even really need devEnum AFAIK, so really the only important lines are the last two (besides the comment).
I've just tried the following:
Create a new console application project
Add the CoreAudioApi project from CodeProject to the solution
Add a project reference to CoreAudioApi in my console app
Create the following classes:
interface IAudio { void SetVolume(float level); }
class XpAudio : IAudio {
public void SetVolume(float level) {
// I do nothing, but this is where your old-style code would go
}
}
class VistaAudio : IAudio {
public void SetVolume(float level) {
MMDeviceEnumerator devEnum = new MMDeviceEnumerator();
MMDevice defaultDevice = devEnum
.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia);
defaultDevice.AudioEndpointVolume.MasterVolumeLevel = level;
}
}
class Program {
static void Main(string[] args) {
IAudio setter = Environment.OSVersion.Version.Major >= 6
? (IAudio)new VistaAudio()
: (IAudio)new XpAudio();
float val = float.Parse(Console.ReadLine());
setter.SetVolume(val);
Console.ReadLine();
}
}
This runs on both my server (~ Windows 7) and local (Windows XP) machines. On my XP machine it'll happily take in a value and ignore it; on my server, it throws an exception, (presumably because I don't have a sound output). If I make my XP machine run the CoreAudioApi, I get an exception when I input a value, not before.
The question is, what are you doing differently to make your application break? Are you using CoreAudioApi code at startup?
EDIT: After seeing your edit, if you do this, you shouldn't need to mess about with Assembly.LoadFrom at all. The framework should dynamically load that assembly if (and only if) and when it needs to.
COREAUDIOAPI.dll does not work on XP or earlier, because they cant handle MMDEVICE API (Device Enumeration). I dont know about Vista.

How To Connect C# with ACAD 2010

Work on vs2008 C#, Need help to connect with autocad 2010, I follow the following steps to connect but it gives me an error.
I have to add a reference, so I go to references>>add reference>>[COM TAB]>>Autocad 2010 type library>>[OK]
I use two libraries:
using Autodesk.AutoCAD.Interop;
using Autodesk.AutoCAD.Interop.Common;
And then I use the following code to connect with AutoCAD 2010:
namespace Sample_CSharp_Acad_connect
{
class Program
{
private static IAcadApplication oAcadApp = null;
private static string sAcadID = "AutoCAD.Application.18";
static void Main()
{
try //get a running AutoCAD instance if avaialbale
{
oAcadApp = (IAcadApplication)System.Runtime.InteropServices.Marshal.GetActiveObject(sAcadID);
}
catch(Exception) //none found so start a new instance
{
System.Type AcadProg = System.Type.GetTypeFromProgID(sAcadID);
oAcadApp = (IAcadApplication)System.Activator.CreateInstance(AcadProg);
}
if (oAcadApp != null)
{
oAcadApp.Visible = true; //could leave this false to hide Acad from the user
//do whatever with Acad
//oAcadApp.Quit();
}
}
}
Error message : error in getting object class COM for component CLSID
COM? Don't do it.
AutoCAD has a .NET API. See http://usa.autodesk.com/adsk/servlet/index?id=1911627&siteID=123112 for resources from Autodesk. Also see the wiki here for more info and links galore: https://stackoverflow.com/tags/autocad/info
How do you run this code? Is it an exe file? As far as I know, it is not so easy to control AutoCAD using an external progam. There are often lizening issues which prevent such operations.
It might be easier to access AutocAD functionality using a DLL. In that case the object model of AutoCAD can be accessed directly:
Dim theApp as Autodesk.AutoCAD.Interop.AcadApplications = Autodesk.AutoCAD.Interop.AcadApplication()
Debug.Print(theApp.Caption)
The SDK contains a lot of samples for DLLs which can be loaded into AutoCAD.
And: If it isn't really necessary, consider using .NET!

C# Add-in: How do you access runtime instances of objects while debugging?

I am developing an add in for C# that would only be used during debugging. Once instantiated, my add in needs to find all instances of a specific class or interface to display a graph about the data found.
How exactly can I find or access these objects in my extension? I have access to the DTE2 application object in my extension, but I'm not sure how to search the actual code being debugged by VS. I'm thinking I might somehow be able to use Reflection, but I'm not sure where to look.
Thanks.
I've implemented a plugin that searches through dlls in a given directory and finds classes that implement a particular interface. Below is the class I used to do this:
public class PlugInFactory<T>
{
public T CreatePlugin(string path)
{
foreach (string file in Directory.GetFiles(path, "*.dll"))
{
foreach (Type assemblyType in Assembly.LoadFrom(file).GetTypes())
{
Type interfaceType = assemblyType.GetInterface(typeof(T).FullName);
if (interfaceType != null)
{
return (T)Activator.CreateInstance(assemblyType);
}
}
}
return default(T);
}
}
All you have to do is initialize this class with something like this:
PluginLoader loader = new PlugInFactory<InterfaceToSearchFor>();
InterfaceToSearchFor instanceOfInterface = loader.CreatePlugin(AppDomain.CurrentDomain.BaseDirectory);
This type of operation isn't really possible from a Visual Studio plugin. The object alive when debugging live in the debugee process while your add-in is running in the Visual Studio process. It's not possible to access arbitrary objects across process boundaries in .Net.

Categories