We have a pair of applications. One is written in C# and uses something like:
string s = "alpha\r\nbeta\r\ngamma\r\ndelta";
// Actually there's wrapper code here to make sure this works.
System.Windows.Forms.Clipboard.SetDataObject(s, true);
To put a list of items onto the clipboard. Another application (in WinBatch) then picks up the list using a ClipGet() function. (We use the clipboard functions to give people the option of editing the list in notepad or something, without having to actually cut-and-paste every time.)
In this particular environment, we have many users on one system via Citrix. Many using these pairs of programs.
Just one user is having the problem where the line delimiters in the text are getting switched from CRLF to LF somewhere between the SetDataObject() and the CLipGet(). I could explain this in a mixed Unix/Windows environment, but there is no Unix here. No unix-y utilities anywhere near this system either. Other users on the same server, no problems at all. It's like something in Windows/Citrix is being "helpful" when we really don't want it, but just for this one guy.
Ideas?
Have you tried clearing their profile on Citrix? That seems to be the solution to many many user specific Citrix problems.
Does Environment.NewLine behave differently on Citrix environments? If so, it may give you a good option that works for all users instead of \r\n.
Related
I'm building a User Control using C#/Winforms and have struck a bit of an issue with localization.
I have added a number of strings to the resource file "inside" the user control, using the UserControl.resx file created automatically by Visual Studio. For the immediate term, these strings provide the Text values for the various buttons in the user control. I have tested this with location specific suffixes (ie, UserControl.zh-HK.resx), and all appears to work perfectly.
What I have found, though, is that the UserControl.resx file I am using gets wiped out, or cleared, at irregular intervals (I haven't nailed down exactly when it does and does not get cleared).
A big clue is that the IDE throws a message box when I attempt to edit this file. It says, in essence, that my changes may be lost. Experience has taught me that this is certainly the case.
For various reasons, the idea of having the resource file tightly coupled to the user control seems attractive. There are several of us, all developing user controls that are destined for the same product.
Is there any way to stop VS from smashing my string resources? Is there a better way, allowing for the fact that we want a separate set of resource files for each user control?
Thanks.
Long story short, everything I was doing was wrong.
In the end, what I have done is create a Resources folder in my project, with a separate set of resource files for each discrete component (form, user control, etc). Then in each component I retrieve the strings like buttonFoo.Text = Resources.UserControl.buttonFoo_Text.
This method seems to be working well enough for now and provides the separation of resource files that I wanted, while making the integration of the code from multiple sources semi-painless.
I'm a programmer with pretty basic abilities, and I located a suspicious looking file on a friend's computer. I emailed it to myself and opened it with the .NET reflector, just for fun on the off chance it worked. It did, and the code looks like it was initially written in C#/VB. The program looks to my untrained eye like a pretty basic stealer, grabbing all sorts of passwords from their standard directories. I also finally found what I was looking for; where all of this data is emailed to. I got it in my head that I could disable this email address and help others who have lost important data by contacting them. However, the email address and its password are stored as variables; Me.Information. What I really need is to find that variable, Me.Information. The program itself is simply enormous, filled with code that I barely understand in context. It's utterly unscrambled as far as I can see. No obfuscation. I've been searching in my free time for quite a while now, any pros out there who could lend a hand would be very much appreciated!
Thanks.
Export it to a project, and open it in some IDE (like visual studio). To address your concern about accidentally running the program, you can actually disable those run configurations in the project settings, so you have no chance of running/building it.
Hope this helps!
if you found the code section that sends the email out, you could just replace it with a messagebox that displays the address, rather than sending something to it. be careful though, dont wanna make a mistake and give away your passwords.
also, you can open up some .net files in notepad and see the strings. often times they will be easily readable... something like:
address = "me#somewhere.net"
(in code)
might be visible in notepad, although it may look like this:
m e # s o m e w h e r e . n e t
(im not sure if they are actually 'spaces' but they do tend to display looking like spaces)
it could take awhile to search for all instances of "#" though, and it wont work unless they assigned it in a simple manner like my example... they may have constructed it to make it less visible
I am having some trouble with the interop.tapi3lib.dll (which can be DL here:dllLink)
For a reporting program i'm writing, i want to monitor all of the devices available by the tapi for their calls. Now this is working nicely when i fire up the program, although i suspect the dll is written with the purpose of modifying calls on a single extension, with very little code i can see all of the activity perfectly.
The problem arrises when a user logs out (or in) a phone (I'm using this for a cisco Callmanager). At that time i am able to capture the tapi_object which in turn can be used to determine which line is removed and added (old number and new number) but i can't register the new address for sending events.
The exception when i try:
Value does not fall within the expected range.
because the tapiclass was created before this address was available i suspect.
At the moment i have done a test which creates a single tapiclass for each line individual and 1 tapiclass for monitoring the tapiobject event, but this is eating 10 times the memory for our company's configuration (20 phones) so i dont even want to test this at the target site (+300 phones). The other option (for i can think of) is to dispose the 'old' tapiclass and create a new one after, however i'm a bit concerned with either loosing events between, getting double events between and pingpong when multiple users log in/out (creating the class takes a couple of seconds with my program)
So, what i would really like is the option to
tapi.RegisterCallNotifications(ad, true, true, TAPI3Lib.TapiConstants.TAPIMEDIATYPE_AUDIO, 2);
for newly available lines.
Bit of background for answers :)
-I am fairly new to C#, completly new to COM-interop and i know the principles of C++, but ive never written anything in it.
Any help would greatly be appriciated. (also any comments about interop and such)
Hmm, turns out I was wrong. Adding the line for notification is possible and does not throw the exception. I think i didn't remove the old line before adding the new in my old sample.
I am building a Windows dialog box that has the standard 'OK' and 'Cancel' buttons. Given that Windows uses the same button text in its own dialogs is there a way for me to grab the correct strings to use on the buttons?
This way my application will have the correct strings no matter which language is being used, without me needing to localize it for lots of different languages myself. I am using C# but can happily use platform invoke to access an OS method if needed.
NOTE: Yes, I can easily localize the resources but I do not want to find and have to enter the zillion different language strings when it must be present within windows already. Please do not answer by saying localize the app!
In Visual Studio: File + Open + File, type c:\windows\system32\user32.dll. Open the String Table node and double click String Table. Scroll down to 800.
Microsoft takes a pretty no-nonsense stance against relying on these resource IDs. Given the number of programmers who've done what you're contemplating, it is however unlikely they can ever change these numbers. You'll need to P/Invoke LoadLibrary() and LoadString().
However, your ultimate downfall on this plan is Vista/Win7 Ultimate with MUI language packs. Which allows the user to switch between languages without updating the resource strings in the DLLs. Such an edition will always have English strings.
see MB_GetString which claims to do exactly this:
https://msdn.microsoft.com/en-us/library/windows/desktop/dn910915(v=vs.85).aspx
however, it seems to require runtime linkage:
http://undoc.airesoft.co.uk/user32.dll/MB_GetString.php
Well, if you use the standard MessageBox.Show() function and pass it approriate parameters it will automatically localize the yes/no/okay/cancel buttons for you.
What is more interesting is how you localize the message text.
No, there is no standard, supported way to do this. Yes, Windows does store these strings and it's (with some effort) possible to obtain them, but there is no guarantee that they'll remain in the same location and under the same identifier from version to version.
While you might not want this to be the answer, the answer is, indeed, to localize your application. If you're localizing everything else (as you'd have to, unless you just wanted OK and Cancel to be localized), I'm not sure why it would be any great effort to include localized values for OK and Cancel as well.
I need to create a patching routine for my application,
it's really small but I need to update it daily or weekly
how does the xdelta and the others work?
i've read around about those but I didn't understand much of it
the user shouldn't be prompted at all
Ok this post got flagged on meta for the answers given, so I'm going to weigh in on this.
xdelta is a binary difference program that, rather than providing you with a full image, only gives you what has changed and where. An example of a text diff will have + and - signs before lines of text showing you that these have been added or removed in the new version.
There are two ways to update a binary image: replace it using your own program or replace it using some form of package management. For example, Linux Systems use rpm etc to push out updates to packages. In a windows environment your options are limited by what is installed if you're not on a corporate network. If you are, try WSUS and MSI packaging. That'll give you an easier life, or ClickOnce as someone has mentioned.
If you're not however, you will need to bear in mind the following:
You need to be an administrator to update anything in certain folders as others have said. I would strongly encourage you to accept this behaviour.
If the user is an administrator, you can offer to check for updates. Then, you can do one of two things. You can download a whole new version of your application and write it over the image on the hard disk (i.e. the file - remember images are loaded into memory so you can re-write your own program file). You then need to tell the user the update has succeeded and reload the program as the new image will be different.
Or, you can apply a diff if bandwidth is a concern. Probably not in your case but you will need to know from the client program the two versions to diff between so that the update server gives you the correct patch. Otherwise, the diff might not succeed.
I don't think for your purposes xdelta is going to give you much gain anyway. Just replace the entire image.
Edit if the user must not be prompted at all, just reload the app. However, I would strongly encourage informing the user you are talking on their network and ask permission to do so / enable a manual update mode, otherwise people like me will block it.
What kind of application is this ? Perhaps you could use clickonce to deploy your application. Clickonce very easily allows you to push updates to your users.
The short story is, Clickonce creates an installation that allows your users to install the application from a web server or a file share, you enable automatic updates, and whenever you place a new version of the app on the server the app will automatically(or ask the user wether to) update the app. The clickonce framework takes care of the rest - fetching the update , figure out which files have changed and need to be downloaded again and performs the update. You can also check/perform the update programatically.
That said, clickonce leaves you with little control over the actual installation procedure, and you have nowhere close to the freedom of building your own .msi.
I wouldn't go with a patching solution, since it really complicates things when you have a lot of revisions. How will the patching solution handle different versions asking to be updated? What if user A is 10 revisions behind the current revision? Or 100 revisions, etc? It would probably be best to just download the latest exe(s) and dll(s) and replace them.
That said, I think this SO question on silent updates might help you.
There is a solution for efficient patching - it works on all platforms and can run in completely silent mode, without the user noticing anything. On .NET, it provides seamless integration of the update process using a custom UserControl declaratively bound to events from your own UI.
It's called wyUpdate.
While the updating client (wyUpdate) is open source, a paid for wybuild tool is used to build and publish the patches.
Depending on the size of your application, you'd probably have it split up into several dll's, an exe, and other files.
What you could do is have the main program check for updates. If updates are available, the main program would close and the update program would take over - updating old files, creating new ones, and deleting current files as specified by the instructions sent along with a patch file (probably a compressed format such as .zip) downloaded by the updater.
If your application is small (say, a single exe) it would suffice to simply have the updater replace that one exe.
Edit:
Another way to do this would be to (upon compilation of the new exe), compare the new one to the old one, and just send the differences over to the updater. It would then make the appropriate adjustments.
You can make your function reside in a separate DLL. So you can just replace the DLL instead of patching the whole program. (Assuming Windows as the target platform for a C# program.)