I have a C#/WPF app. I am trying to create different versions that will ship to different customers with their branding.
The branding is currently in the AssemblyInfo.cs, an icon, splash screen, exe name.
I thought I could create separate project configurations and then I thought I could just create separate AssemblyInfo.cs files for each customer.
But the project seems to only allow one assemblyinfo and does not allow this to be changed on a per configuration basis (e.g. it is the first tab in the Project Properties dialog).
Is a better way to somehow put the AssemblyInfo.cs info in a resource and then have multiple resource files, one for each customer, and have separate configurations that link in the different resource?
I was hoping then as I continued development, I could develop under the native branding and then just Batch Build all the release builds to produce the exes for each customer.
Any help or suggestions on how I can make a maintainable solution would be great.
The AssemblyInfo.cs file, while being a class file, doesn't actually have any class information in it, by default it simply contains attributes. You can use conditional compilation symbols around these attributes:
#if MY_SYMBOL
[assembly: AssemblyTitle("Tim's Magical Application")]
#else
[assembly: AssemblyTitle("Some Other Name")]
#endif
you can also use your own custom attributes in there.
But the project seems to only allow one assemblyinfo
This file resides in the Properties folder of the project. You can also have another .cs file sitting beside it with another list of attributes in it (i.e. AssemblyInfo.custom.cs). Any entries you change via the project properties dialog are reflected in the original AssemblyInfo.cs file, leaving your custom one untouched.
So if you decide to use attributes in the AssemblyInfo.cs to control the customer specific branding then you have a couple of ways to do it. Personally though I would have a neutral image loosely packaged, and use either my build process or installer build to include the appropriate branding images in the distributable package (replacing the neutral image).
Related
I am writing a very basic library in VB.NET
The library just contains classes and modules.
Now in built output I see this files
Application.Designer.vb
Application.myapp
AssemblyInfo.vb
Resources.Designer.vb
Resources.resx
Settings.Designer.vb
Settings.settings
Since I've seen other libraries with only AssemblyInfo.vb file, I was wondering if I can delete the rest.
What is the minimum of files I need here for the lib to work correctly, since I don't have any ressource or setting?
All the files you listed are necessary for a vb.net library project. And these files are generated (in My Project folder) when the project created not the build output files. So you need to keep all the files you listed in order to develop and build your project locally.
And for the files of build output, you can add these files in .gitignore.
When you create a project in VS, you select a predefined template that dictates what gets created. People often become accustomed to seeing the superfluous objects that a given template creates and assume that those objects are mandatory and must be there, However, much of it is not needed.
There is also the Empty Project template (the exact name of this template varies depending on the VS version used).
In VS2017, selection of the template would look like this:
This is a bare-bones project and the Solution Explorer will look like this:
As you can see, there are no pre-loaded references. You will need to add them yourself. About the only thing defined in this template is that you are using the VB language; This project starts out as a WinForm type, so go to the Project Properties->Application tab and change the "Application type" to "Class Library" since you want to create a library.
You may find it useful to start with an Empty Project and add the stuff you normally use and then export the project as new template (in VS2017: Project Menu->Export Template). For more on creating termplates, see: Creating Project and Item Templates
Edit: I just realized that I did not answer your real question about deleting the unused items. I just did a test case and deleted the items under MyProject. I received an error on deletion, but doing a clean/rebuild allowed me to proceed without issues. I would recommend that you backup the project before attempting this on an existing project, but I saw no long term issues in deleting unneeded objects from MyProject.
I would like to add into project some files that shouldn't be compiled. I mean mainly text files with for example notes, concepts, comments etc.
I realized that it is possible only at module level. But it is not very convenient. I'd rather prefer to keep them on project level. Is it possible in any way?
And if not:
I have another idea: to create special module, name it for example "other_stuff", do not create src directory and put files there. Is it ok? I'm afraid of potential compilation problems when one of modules is artificial, with no sources but still has sdk assigned (it is probably impossible to leave module without sdk assigned).
While generating artifacts you can add any file into your artifact. Also, in modules you can have folders not declared as source, and they will not be compiled.
I have a C# project which is built in a few different configurations. Some of the source files should be always included, and some only in certain configurations. So far I've been doing this with #if ... #endif around the entire files, but I was hoping to create a small extension to do this a nicer way.
I've created an extension that adds an item to files' context menus, but I can't find any way to set the Condition attribute on the item node in the project file.
I've looked at the Properties collection of the EnvDTE.ProjectItem interface, but can't see anything useful there (except BuildAction... I'll come back to that).
Then I tried getting an IVsBuildPropertyStorage on the item and calling SetItemAttribute(). This does add information to the project file, but as a child element like this:
<ItemGroup>
<Compile Include="Program.cs">
<Condition>%27%24%28Configuration%29%27==%27Debug%27</Condition>
</Compile>
</ItemGroup>
when what I was trying to achieve was:
<ItemGroup>
<Compile Include="Program.cs" Condition="'$(Configuration)'=='Debug'" />
</ItemGroup>
There's also an IVsBuildPropertyStorage.SetPropertyValue() but that adds a similar child element to a PropertyGroup section near the top, not to the item node.
I've looked at 'Project Subtypes/Flavors', but that looks like it's just going to get me another IVsBuildPropertyStorage, which doesn't seem to be useful. They do look capable of a lot of complex things, but documentation on the subject appears to be minimal and vague.
I've seen some posts describing how to use the MSBuild assemblies to directly load and manipulate the project file, but I'm not sure when is safe to do that without confusing Visual Studio and potentially losing changes, since VS prompts to reload when it detects changes to the project file.
As a last idea, I thought about manipulating the BuildAction property between Compile and None, but that sounds like it could be a lot of work for my extension to maintain correctly, keeping it in sync with every time the user switches configurations in the IDE for example.
Is there anyone with any experience with this kind of thing that has any advice to offer me, or should I give up hope and stick with manually adding #if directives everywhere?
You may like to explore the MSBuild option you mentioned.
You don't actually have to load the MSBuild project from file, because Visual Studio gives you a way of accessing the MSBuild project directly, i.e.:
string projectPath = projectItem.ContainingProject.FullName;
MsBuildProject project = ProjectCollection.GlobalProjectCollection.GetLoadedProjects(projectPath);
var compileItems = project.GetItems("Compile");
From there you can locate your specific items and potentially add the condition attribute, though I haven't tried this step myself (if this doesn't work, you might have to try modifying the project elements under the project.Xml property instead).
You can then call project.Save(), which shouldn't trigger the "Reload project?" dialog because of the way the MsBuild project instance is linked to the Visual Studio project hierarchy.
However, you may like to force Visual Studio to reload the project anyway, because if you switch build configurations (e.g. between Debug and Release), the MSBuild engine may not re-evaluate your item conditions during build. The code to do this programmatically can be found here:
How do I programmatically refresh/reload a VS project after modifying the underlying file?
Unfortunately I never got the time to persue the original goal of creating an extension for doing this, however I did achieve what I needed using the suggestion by lex-li: using separate project files per configuration.
Since the project files can all reside in the same directory, it's easy to simply use the 'Include/Exclude from project' context menu item in the solution explorer to choose which files are included. There's also no need for file linking this way, which I'd tried before and found very time-consuming to manage.
Partial Methods are also worth looking at, if you have similar needs. They allow you to define the signature of a method in one place, but optionally implement it elsewhere. If you don't implement it, no call is generated by the compiler.
With respect to the original idea of the extension, I suspect the answer by Daniel Nolan was heading in the right direction, but unfortunately I didn't get to try it out.
An iPad project I have been working on has become bloated with a huge number of files. The application is a prototype and we are considering ways to prevent this when we rewrite it.
One of the members of our team suggests dividing all of the components into separate Xcode projects which will be included in a master Xcode project.
Is this a good idea? What are the reasons, if any, to avoid dividing features/components/controls into separate Xcode projects?
You can add a subsidiary project file to a master project file in Xcode. Just choose "Add File" and add it. When Xcode builds the master it will build the subsidiary as well if needed.
I use a similar system. I often break a project into sub projects just so I can focus on and enforce encapsulation. I write the data model first, then add the app delegate, then specific UI elements. I add each project to the next in turn. This also allows me to go back and change things without as much risk of breaking.
Really, a properly designed objective-c app should be easy to decompose into multiple project. Ideally, all the components are so encapsulate that they don't need any others save the data model.
We have put some of the code in its own project, building a framework which we link against at some of the other projects. It's sometimes annoying that you won't see the implementation files of the framework code right away in another project (by cmd+clicking or cmd+shift+D, or whatever you do normally to navigate). Xcode will only show you the header, you'll have to open the other project and find your file there manually. Not a big deal, but if you look up the code often, it will bother you.
A real problem is that you change the scope of some operations. Stuff like "Find in project" will work on a different file set, which might not be what you want sometimes (trying to find where this method is called / key is used in your whole code, or something); well, there remains Finder / find, so it might be okay. Refactoring is not - all the renaming stuff just breaks, as it will change only the code of the current project, but not of projects referencing this one. If you change interfaces often, better avoid splitting up the project.
A good thing is that you will get less conflicts on your .xcodeproj files (if stored in a shared repository) as someone removing a file from project X won't create a conflict with someone else adding a target on project Y, which where previously the same .xcodeproj (not exactly sure this is a conflict case, but there definitely are some).
Now with Xcode4 you can create a workspace and add all your projects there. Only for documentation purpose :)
To view and modify subproject implementation files, you should add the sub projects directly into the main project.
1 step - Drag and drop the .xcode project files to main project.
2 step - Go to main project TARGETS - > Build Phases. Add subproject target in Target Dependencies. You can also add binary files in Link Binary With Libraries.
3 step - Add subproject source path to main projects header search path.
Go to main project - > Build Settings - > Header Search Paths (e.g $(SRCROOT)/../CoconutKit-master/CoconutKit/Sources )
An Xcode project can have any number of build targets within it, and you can arbitrarily group source files into folders. What makes you think that multiple projects are necessary?
I'm working with xcode and I have classes associated with other projects that I want to be included in new projects. I realize that the #import will do the job technically (although what should i do if it's out of the project root folder). But what do I do if I want to include the class "properly" --basically so i can double click and edit out of the main project window where you can see all your files and such.
I guess I'm just looking for the best and/or proper way to include/import (into the project) .h and .m files that I've already created outside of the current project I'm working on. Taking into consideration that I may want to modify the class from the original without subclassing. Hopefully this makes sense.
Thanks,
Nick
Xcode project file organization doesn't reflect the data files on disk. Files can be added to a project from anywhere in the file system. When you add the files, choosing not to copy the files to the current project's directory means that the original files are used. Selecting one of these files in Xcode for editing will alter the original file in that other project. When returning to that other project, Xcode will use the edited files in any further work.
This type of use can be quite handy while working on multiple projects with some shared code. Yet, it can also cause headaches for a versioning system.
Might be worth thinking about how to make the classes into a private framework - then you can import that as another dependency each time. Alternatively you could use a separate version control system location to store the shared classes and just check that out into the project folder.