For my current project, I need to compare two build versions of a program and generate a report showing which files have changed. My own idea was to run through each file using the file system, comparing dates modified. It was suggested, however, that I instead find the changelists stored in Source Depot and compare that way.
Being unfamiliar with Source Depot, I was able to find two relevant commands - "changes" and "changelist". However, the documentation is very vague about explaining how to use the SD commands, and typing something like "sd changes 1249191" results in errors like "must create client 'MGURL' to access local files". The other problem is that even if I had that aspect working, making a call with "System.Diagnostics.Process.Start" would most likely only print info to the console and not return any data to me from within C#.
I think what I really need is a library similar to the Microsoft.TeamFoundation for TFS. However, I've found little to no info online about Source Depot at all, let alone a way to interface with it through C#. Anyone have any insights? Have you done something like this before?
Check out the internal toolbox website for Source Depot utilities. There should also be a internal email alias for Source Depot questions like this...
The solution I found was two-fold, and this was partly due to my own research into the tool and partly from a colleague's suggestion.
Firstly, upon re-examining the sd command list, I found I wasn't looking at the right commands to get the info back that I wanted.
Secondly, there is no way to directly interact with source depot, but I can redirect the console's output back to me by using RedirectStandardOuput:
Process process = new Process();
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.FileName = "sd.exe";
process.StartInfo.Arguments = string.Format("describe {0}", newChangelist);
process.Start();
// read strings from process.StandardOutput here
process.WaitForExit();
Related
I would like to open programmaticaly an application.
First i used System.Diagnostics.Process.Start(#"C:\Program Files (x86)\Program1.exe") works fine, but the application always needs to be on the same path (not always true because different computer)
And a simple way to find it (with mouse & click, not programmaticaly though) is to use the windows file explorer, i enter the title of my application and i find it instantly.
I would like to code that.
I thought i could use the keyboard shortcut "Home + F" and simulate the word with SendKeys.Send("blabla") but the "Home key" doesn't seem to exist with c# (at least not here https://msdn.microsoft.com/fr-fr/library/ms127847(v=vs.110).aspx)
It's a little program for children i can't expect them to find manually the path (so forget the OpenFileDialog..)
Maybe thats a very bad idea and there are another solution to find a program without knowing his path, i don't know have you got better idea?!
You're trying to solve the problem the wrong way. What you're trying to "program" is the setting oft the working directory when the program is run using Explorer. The right way to do that is to use Process.Start by passing it all of the necessary info to start the process:
var startInfo = new ProcessStartInfo("Program1.exe");
startInfo.WorkingDirectory = #"C:\Program Files (x86)\";
Process proc = Process.Start(startInfo);
thanks for taking the time to read my quandary.
I need to open a PDF (C# 4.0, winforms). Now normally this is pretty easy if you aren't passing in arguments (Process.Start to the PDF), but I need to be able to pass in arguments (go to a specific page or named destination right now, maybe more later).
Now I know if you call AcroRd32 you can pass in the arguments needed to do this, but it is possible that the user won't have Acrobat Reader installed on their machine, so I don't really want to call that exe necessarily. Anyone know of a way to pull this off?
Am I missing an obvious way to do this using something else?
Thanks for your help!
PS - replies can be in C# or VB, don't care
To pass the arguments in Process.Start(), you need to call AcroRd32.exe or Acrobat.exe, like:
Process myProcess = new Process();
myProcess.StartInfo.FileName = "acroRd32.exe"; //not the full application path
myProcess.StartInfo.Arguments = "/A \"page=2=OpenActions\" /n C:\\sample.pdf";
myProcess.Start();
I suggest putting this is a Try/Catch block, and if it fails then try "Acrobat.exe" as the FileName in another, nested Try/Catch block, and if that fails, default to:
Process.Start("C:\\sample.pdf");
which doesn't allow you to open to the specific page, but at least the PDF will open if the first two approaches have failed.
I am using the following code to open flash:
private Process flash = new Process();
flash.StartInfo.FileName = ("Flash.exe");
flash.Start();
The target machine has many version of flash like flash cs5,4,3. I want to open the newest version or let the user choose, how can I possibly do that?
Typically speaking, all other flash installations would be in different program folders, so you would just need to make sure you're running Flash.exe from the right folder. For instance, my current installation lies here: C:\Program Files (x86)\Adobe\Adobe Flash CS5\Flash.exe, but an alternate one could very well be in C:\Program Files (x86)\Adobe\Adobe Flash CS4\Flash.exe`.
An important thing to notice is that you can't assume the user installed flash CS* in its default directory! You should always query the Windows registry to find the list of installed products.
Also, another notice would be that you don't need parentheses around string literals. So you can just write:
string foo = "Hello!";
instead of
string foo = ("Hello!");
Edit 1:
Hey, I found a similar problem being treated in a forum thread here! I downloaded the code sample and ran it through a vb.net -> C# converter (like this one) and got it to work after a few minor syntax tweaks. Now it's able to output a list of the installed programs with their appropriate version numbers.
There will be a bunch of methods that get programs form e.g. certain users. All of these will then be placed in a common list, returned to the user. Now, this seems perfect, but there is just one flaw - no path is available... so far!
You can just query the UninstallString, and get a path to the uninstaller (which is IIRC in the same folder as Flash.exe). For instance, in GetUninstallKeyPrograms, after the
try
{
IsSystemComponent = Convert.ToInt32(CurrentSubKey.GetValue("SystemComponent", 0));
}
snippet, you can try to get the UninstallString value in order to obtain the path. Hope it helps!
Currently running this code to open Business Vision (an application written by someone else that i don't have access to the code of):
ProcessStartInfo myProcessStartInfo = new ProcessStartInfo(BusinessVisionPath);
myProcessStartInfo.UseShellExecute = false;
myProcessStartInfo.RedirectStandardOutput = true;
myProcess.StartInfo = myProcessStartInfo;
myProcess.Start();
StreamReader myStreamReader = myProcess.StandardOutput;
Boolean done = false;
while (done == false)
{
int s = myStreamReader.Read();
Console.WriteLine(s);
if (s == -1)
{
done = true;
Process IProcess = new Process();
ProcessStartInfo IProcessStartInfo = new ProcessStartInfo(QuickPrinterPath);
IProcessStartInfo.WindowStyle = ProcessWindowStyle.Maximized;
IProcess.StartInfo = IProcessStartInfo;
IProcess.Start();
}
}
myProcess.Close();
Console.ReadLine();
Anyways,
this code currently opens my printer program when BusinessVision closes.
Questions:
How (if possible) can i open my program when a certain message box pops up within BV ("Are you sure you want to print an invoice"?)
Is it possible to get any data from the application ? like raw data that i can parse through as it runs or something?
You might want to look into Microsoft's UI Automation. It allows you to read data from the windows of other applications, and interact with other applications' UI programmatically. I used this a couple years ago to automate a bunch of tests on an old VB6 app we had. My code would find the main window of the application, then drill down to the menus/controls/etc that I was interested in. From there I could automate clicks and keystrokes, and then scrape the text/data I wanted from the labels in various windows. I could then pull the data into my .NET app and do what I wanted with it.
In your case you would need some always-running app (such as a Windows service) to constantly monitor the BV program and detect when the message box appears, and then react accordingly by launching your program.
It takes a fair amount of work to understand and get working, but it's very powerful. There are free apps out there that will make it easier to browse the visual hierarchy of windows and see what kind of information is available. Check out Microsoft's UISpy:
http://msdn.microsoft.com/en-us/library/ms727247.aspx
Here are some other links to get you started:
http://en.wikipedia.org/wiki/Microsoft_UI_Automation
http://msdn.microsoft.com/en-us/library/ms747327.aspx
You can try to use one of the approved way to access data.
In the case of Sage BusinessVision there is:
Data import and export as csv availlable manualy from the application.
Direct acces to the Pervasive database, documentation availlable in the help section of the application in a file called BusinessVision Database Structure Reference.chm
API availlable to Sage partners.
1 is the most simple way and nothing is automatic.
2 is more challenging but will give you acces to the underlying data live.
3 requires that you pay and that you meet requirement by Sage.
If you combine 2. and some UI automation you could build some trigger on certain UI events and bring foward new windows filled with data from the database.
Note that UI automation will be extremly fragile to new version of the application and will certainly need to be reworked every time.
You could, although I'm not sure I'd recommend it, Enumerate top level windows, and check if one of them matches the pop-up box.
Except for files or database entries that the application creates, not that I am aware of, unless you want to get into Binary Patching of the application.
If the target is a .NET exe, perhaps the developers were sloppy and exposed their classes and methods publicly. In that case, load the exe as if it were a DLL dependency for your application and call their methods directly.
You could always try a decompiler :)
dotPeek
I've spent the last few days scouring the site looking for an answer to this problem,
i need to create a folder and then make it a shared networked folder, I've tried several different sample code snippets from different sites
http://www.sarampalis.org/articles/dotnet/dotnet0002.shtml (this link is dead)
but none seem to allow the folder to be shared
If anyone could be of help it'd be much aprriciated
If you don't find the real Windows API that does this, and you can settle for a dirty solution, you can do it by executing the command "net share".
For example, like this:
ProcessStartInfo info = new ProcessStartInfo("net", "share MyNewShare=c:\\folder");
info.CreateNoWindow = true;
Process.Start(info);
Note that in any case, in order to create a share you need administrative rights, so your code will have to run elevated if you're running on Win7/Vista with UAC enabled.
I did follow the link that you have in your question.
I have a Win 7 Professional + VS.NET 2010 Professional as my dev environment on my laptop.
I took the code from the article and quickly fired up a devenv and executed the code. The code executed perfectly without any error. When i looked at the created directory you dont see a share icon on the folder but it is indeed shared. How can you check that:
open a command prompt
type "net share" and press enter
you will see that it will list the folder c:\MyTestShare with a share name "My Test Share"
One more way to find out whether it is shared or not is to right click on the folder and look at the sharing tab. Check the Network Path label. It will clearly show the shared path.
Hope this helps you.
Lohith
See
http://www.sarampalis.org/articles/dotnet/dotnet0002.shtml
http://www.codeproject.com/KB/system/Share-Folder-c_.aspx