I have a pretty complex outlook addin that we have developed for our company.
The same users that use it in production are also the testers.
This leads to a lot of confusion and frustration as they have to uninstall the production version to test and then reinstall the production version when done testing. This is error prone as sometimes they forget to uninstall the test version. Also, The automatic updater will pick up the test version and install it on the non-testing user's outlook.
I would like the following:
Allow both test and production builds of the addin to be installed on the same person's outlook at the same time.
Use a different icon for the test version; perhaps just overlay "test" on the icon.
The addin communicates to web service so the test version will have to know to switch to the test URL.
What is a graceful way to achieve this?
You will be able to install same outlook addin twice:
1) By changing the AssemblyInfo.cs Title, Product and it's Guid.
e.g.
[assembly: AssemblyTitle("AddIn1")]
[assembly: AssemblyProduct("AddIn1")]
[assembly: Guid("d85cd50b-7e2f-4214-beaa-10698acdf6ed")]
2) You will also need to change the Assembly name from Application tab.
So by making two different projects with different icons loaded and with different assembly name you will be able to achieve this.
The C# compiler csc.exe and the C# language itself do not expose any predefined constants for conditional compilation. Visual Studio only adds the DEBUG and TRACE values, which can be configured through the IDE. The IDE also lets you add your own arbitrary symbols, but since these are essentially fixed (invariant) values, the capability is of limited use.
You can use conditional compilation in the following way - the DEBUG configuration can be used for testing the add-in:
#if DEBUG
[assembly: AssemblyTitle("TestAddin")]
[assembly: AssemblyProduct("TestAddin")]
[assembly: Guid("d85ca54b-7e1f-4214-beaa-10694acda6ed")]
#else
[assembly: AssemblyTitle("ReleaseAddin")]
[assembly: AssemblyProduct("ReleaseAddin")]
[assembly: Guid("d85cd50b-7e2f-4214-beaa-10698acdf6ed")]
#endif
Read more about assembly attributes in the Set assembly attributes article.
Related
I have a DLL written in C# and set for COM visibility. I have it setup as a side-by-side assembly and can successfully deploy the application to client PCs registration free. My question is related to the development PC. Is it possible to compile against the DLL in a similar registration-free manner or is registration required on the development machine? I have tried adding the DLL directly though the Project -> References menu and get an error stating "Can't add a reference to the specific file." The DLL is sitting in the same directory as the .vbp file and I have tried adding the DLL both with and without the client app manifest being present.
I have tried adding the DLL directly though the Project -> References menu
That adds a reference to a type library. A type library is a language-independent description of the types in a COM component, VB6 uses it to know how generate efficient code and to provide type checking and auto-completion. A type library is the exact equivalent of metadata in a .NET assembly.
Traditionally, and the way VB6 did it, the type library was embedded as a resource in a DLL. So you are probably used to picking a DLL in the dialog. That however doesn't work so well when the DLL is generated by C#, the type library can only be generated after the C# code is compiled. You have to pick the .tlb file in the VB6 dialog. The traditional way starts with the COM component being described in the IDL language, the type library can be generated before the code is compiled so can easily be embedded in the final DLL. It is technically possible to do it in C# as well, but the build steps are very laborious and painful, you essentially have to build the DLL twice with different build commands.
The type library for a C# library is normally generated in one of three ways:
Using Project + Properties, Build tab, "Register for COM interop" option. This requires VS to run elevated so it can write to the registry. You start VS elevated by right-clicking its shortcut and picking "Run as Administrator"
By running Regasm.exe, using the /tlb:filename option. An alternative for the 1st bullet and necessary if you don't want to run VS elevated for some reason. Using the /codebase option on your dev machine is also wise to make it work exactly like the 1st bullet and not require putting the DLL into the GAC with gacutil.exe
By running the Tlbexp.exe utility, the type library exporter for .NET assemblies. No registration is done, it only generates the .tlb file.
The first bullet is the normal choice and very desirable because you can never forget to update the type library this way. It is perfectly fine on a dev machine since you only really care about reg-free deployment on the user's machine. You probably got into trouble by not doing this anymore.
Using the 3rd choice is okay and more compatible with your goals, run Tlbexp from the Visual Studio Command Prompt. Just keep in mind that you have to do it again when you make changes to your C# code. Forgetting this once and losing clumps of head-hair trying to figure out why your C# changes don't seem to be effective or getting hard-to-diagnose error codes gives you lots of reasons to consider the 1st bullet again :) You can emulate the reg-free scenario by running Regasm.exe with the /uninstall option.
Please bear with me on this, since I am a Java developer just dipping a toe into the ASP.Net world
I started coding in an existing C# VS2012 codebase. It uses nuget and Newtonsoft is mentioned in the packages.config
When I right-click on Controllers > Add a new controller, I get the following error.
Could not load file or assembly 'nunit.framework, Version=2.2.4.0, Culture=neutral, PublicKeyToken=...' or one of its dependencies.
The system cannot find the file specified.
Now looking around in Google, it seems the GAC is missing an NUnit assembly. Not sure what I should do about that. Should I get NUnit? Why is it looking for a certain version of nunit (& that too a very old one)?
Any help for me to resolve this problem will be highly appreciated!
When you click "Add new Controller' Visual Studio will try to complete the parse/build to populate a number of values in the window that it is supposed to show you (with the available Models and available Views). It looks like at least one of your projects is missing a dependency (probably your Unit Test project).
NUnit 2.2.4.0 is indeed a pretty old version, it doesn't even exist on NuGet yet (which would have been an easy fix). It makes sense that NUnit is not installed in the GAC, since you normally don't put everything in the GAC just because it seems to be possible. If you're willing to upgrade to the latest NUnit version, the easiest way is to add the NUnit NuGet package to your project through the Package Manager.
I would assume that when you'd open the project file for the project that is generating this warning in Notepad, you'd see a <hintpath> tag as a sibling of the NUnit Reference (it may not be there) which points to the folder where it is telling Visual Studio to look for NUnit.
I suggest you install the NUnit version your project is looking for from here and then update the reference in your project to point to the correct location. That should fix the issue.
As for your remark on the specific version, .NET Assemblies are compiled with a specific version number (usually set in the AssemblyInfo.cs) a reference in a project file can be to a specific version or to any assembly with that name (highlight the reference in the Solution Explorer and check the properties window (ctrl+w,p or alt+enter). You'll see a property "Specific Version" which in your case is set to "true" which caused Visual Studio to store the assembly version in the project file.
Add the code files into a workable solution project.
It is workable for me.
Or, try to create a new Nunit test project with the codes
I also try the following method, but not working for me
Install Nunit, adapter, SDK from the Nuget package
Clean-Rebuild
I use API to make a programs. It runs pretty well on Windows 7 (with debug file .exe), but it doesn't when I run it on Windows XP. Are there any ways to solve this problem?
I suppose you are using Visual C++, according the the message you get.
Your project is set up (by default) to link the Microsoft C++ Runtime Librairy dynamically, so it saves up space in your final executable, but you need the dynamic linked libraries to be in your system or in your executable's folder.
To solve this in Visual C++, without any afford from who are executing the program in their machines, you can change how MSVC link their runtime library to your executable, that is, if you set it to be linked statically, all the dependencies will be linked inside your final .exe, with no need of additional .dlls.
To change this option, refer to /MD, /MT, /LD (Use Run-Time Library) - MSDN.
Or in short: Project Properties>Configuration Properties>C/C++>Code Generation>Runtime Library
If in debug mode, use /MTd, otherwise use /MT.
For Noda Time version 1.1, the main goal is to build a Portable Class Library flavour, primarily to support Windows Phone and Windows Store apps. This means losing some functionality, so we build a desktop configuration and a PCL configuration (for each of debug, release, and "signed release").
To avoid having to work with umpteen project files, all of the 6 configurations exist in the same project file. The project file is customized to generate a property called "Portability", which is set to either "PCL" or "Desktop", like this:
<!-- Set the custom Portability property based on configuration -->
<PropertyGroup>
<Portability Condition="'$(Configuration)' == 'Debug Portable'">PCL</Portability>
<Portability Condition="'$(Configuration)' == 'Release Portable'">PCL</Portability>
<Portability Condition="'$(Configuration)' == 'Signed Release Portable'">PCL</Portability>
<!-- Default to desktop if not explicitly set above -->
<Portability Condition="'$(Portability)' == ''">Desktop</Portability>
</PropertyGroup>
We then have separate property groups for portable vs desktop, based on the above property. This is what defines the project type as "class library" or "portable class library" (along with the OutputType of Library, which is shared):
<!-- Desktop-specific properties -->
<PropertyGroup Condition="'$(Portability)' == 'Desktop'">
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
</PropertyGroup>
<!-- PCL-specific properties -->
<PropertyGroup Condition="'$(Portability)' == 'PCL'">
<MinimumVisualStudioVersion>10.0</MinimumVisualStudioVersion>
<ProjectGuid>{c78f6992-28d7-45c9-a4c1-6eaa649f3247}</ProjectGuid>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkProfile>Profile2</TargetFrameworkProfile>
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
</PropertyGroup>
This generally works very well - I have the different solution configurations, so I can build and test everything at a moment's notice, and I only need to add each new .cs file to a single project file. So under Visual Studio 2012 Professional (which is what I use) I'm perfectly happy.
The problem comes when I try to load the solution in Visual Studio Express (either VS2010 or VS2012). While the solution is loading, it fails with an error to say that some projects can't be loaded, and the two projects which build PCL versions then have build output like this:
C:\Path\To\NodaTime.csproj : error :
The project file 'C:\Path\To\NodaTime.csproj' cannot be opened.
There is a missing project subtype.
Subtype: '{786C830F-07A1-408B-BD7F-6EE04809D6DB}'
is unsupported by this installation.
(Reformatted for clarity.) The two projects refuse to load, so you can't even browse the source code.
I had really hoped that even if Express users couldn't build the PCL versions, they'd still be able to load up the solution, browse the source, and build non-PCL versions. MSBuild works from the command line, but that's not as friendly.
I've tried removing the solution configurations which refer to the PCL project configurations, and that doesn't help. Weirdly enough, even commenting out the XML element, like this:
<!--
<ProjectTypeGuids>(Guids as before)</ProjectTypeGuids>
-->
doesn't help - although deleting the line does. It's as if Visual Studio isn't actually loading it as a real XML file. (I haven't tried loading the version with the commented out element into VS Pro.)
I could go down the route of generating separate PCL project files if I need to, but I'd really like to avoid it if possible - it would make normal development more painful. Likewise I could generate Express-only PCL and solution files, but again I'd rather not - it just feels wrong.
While ideally I'd like to support VS Express both 2010 and 2012, if there's a solution which only works for 2012, that would be a good start.
So, is there any way of persuading Visual Studio Express that it really can load a project despite a conditional property group (whose condition isn't met) referring to a project type it doesn't know about?
David Kean's comment here gave me the answer I'm using for the moment:
or remove the <ProjectTypeGuid> element entirely - this will opt you of "portable" enhancements, such as a UI for changing the target framework, etc
I've tried that, and it works like a dream. On machines which have everything appropriately installed, you can then even build the PCL version under Express! I've verified that the resulting binary really is a PCL, and it seems fine.
I wouldn't be surprised to find that I ran into some problems later on, but for the moment this works fine for me. I can easily live without the enhancements in Visual Studio - it was already confused by my project having very different build configurations, so I don't think I was getting much benefit anyway.
As answered here:
Visual Studio 2012 Express with Portable Class Library?
and here:
Share functionality using Portable Class Libraries
Portable Class library projects are not supported in the express
SKU...need a higher SKU for the full support. Of course the binary
(e.g., using it as a reference) is, just not the project/source
support.
I can imagine there is a simple reason for that - there are different types of VS2012 Express editions: for Windows Phone development, for Desktop apps, for Windows 8 apps... I bet the Windows Phone Express edition does not know about the Windows Phone project type and vice versa. This could be the simple reason why PCLs are not supported as well.
Although the idea of Portable Class Libraries is really nice, it's still quite limited in many ways, for instance you cannot use conditional compilation using #if xy as far as I know. If you really have to use Visual Studio Express for development, then it might be better to use projects for each platform with referenced source files and conditional compilation.
So far as I'm aware, most of the below types are now, and have always been, defined in mscorlib and/or System.dll.
However, in looking in the v4 framework directories (I have 4.5 installed, not sure if it also exists in Vanilla v4), I find an assembly called System.IO.dll.
Examining it in reflector, I can't see any actual code. All I can find are the following entries:
[assembly: TypeForwardedTo(typeof(BinaryReader))]
[assembly: TypeForwardedTo(typeof(BinaryWriter))]
[assembly: TypeForwardedTo(typeof(EndOfStreamException))]
[assembly: TypeForwardedTo(typeof(FileNotFoundException))]
[assembly: TypeForwardedTo(typeof(InvalidDataException))]
[assembly: TypeForwardedTo(typeof(IOException))]
[assembly: TypeForwardedTo(typeof(MemoryStream))]
[assembly: TypeForwardedTo(typeof(SeekOrigin))]
[assembly: TypeForwardedTo(typeof(Stream))]
[assembly: TypeForwardedTo(typeof(StreamReader))]
[assembly: TypeForwardedTo(typeof(StreamWriter))]
[assembly: TypeForwardedTo(typeof(StringReader))]
[assembly: TypeForwardedTo(typeof(StringWriter))]
[assembly: TypeForwardedTo(typeof(TextReader))]
[assembly: TypeForwardedTo(typeof(TextWriter))]
All pointing back to mscorlib (I think, haven't checked all of them). I've had a look around, and I can't see any framework version (e.g. silverlight, compact, etc) where these types aren't in mscorlib. So, does anyone know why this assembly exists (and why now)?
You found a reference assembly. That may sound odd, since you definitely don't use such a reference assembly in a .NET project that targets .NET >= 4.0. You normally get them from the C:\Program Files (x86)\Reference Assemblies directory on your dev machine. But that is not the only scenario in which a compiler is used. You also use a compiler when you use System.CodeDom in your program or depend on XML serialization.
Specific about System.CodeDom and XML serialization is that the compiler runs on your user's machine. And that you cannot target a specific .NET Framework version. Your user's machine does not have the targeting packs that your machine has. So its gets whichever version happens to be installed on the machine. The files in C:\Windows\Microsoft.NET\Framework\v4.0.30319 contains the reference assemblies that match that installed version. If the machine gets updated with another .NET 4.x release then those reference assemblies get updated as well.
Not the only possible scenario, likely that you'll also use them when you build from the command line. Or on a build server and decided to not pay for a VS license, very bad idea. Or in an ILMerge command, excessively bad idea. Those scenarios are a lot more troublesome. It works okay as long as the built assembly stays on the same machine. But not if they travel to another one machine, one that has a different framework version installed. That can produce pretty mystifying runtime exceptions, evident in this Q+A.
System.IO.dll is fairly exotic. You are only going to need it when you run System.CodeDom with a reference to a PCL assembly. Its primary role is to hide declarations, the kind that should not be used in the profile you picked. The System.IO namespace needs hiding because these types cannot be used when you target WinRT. But otherwise the reason that it doesn't contain any types, the [TypeForwardedTo] tells the compiler that the type is supported on a desktop machine and to look for the declaration elsewhere, mscorlib.dll