I am writing a c# application that opens a number of PI ProcessBook display files. PI Processbook is a program that has embedded Visual Basic for Applications support, including a VBE environment.
The problem that I have is that a number of the displays I want to open have macros in them that run automatically when the display is opened. I have set the macro protection to maximum (which should disable macros completely!), but unfortunately there is something in the TypeLibrary that I am using that means that when a file is opened programatically, it bypasses macro security and the macros run anyway. Go figure....
I am therefore trying to find a way to programatically kill these macros, even if they have started. I have tried using SendKeys.Wait("^{BREAK}") to force into break mode. This "works", but is a bit hit-and-miss: I find that if the macro doesn't pause at some point, SetForegroundWindow can't force the VB Editor to the foreground to accept the sendkeys input. I therefore tried using sendmessage. I used SPY++ to see that CTRL+BREAK appears to send a WM_CANCELMODE message to the window. Apparently, this is somehow handled differently from literally ALT+Tabbing or clicking on the window with a mouse and pressing the CTRL+Break keys, in that the message gets queued, but does not appear to process until the macro has finished executing.
Does anyone have any other suggestions of things to try?
I am therefore trying to find a way to programatically kill these
macros, even if they have started.
Hold down the Shift key while opening the Spreadsheet and the Macro's wont run.
Otherwise you could try halting the code while its running: Ctrl + Alt + PauseBreak
Edit:
I have set the macro protection to maximum (which should disable
macros completely!)
Try disabling them:
Related
I've an applications that allows a user to start MS Word.
If the user holds the "CTRL" key while starting MS Word, following dialog is shown:
This leads to errors in my application, because users seem to hold the "CTRL" key by accident and may click on "yes", which deactivates my office addins.
Is there a way to prevent Word from showing this dialog and also from starting in safe mode?
For instance, if you try to start Excel with the "\e" parameter + holding "CTRL" key, Excel starts without any dialog and not in safe mode.
The application is developed in .Net (c#)
You tell the user to stop doing that!
AFAIK, There is no way you can, with code or otherwise, stop Word from starting in safe mode. That is a basic diagnostic built into the programs and is not optional.
It's in a C++ translation program. When user selects some text in some other program without pressing CTRL-C, I want to get the highlighted text so that I could translate it. C# solutions are welcome because this(text acquisition) is a relatively standalone component.
One possible solution is to add hook to mouse event. I detect the following messages: mouse drag with left button hold, then release left button. Then I send CTRL-C to the program and get the text from clipboard.
I save and restore clipboard so most programs would work well with the method. But I have observed some programs would process events like WM_KEYUP in their message loops. For these programs I send fake messages! Is there another safer way to get the highlighted text?
I was trying to find some API call to get text between two mouse cursor positions, but I cannot find one.
The right way to write a Windows program that interacts with another programs GUI interface is to use UI Automation. Specifically, you'll write a UI Automation Client.
It requires a bit of work, but a UI Automation solution will work with almost every other application. A hacky solution built on hooks and messages will also be a lot of work, but it will be very fragile. It will only work with certain kinds of applications in certain contexts. Lots of things can go wrong.
I'm developing a vbnet/c#.NET based application that opens files with different applications(excel, word, etc).
The application is launched using Dim app As Process = Process.Start(ProcessProperties)
Now, when I have to terminate the process I use app.Kill() but I need to check if the document has been modified before killing it.
How can I handle that? And if it's possible, how can I launch the application native prompt for save?
Thanks
For office applications use Office Interop Assemblies, not Process.Start to start and control them. Here is an example code for Excel (in VB.NET). You should add Microsoft.Office.Interop.Excel.dll to the project references in order for this to work.
oExcel = New Microsof.Office.Interop.Excel.Application
oBook = oExcel.Workbooks.Open(filepath)
'Do your stuff
oBook.Close 'This will trigger the application native prompt if the document was modified
oExcel.Quit()
For other programs it depends much on a program
You can achieve behaviour close to what you require by calling Process.CloseMainWindow rather than Process.Kill.
The behavior of CloseMainWindow is identical to that of a user closing an application's main window using the system menu. Therefore, the request to exit the process by closing the main window does not force the application to quit immediately.
Data edited by the process or resources allocated to the process can be lost if you call Kill. Kill causes an abnormal process termination, and should be used only when necessary. CloseMainWindow enables an orderly termination of the process and closes all windows, so it is preferable for applications with an interface.
In the case of Office applications with unsaved changes, CloseMainWindow would launch the Save dialog. You would need to handle scenarios where the users presses “Cancel”, since that may result in the WaitForExit call blocking indefinitely.
For example:
// Launch Word application.
Process wordProcess =
Process.Start(#"C:\Program Files (x86)\Microsoft Office\Office12\winword.exe");
// Give user some time to type in text.
Thread.Sleep(TimeSpan.FromSeconds(20));
// Request Word to close.
wordProcess.CloseMainWindow();
// Wait until user saves or discards changes.
// May block indefinitely if user cancels.
wordProcess.WaitForExit();
There are different approaches for this problem. You can calculate some sort of initial check-sum and see whether your document has any changes by redoing the check-sum and comparing against the original one.
This part is not very clear from your question, If the document gets saved, probably you can look at the date_modified value of the file to see whether there has been any modifications.
I am debugging a C# program that calls Word 2007 for rendering of some office files. It all works well as long as Word starts up and shuts down properly.
In the few instances where it wasn't, there is a pop-up message from Word the next time. It basically says that it wasn't started properly last time and then asks if I would like to start it in Safe-mode. Is there any way of avoiding this popup message?
There are a few approaches here:
Do you really need to avoid safe mode, or just the dialog? If you can start Word with the /safe option then it will always be in safe mode and shouldn't ask you.
Do you know what causes safe mode? Maybe starting Word with the /a option to disable add-ins (assuming you're not using any) would prevent the cause of the crashing in the first place.
See if you can figure out what causes Word to think it should open in safe mode. There has to be a file or registry entry that trips it up. You can use Process Monitor to see what files and registry entries it looks at, and see which ones are different between traces from a regular startup and one where it asks for safe mode. Then make sure that condition doesn't exist just prior to opening Word.
See http://support.microsoft.com/kb/210565 for a list of command line options for Word.
I have the same problem with powerpoint. We run a theatre that does slide shows in between shows. If powerpoint somehow crashes or closes uncleanly, you are prompted to start in safe mode. What happens is that the "do you want to start powerpoint in safe mode" comes up and requires user intervention to fix. I would like to disable this "feature" or safe mode entirely. The closest I have come is the following fix, which I have now implemented but I do not know if it will actually prevent it or not until another crash (which can take months to happen - thankfully). Seems promising though!
Open up a blank Word document on your computer.
Click on the circular icon in the upper left-hand corner. Select "Word Options" from the menu.
Click on "Trust Center" on the left-hand side of the menu.
Select "Trust Center Settings."
Select the "Active X Settings" and uncheck the box for "Safe Mode." This will disable the feature in all Office programs.
Hit "OK" to save your changes and close the Microsoft Word document.
Most likely, but you must look to fix the problem at the level of diagnosis, not fire-fight the symptoms away.
Look into the code which utilises
Word
Localise the piece of code which
could cause failure
Find particular solutions to the
found problem
Correct the issue
Don't look to 'auto-click' the dialog away or any other such flakiness, this is a hack.
The code in question would be useful, if not invaluable to providing real help.
I have similar problem dealing with PowerPoint in .Net
the safe-mode message box will show up when I launch it from my program after PowerPoint crashed, which stopped my automatically process
after some investigation into the registry, deleting this
HKCU\Software\Microsoft\Office\15.0\PowerPoint\Resiliency (change the Product and Version)
before starting the Office program will avoid the Safe-mode
(This registry key stores the info of last opened file, by deleting this, PowerPoint won't know it was crashed, so it opens normally)
I got a bit of a problem.
Related to my earlier questions about Slipstreamed SP3 vs. patched SP3, we've come to the conclusion that there is an Internet Explorer process being started, instructed to load a simple .html file from the local disk, which contains javascript, which opens up the rest of a larger chat/meeting system. Internet Explorer is started from a Lotus Notes client.
Unfortunately, all we can see is the IExplore.exe process popping up in Task Manager, and some seconds later, disappear again.
If we try to open the local .html file, which we've found on disk, it gives us that information bar at the top, telling us that it has disabled active content. This, however, is not the real problem. We have another machine that has the same settings but where everything works, and loading the .html file manually gives us the same error there as well.
However, perhaps there is another error message being shown when IExplore is started from notes, but since this process is supposed to just kickstart the rest of the system, and this window is hidden, we can't see it, that is, the error message / problem.
So, I thought, perhaps I should try creating a small program that waits for IExplore.exe to start, then immediately shows the window, so that we can see the error message, or whatever the problem is. At least, hopefully we'll be able to see that.
So far so good, except that if I start a process from my own program, with a hidden window, the main window handle is 0, and thus I cannot show the window after all. I expect this IExplore.exe process started from Lotus Notes to have the same issue.
My monitoring program is written in C#, and basically runs this loop:
foreach (var process in Process.GetProcesses())
{
if (process.ProcessName.ToLower() == "iexplore")
result.Add(process);
}
This picks up all the IExplore.exe processes, windows or not, and with IE8, I get 2 processes for the first window, as expected. I run this over and over again, and handles the differences from the previous runs.
However, the process briefly has a window handle 0 at the start, so I changed it to this:
foreach (var process in Process.GetProcesses())
{
if (process.ProcessName.ToLower() == "iexplore" &&
process.MainWindowHandle != IntPtr.Zero)
{
result.Add(process);
}
}
but now it doesn't pick up anything at all, even after the window has gotten a handle (and yes, process.MainWindowHandle does have a non-zero handle value after the window has been shown, but in the case where the window is never shown, it stays at 0.)
So, the question is: Is there any way for me to take this hidden IExplore.exe process, and instruct it to show itself, when it doesn't have a window handle already? I doubt it, but perhaps someone can prove me wrong.
If not, my backup plan is to create a shim IExplore.exe program, that forwards all command line arguments to the original one, except that it specifies that the window is to be shown. Would this be a solution?
I do not believe there is any way to force an IE window which does not have a window handle to allocate a window handle for itself (or use a previously allocated one) and display itself.
As to your backup method: I think this would work, but you're working in dangerous territory there. I'd actually recommend writing your shim to just log every invocation of iexplore.exe and everything that goes into it, and use that to characterize your problem; only after thoroughly characterizing your problem with completely benign logging would I suggest possibly modifying the parameters to force iexplore.exe to display a window.