I have a C# WPF application. It is designed to work on any and all files. Right now, it accepts 'input' by means of commandline arguments as well as drag and drop to a control in its main window. However, ideally I want people to rightclick any file/multiple files and have them be able to simply click 'Awesomify this'. (That's not the real name. :P)
I've got some experience with context menus from years ago, so all in all, it isn't too current. As such, I am looking for advice on the best way to implement this feature. All examples following are based on what I see using W7.
Generally, I understand there's basically two ways: pure registry, and registry + COM object.
The former has a certain elegance to it, since I don't want anything special; however, from what I can tell by documentation, these menu items always clump up at the same place as the primary file actions (Open, Preview, Print). However, I'd like my item to appear lower on the totem pole. If I look at my personal contextmenu for a random file, I'd want it to be at the 'spot' UltraEdit and Malwarebytes Anti-Malware stick themselves. Sticking my entry under HKCR\*\shell\AwesomeTest gets me my item, but no matter what I pick for the Position, I get two different extremes I don't like: Top puts it above the default item, Bottom puts it right above Properties. I want it inbetween Share with and Restore previous versions, which where most general-purpose tools seem to find a home.
Some more registry digging seems to point out the apps I wish to mimic use the COM object route. And that would bring me (I believe) back to native code. Which would then bring with it all the hells of 32-bit and 64-bit development I am trying to avoid.
Is there anything I am missing? Likewise, other than the MSDN page regarding context menu handlers which I have looked through and found to be rather unhelpful (as it seems to skim a lot without diving into the more precise details regarding placement and such), are there any good sources regarding this problem?
Another thing I've not been able to figure out just yet is how I can properly add IDropTarget support to my .NET WPF application yet, so information on that would also be welcome.
If anyone has an instant answer, well that would be nice, but I am mainly trying to find the right path to take without wasting several days on the paths that are dead-ends. Which there seem to be a lot of. :(
IContextMenu::QueryContextMenu(). Shell extensions are in the domain of C++, very unpleasant in C#, .NET 4.0 required. A sample project that uses it is here.
Related
Basically i am working on UI automation testing of a windows based application using visual studio CODE UI, problem comes as and when the layout changes or some new control is added in the GUI,and the control ID of the controls change.As we can see from the screenshot that a typical hierarchy is recoreded by CODE UI builder which is :-
Main Window ->Window with Control Id property -> Actual control.
So here are my questions related to this heirarchy and control Ids?
1) How are these Control IDs generated?
a) I know there is some logic by which these control ID Nos are
generated, depending on the depth of the control in the GUI,but i am
not able to find out any consistent way of how they are generated ,
for example in images the two buttons connect and help seems to be
in same level of GUI but still their control IDs are so different 1
and 5013.
b) Are these control IDs generated by coded UI builder used in Testing
environment or there is some logic in product development side or that code itself
by which they are generated
2)Is there a way to skip this middle layer of window with control ID and do the record and playback successfully.(As in my case we have access to logical name of all the controls which themselves are unique in nature ,and we are good to get rid of these control IDs)
3)Plus Can we have hybrid approach where we have two layers for almost all controls but three layers for some special cases where its not possible to work with logical name or label only and we explicitly require control IDs
4)Last but not least how much of the accessibily implementation of this type can be done in Testing Environment as per my knowledge most part of accessibilty of controls has to be done on the product development Environment by adding some properties in code itself which then can be retrived for testing using various tools like CODE UI in testing Environment.
But for large scale products i dont think that is a good approach as it imposes extra burden on development side and it is like adding extra unnecessary code in product(needed for testing purposes only) which needs to be delivered to the customer.
Plz see images below as a reference for clarity on my questions.
1st Image shows Remote Desktop GUI
2nd shows Computer: control properties recorded by CODED UI
3rd shows Connect Button properties recorded by CODED UI
4th shows Help Button properties recorded by CODED UI
I am only starting with CodedUI now, but I did a lot of UI Automation using different products before and using the same technology (MSUIA etc.). So this should apply here as well.
Each control has several properties, like name and automationid to name the most important ones. If you are automating a UI that is your own (you code/build it yourself) you should always attempt to give a unique automationid to each control, that will make your life a lot easier when automating. Name often is a bad option, since it frequently changes when you have a different language version of a program.
Since in that case you do not have the source and cannot influence the values it reports, you have to work with what is given. Still, even though CodedUI recorder will choose any property it sees fit, you can change the search criteria yourself by changing the UIMap.uitest for each element found:
This probably will take some time getting used to.. especially for more complicated UIs where elements have similar properties, also for dynamic UIs, etc.
By the way, the products I was using earlier on directly were working with AutomationElements, and here you have the full power to select and do what you want - even though with a high maintenance and start cost. (Ok, so it is generally very time consuming - and will always be more time consuming than using any ready solution like VS Coded UI.)
One more easy solution also is to simply go by coordinates (relative to some known controls, like main window or a tab group), this also will work 99% of the time and bring you to your goal that much quicker.
Ok, answering your concrete questions
1) if that is what I think it is, they are generated at runtime and there really is no relying on them
2) When going lower level (like AutomationElement) you can search whole trees. Still, that will typically make the search rather slow as well - not much faster then if you get the whole tree yourself and traverse it
3) You can mix anything you want. Actually, you can even convert handles to AutomationElements to Controls (at least for most standard controls). So you could use any technology, like Win32 SDK, to traverse the tree. Actually, all GUI trees in all technologies are similar - though not the same. And few people coding seem to adhere to any standards.. at least that is my experience.
4) Using a variation of technologies, coordinates (actually, I even used screenshots) etc you can achieve almost everything. It takes a lot a lot of time though. Getting the basics right during development and taking feedback from UI test developers into account can greatly help speed up later testing.
Simplest example: whether an application paints "all ok" on the screen or whether there is a control that can reach that has a name property that says "all ok" - second solution will be a lot better for the automation guy.
Also, for more complicated UIs, if you are in a corporate environment, have some money and want to spend a lot of time on UI tests anyway, I suggest a product like Ranorex, SilkRunner and the like. I worked with a Ranorex Eval for a few days and (after some getting used to it) could navigate UIs that very rather difficult to navigate myself beforehand.
I've got an ASP.NET web application, that is essentially our intranet site. I made a lot of progress on the administration office's employee management pages. It ties into an SQL server database, and I'm using a three layered design (Objects, Logic, DataAccess). It was all reviewed and all of it was accepted, except! for the part that manages vacations and vacation histories.
My question, before I go into details is, how does one efficiently "untangle" code that is no longer necessary?
For example: previously I was treating each VacationDay as it's own entity with it's own history. Such that I could track the history of an individual day. To help in tracking, I have an enum called VacationDayAction, which includes options such as .Submitted, .RequestDenied, .CancellationRequested, and so on. This was in an attempt to provide meticulous detail for each day. It was then determined that we no longer need that. We do, however, still need VacationDays and all the basic functions of that (saving days, getting days, etc.), but now we no longer need any of the "history" related classes.
My problem is, when I right click a class that I no longer need in VS and go to "Show All References," I get a ton of results scattered across several pages. I need to get rid of all of them, without breaking the rest of the application. Is there not some kind of "smart" technique or method for easily untangling parts that are no longer necessary? This is particularly difficult because 90% of what I did was just fine, and needs to stay like it is. Yet scattered in that 90% is 10% of stuff that is no longer needed. I can't just go storming through with the delete key either, because with the removal of each reference, I need to be sure that any dependencies on that reference are also fixed in a way that they don't call stuff that isn't there anymore. And I still need the application is a compilable state, so that I can test along the way that the rest of the application didn't fall apart as a result of some deletion.
To give you an idea of my low level of experience, I started two years ago with having never used C#, ASP.Net, or Visual Studio. It blew my mind when, way after starting and as I was learning, someone taught me that I could use breakpoints. And then it really really blew my mind when I learned about multi-layered design. I'm wondering if there is not some technique or trick or feature that can help in scenarios like this, where you have to "untangle" and throw away unnecessary stuff.
This is not a simple question. In fact, I would say this is one of the major challenges for any systems developer; how to handle and get rid of old code which is not in use. There is lots of literature on this, and few really excellent answers. A good book may be "Working effectively with legacy code" by Michael Feathers, which deals with many related problems. It is no light read though, and will probably take some time to get through, but it will likely help you become a better coder, and better at these kinds of tasks in particular.
Maybe you can have a look at the Resharper tool? ( http://www.jetbrains.com/resharper/ ) It is a productivity tool which among other things shows "dead" code (unused code) in grey, and lets you remove it. It will also help you remove unused references from each class (again, they will be grayed out and let you remove them automatically).
Drawing diagrams where each major piece of code /component is a box with a line linking it to any related component might help you get a better overview; try to draw a hierarchy showing how different parts of the code are related and dependent.
The bottom line as far as I know, is that you just have to muddle through it, commenting out code a little at a time, then recompiling and testing it. If it still works, fine, now you can remove the commented out code completely. This would be easier if you had unit-tests covering your code, but I take it as a given that you don't, as is unfortunately often the case.
I just had a conversation with my manager relating to checkin\out policies on a project I'm currently working on. Basically I tried to edit a file that was already checked out by another developer and I couldn't - I asked my manager why we couldn't edit the same class at the same time and he gave this reason for turning that functionality off: We had a lot of problems with developers editing the same Form (or anything visual done in the designer) and then cheking it in. Merging the changes in the designer generated code was a lot of hassle...
As I'm writing this I'm struggling to see what problem they were having - surely they were getting the latest code before trying to check something in??
Have any of you come across problems with editing the same Form (or something in the designer) as another developer and then checking into TFS? If so how did your team get around the problem? Did you also turn off the ability for developers to work on the same class?
EDIT: The following post (found here) is exactly the problem my manager was describing. Anyone know of a simpler way to resolve the issue than the ones in that post?
I would argue that the solution to your problem would be to establish best practices for source code modification.
Discourage people from going into UI code and arbitrarily jiggling the components around in the designer. Any reasonable UI modifications should be easily mergeable. Your best bet is to try and educate people as to the best way to merge in any given source control system. Also, as helpful as the designer is, ignorance of what code is being automatically generated in the background will be significantly detrimental in the long-term.
People who insist on locking checked-out files for the reasons you stated in your post typically wait long periods of time to check their code in. Naturally, the more time passes, the more code gets modified, so it makes merging difficult for these people. Checking in early, often, and incrementally requires people to think about their changes in stages, and for some coders, this is a rather painful cultural/psychological adjustment.
I've just checked back through the histories of some of my .designer.cs files and I can't see any changes that would cause a merge problems. There were no wholesale rearrangements of code for example.
Another thing to consider is to make sure that everyone does a "get latest" at regular intervals then any individual merge/resolution isn't going to be that great thus minimising the chances of anything going wrong.
It might also be worth investigating a 3rd party merge tool. There are plenty around.
Now it could be that the changes I've done are simple compared to the ones you've got so you should take my anecdotal data with a pinch of salt.
It can cause problems (in general) when a lot of people are editing UI concurrently. The merge logic will do a fine job merging things, but in a lot of cases the UI is drawn according to how things are added to the form. Your UI can get messed up quickly.
I don't know if I would use this as an excuse to enforce exclusive checkouts across the board, though. I might go from a (non programmatic) policy standpoint that says shared checkout for business logic, but exclusive for UI changes.
I would couple that with a strong MVP, MVC, or MVVM approach, though, which should limit the number of people that have to touch the UI concurrently.
As others have alluded to, keep one of the seminal rules of SCM in mind: merge early and often, and your problems are reduced. (along with that is "always get latest before you start working on the code).
The application in question is a fairly extensive with many different types of access roles (read Customer Service, HR, Admins, etc etc). Tiered access, so each role inherits the access below it, so HR has Read Only, CS has edit abilities, Admins full control. Menu bars and buttons enable/visible attributes are controlled by an outside an outside library that handles all role-based access via reflection. The man who wrote this was an evil genius.
That being said, I'd like eventually to remove it. The knowledge base on how it works left with him years ago, and development on this application is starting to stagnate since the documentation on the security 'suite' is awful. Everything is stored within a database, down to label visibility for each label. It's a bit overboard and not refactor-friendly.
I've spent a solid amount of time looking into windows forms security. We're running our own user/roles for this app rather than Active Directory. I'd like to use User/Principal, since that looks like the best option. If there's another option, I'm open to advice, I'd like to see this done the right way since we're considering a full rewrite (unrelated to this).
All the searching I've done through MSDN and other websites has led me to believe that I can only control flow through methods and classes based on roles, not as granular as "enable this button" or "hide this menu bar."
Is there a better way than doing something along the lines of:
btnA.Visible = Thread.CurrentPrincipal.IsInRole("HR");
btnA.Enabled = Thread.CurrentPrincipal.IsInRole("CS") ||
Thread.CurrentPrincipal.IsInRole("ADMIN");
Is there a better way in general? What's the best way to handle this?
That's pretty close to the way that we do it, both in WinForms and in our ASP.net applications. The one difference is that we store the role names in a database so that they are easier to maintain and upgrade than hardcoded constants.
While it lacks the sexiness of some sort of automatic binding (which it seems that you are looking for), it's solid and has not been troublesome to deal with. However, our application does not have a tremendous variation between users. For the most part, if a user can get access to part of the application they can perform most of the actions.
OK so that title sucks a little but I could not think of anything better (maybe someone else can?).
So I have a few questions around a subject here. What I want to do is create a program that can take an object and use reflection to list all its properties, methods, constructors etc. I can then manipulate these objects at runtime to test, debug and figure out exactly what some of my classes / programs are doing whilst they are running, (some of them will be windows services and maybe installed on the machine rather than running in debug from VS).
So I would provide a hook to the program that from the local machine (only) this program could get an instance of the main object and therefore see all the sub objects running in it. (for security the program may need to be started with an arg to expose that hook).
The "reflection machine" would allow for runtime manipulation and interrogation.
Does this sound possible?
Would the program have to provide a hook or could the "reflection machine" take an EXE and (if it knew all the classes it was using), create an object to use?
I know you can import DLL's at runtime so that it knows about all sorts of classes, but can you import individual classes? I.E. Say I have project 'Y' that is not compiled to a DLL but I want to use the "reflection machine" on it, can I point at that directory and grab the files to be able to reference those classes?
EDIT: I would love to try and develop it my self but I already have a long list of projects I would like to do and have already started. Why reinvent the wheel when there is already a great selection to choose from.
Try looking at Crack.NET. It is used to do runtime manipulation and interrogation on WPF/WinForms but the source is available and might be a good start if it already doesn't meet your needs.
It sound as if Corneliu Tusnea's Hawkeye might be close to what you're looking for runtime interrogation of objects/properties/etc. He calls it the .NET Runtime Object Editor. I'm not sure if the homepage I linked to above or the CodePlex project is the best place to start.
It's a bit out of date now, I think, but there's an earlier version of it on CodeProject where you can see the source code for how and what he did.
Powershell actually does nearly all of this, if I properly understand what you are saying.
See this answer on how to build a "reflection engine".
All you need to do is to drop that set of machinery in the your set of available
runtime libraries and it does what you want, I think.
(It might not be as easy as I've made it sound in practice).
My guess is you'll also want a runtime compiler, so that you can
manufacture instrumented/transformed variants of the program under inspection
to collect the runtime data you want. You may find that such
machinery provide static analysis results that let you avoid
doing the runtime analysis in many cases.