Registering file associations in MFC doesn't work on Windows 7 - windows

This problem I am having is very easy to reproduce. Create a basic MFC MDI application with file extension as .xyz using Visual Studio 2010. The application default code readily registers the file associations via calls:
// Enable DDE Execute open
EnableShellOpen();
RegisterShellFileTypes(TRUE);
The problem is that inside RegisterShellFileTypes(TRUE), the call below fails:
if (!_AfxSetRegKey(strFileTypeId, strFileTypeName))
continue; // just skip it
The file is obviously not being registered and it doesn't adopt the application assigned file icon. All I want is when I double click the registered file type (in this case .xyz) it should open in the application but it doesn't. What is possibly missing..how to make this work?

Microsoft has changed their concept of registering an extension over the years. Starting with Vista, it's expected that the extension will be registered at installation time with a Setup application which will have Admin privileges. The registry keys necessary to map an extension to an application are now in a protected area of the registry. What you're asking for is no longer possible.

You need administrator privileges to accomplish this. Usually, you should let your installer register your files. However, it can be done if you explicitly elevate (and re-run) your process before your file types are registered:
// In your InitInstance, do the following:
OSVERSIONINFOEX osvi;
osvi.dwOSVersionInfoSize = sizeof OSVERSIONINFOEX;
GetVersionEx((OSVERSIONINFO*)&osvi);
if (osvi.dwMajorVersion >= 6) // XP or Vista/elevated?
{
TCHAR exePath[MAX_PATH];
GetModuleFileName(NULL, exePath, MAX_PATH);
ShellExecute(NULL, _T("runas"), exePath, NULL, NULL, SW_SHOWNORMAL);
return FALSE;
}

As Parapura Rajkumar mentioned, if you put this code in your init instance:
// Enable DDE Execute open
EnableShellOpen();
RegisterShellFileTypes(TRUE);
The application should run at least one time as admin (right click and run as administrator) to register file types in windows registry.

Related

Launcher.LaunchUriAsync does not work on Xamarin Forms UWP [duplicate]

no Error just nothing happen and file target still there in my path
public void keyboard(){
ProcessStartInfo touchkey = new ProcessStartInfo(#"C:\Program
Files\Common Files\microsoft shared\ink\TabTip.exe");
touchkey.WorkingDirectory = #"C:\";
touchkey.WindowStyle = ProcessWindowStyle.Hidden;
Process.Start(touchkey);
}
Update
The suggested solution threw a `UnauthorizedAccessException`:
var path = #"ms-appx://C:/Program Files/Common Files/microsoft
shared/ink/TabTip.exe";
var file = await
Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(path);
await Windows.System.Launcher.LaunchFileAsync(file);
Update2
I try to use FullTrustProcessLauncher it's work fine but like code before Keyboard tabtip.exe not show I dont know what should I do
await Dispatcher.RunAsync(CoreDispatcherPriority.High, () =>
{
FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync();
});
UWP applications are sandboxed and cannot launch other processes directly due to security restrictions.
The only way to launch other applications is if those applications have a URI registered, or an application is a default handler for a particular file type.
In those instances, you can use methods such as LaunchUriAsync or LaunchFileAsync
Without TabTip.exe
I recognize you are trying to show the on-screen keyboard judging by the path of the exe. I suggest a better approach would be to trigger the new touch-enabled keyboard which is easily possible without additional hassle from UWP with InputPane API:
var pane = InputPane.GetForCurrentView();
pane.TryShow();
With TabTip.exe
If you prefer the older on-screen keyboard for some reason, you have two problems with your existing code.
Firstly, ms-appx: scheme is used to refer to files at the application installation path. The path you require is an absolute path, so you can't use it there.
Secondly, as this is an arbitrary path on the hard drive, you don't have access to it directly (as UWP apps run in a sandbox and can't access the filesystem directly for security reasons). To access the file, you will need to declare the broadFileSystemAccess capability, which will then allow you to initialize the StorageFile instance. You can check for example this SO question to learn how to do just that.
Note: I don't have my VS PC around so I can't say for sure if this will allow you to launch the executable or not, as that seems like an additional permission which may not be granted. In case this fails, I strongly recommend the first solution.
Make sure you edited the manifest file and add the extension for full trust process in the application.

How to attach a debugger dynamically to a specific process

I am building an internal development tool to manage different processes commonly used in our development environment. The tool shows the list of the monitored processes, indicating their running state and allows to start or stop each process.
I'd like to add the functionality of attaching a debugger to a monitored process from my tool instead of going in Debug -> Attach to process in Visual Studio and finding the process.
My goal is to have something like Debugger.Launch() that would show a list of the available Visual Studio. I can't use Debugger.Launch(), because it launches the debugger on the process that makes the call. I would need something like Debugger.Launch(processId).
How do I achieve this functionality?
A solution could be to implement a command in each monitored process to call Debugger.Launch() when the command is received from the monitoring tool, but I would prefer something that does not require to modify the code of the monitored processes.
Side question:
When using Debugger.Launch(), instances of Visual Studio that already have a debugger attached are not listed. Visual Studio is not limited to one attached debugger, you can attach on multiple process when using Debug → Attach to process.
How do I bypass this limitation when using Debugger.Launch() or an alternative?
A coworker ended up with a solution using DTE, and I posted the code on PasteBin.
The methods of interest are AttachVisualStudioToProcess and TryGetVsInstance
Source Code
public static void AttachVisualStudioToProcess(Process visualStudioProcess, Process applicationProcess)
{
_DTE visualStudioInstance;
if (TryGetVsInstance(visualStudioProcess.Id, out visualStudioInstance))
{
//Find the process you want the Visual Studio instance to attach to...
DTEProcess processToAttachTo = visualStudioInstance.Debugger.LocalProcesses.Cast<DTEProcess>().FirstOrDefault(process => process.ProcessID == applicationProcess.Id);
// Attach to the process.
if (processToAttachTo != null)
{
processToAttachTo.Attach();
ShowWindow((int)visualStudioProcess.MainWindowHandle, 3);
SetForegroundWindow(visualStudioProcess.MainWindowHandle);
}
else
{
throw new InvalidOperationException("Visual Studio process cannot find specified application '" + applicationProcess.Id + "'");
}
}
}
private static bool TryGetVsInstance(int processId, out _DTE instance)
{
IntPtr numFetched = IntPtr.Zero;
IRunningObjectTable runningObjectTable;
IEnumMoniker monikerEnumerator;
IMoniker[] monikers = new IMoniker[1];
GetRunningObjectTable(0, out runningObjectTable);
runningObjectTable.EnumRunning(out monikerEnumerator);
monikerEnumerator.Reset();
while (monikerEnumerator.Next(1, monikers, numFetched) == 0)
{
IBindCtx ctx;
CreateBindCtx(0, out ctx);
string runningObjectName;
monikers[0].GetDisplayName(ctx, null, out runningObjectName);
object runningObjectVal;
runningObjectTable.GetObject(monikers[0], out runningObjectVal);
if (runningObjectVal is _DTE && runningObjectName.StartsWith("!VisualStudio"))
{
int currentProcessId = int.Parse(runningObjectName.Split(':')[1]);
if (currentProcessId == processId)
{
instance = (_DTE)runningObjectVal;
return true;
}
}
}
instance = null;
return false;
}
WinDbg does the chain debugging for native code by default. If you want to launch another instance of Visual Studio, check Launch the Debugger Automatically on MSDN:
To automate the existing debugger, use Marshal.GetActiveObject to get the current EnvDTE.Debugger then let it attach to the process you just created.
Sometimes, you may need to debug the startup code for an application that is launched by another process. Examples include services and custom setup actions. In these scenarios, you can have the debugger launch and automatically attach when your application starts.
To setup an application to launch the debugger automatically
Start the Registry Editor (regedit).
In the Registry Editor, open the HKEY_LOCAL_MACHINE folder.
Navigate to HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\currentversion\image file execution options.
In the Image File Execution Options folder, locate the name of the application you want to debug, such as myapp.exe. If you cannot find the application you want to debug:
a. Right-click the Image File Execution Options folder, and on the shortcut menu, click New Key.
b. Right-click the new key, and on the shortcut menu, click Rename.
c. Edit the key name to the name of your application; myapp.exe, in this example.
Right-click the myapp.exe folder, and on the shortcut menu, click New String Value.
Right-click the new string value, and on the shortcut menu, click Rename.
Change the name to debugger.
Right-click the new string value, and on the shortcut menu, click Modify.
The Edit String dialog box appears.
In the Value data box, type vsjitdebugger.exe.
Click OK.
From the Registry menu, click Exit.
The directory containing vsjitdebugger.exe must be in your system path. To add it to the system path, follow these steps:
a. Open the Control Panel in Classic view, and double-click System.
b. Click Advanced System Settings.
c. In System Properties, click the Advanced tab.
d. On the Advanced tab, click Environment Variables.
e. In the Environment Variables dialog box, under System variables, select Path, then click the Edit button.
f. In the Edit System Variable dialog box, add the directory to the Variable value box. Use a semicolon to separate it from other entries in the list.
g. Click OK to close the Edit System Variable dialog box.
h. Click OK to close the Environment Variables dialog box.
i. Click OK to close the System Properties dialog box.
Now, use any method to start your application. Visual Studio will start and load the application.
Here is some information about how you can programmatically attach the debugger to multiple processes:
Attach to locally running processes
Attach to remotely running processes

How to run an Application on windows start up in win32 API using visual c++

I have a Window (win32 API) Application in visual c++. I am not using MFC. I have to run my application on windows start up. I am using windows 7 and visual studio 2008. Can any one help me out in achieving the above task? Thanks in advance.
Here's some example code:
HKEY hkey = NULL;
RegCreateKey(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run", &hkey);
RegSetValueEx(hkey, L"myapp", 0, REG_SZ , (BYTE*)path, (wcslen(path)+1)*2);
The most straightforward way is to create a registry key:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
(Insert the code into your installation program to add the key.)
If you create it under HKEY_LOCAL_MACHINE, it will apply to all users of the machine. If you create it under HKEY_CURRENT_USER, then the program will run automatically upon startup only for that user.
Don't know about Win32 but how about a simple shortcut to your program:
C:\Documents and Settings\\Start
Menu\Programs\Startup
(or use All Users instead of USER)
Just add it to the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run key int he registry.
Look at autoruns by SysInternals (now Microsoft). It will show you the many ways a process can be started by Windows. You will want to check out the Logon tab which shows several file and registry settings that can enable you to start stuff on Logon. Services and Drivers start on system startup (don't require a logon). Bootexecute allows you to run stuff at boot time which is probably not what you want.
The rest of the tabs show you how to hook into various other system processes to load your code. It's no wonder Windows is ripe for malware authors especially if you run as root.
If you create the registry entry under HKEY_LOCAL_MACHINE, the application startup is forced on all users on the local machine. Write entries below HKEY_CURRENT_USER key to target only the current logged(active) user while this application is launched.
CString csPath ="your path";
HRESULT hres = RegCreateKey(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", &hkey);
hres = RegSetValueEx(hkey, L"your app", 0, REG_SZ , (BYTE*)csPath.GetBuffer(), (wcslen(csPath)+1)*2);

Install Shield 2009 Premier, Uninstall doesn't close the process/gui

My application (developed using C#.net) is open now i uninstall, InstallShield gives message stating the application is already open and whether really want to close the application. Selection 'Ignore' continues uninstall. Some files and the exe of the application are not closed. How to close them by installshield on uninstall. Or there are some properties I have to set. I know adding a custom action at uninstall i can kill the process, but shouldn't installshield do it?
If your goal is to restart the open applications and not honor the "Ignore" selection, you might consider setting the "REBOOT" property to "Force". That will ask that user to restart the system, thus achieving your desired result.
If your project type is InstallScript MSI or it supports Installscript, i prefer to write code for this for example:
export prototype _Server_UnInstalling();
function _Server_UnInstalling()
STRING Application, ServiceName;
begin
//application name
Application = "Demo";
MessageBox("In _Server_UnInstalling",INFORMATION);
//Check whether application is running or not.
if ProcessRunning( Application ) then
MessageBox("Demo is running",INFORMATION);
//Close server Application
ProcessEnd(Application);
endif;
//if application is having service at the background then
ServiceName = "Demo Server";
//Uninstall the server windows services on uninstallation.
ServiceRemoveDuringUninstallation(ServiceName);
end;
The above example give the skeleton, you need to implement the logic for ProcessRunning, ProcessEnd and ServiceRemoveDuringUninstallation methods, you can refer Installshield help doc they have given documentation with along with source code
hope this helps...

How do I disable the 'Debug / Close Application' dialog on Windows Vista?

When an application crashes on Windows and a debugger such as Visual Studio is installed the following modal dialog appears:
[Title: Microsoft Windows]
X has stopped working
A problem caused the program to stop
working correctly. Windows will close
the program and notify you if a
solution is available.
[Debug][Close Application]
Is there a way to disable this dialog? That is, have the program just crash and burn silently?
My scenario is that I would like to run several automated tests, some of which will crash due to bugs in the application under test. I don't want these dialogs stalling the automation run.
Searching around I think I've located the solution for disabling this on Windows XP, which is nuking this reg key:
HKLM\Software\Microsoft\Windows NT\CurrentVersion\AeDebug\Debugger
However, that did not work on Windows Vista.
To force Windows Error Reporting (WER) to take a crash dump and close the app, instead of prompting you to debug the program, you can set these registry entries:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting]
"ForceQueue"=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\Consent]
"DefaultConsent"=dword:00000001
After this is set, when your apps crash, you should see *.hdmp and *.mdmp files in:
%ALLUSERSPROFILE%\Microsoft\Windows\WER\
See here:
http://msdn.microsoft.com/en-us/library/bb513638.aspx
regedit
DWORD HKLM or HKCU\Software\Microsoft\Windows\Windows Error Reporting\DontShowUI = "1"
will make WER silently report. Then you can set
DWORD HKLM or HKCU\Software\Microsoft\Windows\Windows Error Reporting\Disabled = "1"
to stop it from talking to MS.
I'm not sure if this refers to exactly the same dialog but here is an alternative approach from Raymond Chen:
DWORD dwMode = SetErrorMode(SEM_NOGPFAULTERRORBOX);
SetErrorMode(dwMode | SEM_NOGPFAULTERRORBOX);
I had to disable this for release automation work on Windows 64-bits for Firefox and I did the following:
gpedit.msc
Computer configuration -> Administrative Templates
Windows Components -> Windows Error Reporting
Set "Prevent display of the user interface for critical errors" to Enabled
It is similar what was accomplished for Customer Experience reporting in:
http://www.blogsdna.com/2137/fix-windows-installer-explorer-update-has-stopped-working-in-windows-7.htm
In my context, I only want to suppress the popup for my unit tests and not for the entire system. I've found that a combination of functions are needed in order to suppress these errors, such as catching unhandled exceptions, suppressing run time checks (such as the validity of the stack pointer) and the error mode flags. This is what I've used with some success:
#include <windows.h>
#include <rtcapi.h>
int exception_handler(LPEXCEPTION_POINTERS p)
{
printf("Exception detected during the unit tests!\n");
exit(1);
}
int runtime_check_handler(int errorType, const char *filename, int linenumber, const char *moduleName, const char *format, ...)
{
printf("Error type %d at %s line %d in %s", errorType, filename, linenumber, moduleName);
exit(1);
}
int main()
{
DWORD dwMode = SetErrorMode(SEM_NOGPFAULTERRORBOX);
SetErrorMode(dwMode | SEM_NOGPFAULTERRORBOX);
SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)&exception_handler);
_RTC_SetErrorFunc(&runtime_check_handler);
// Run your tests here
return 0;
}
In WPF application
[DllImport("kernel32.dll", SetLastError = true)]
static extern int SetErrorMode(int wMode);
[DllImport("kernel32.dll")]
static extern FilterDelegate SetUnhandledExceptionFilter(FilterDelegate lpTopLevelExceptionFilter);
public delegate bool FilterDelegate(Exception ex);
public static void DisableChashReport()
{
FilterDelegate fd = delegate(Exception ex)
{
return true;
};
SetUnhandledExceptionFilter(fd);
SetErrorMode(SetErrorMode(0) | 0x0002 );
}
You have to implement an unhandled exception filter which simply quits your application, then set that filter function with SetUnhandledExceptionFilter().
If you're using the secure CRT, you also have to provide your own invalid parameter handler and set this with _set_invalid_parameter_handler().
This blog post has some information too:
http://blog.kalmbachnet.de/?postid=75
During test you can run with a 'debugger' like ADPlus attached which can be configured in many useful ways to collect data (minidumps) on errors and yet prevent the modal dialog problems you state above.
If you want to get some useful information when your app crashes in production you can configure Microsoft Error reporting to get something similar to ADPlus data.
This isn't a direct answer to the question since this is a workaround and the question is about how to disable that feature, but in my case, I'm a user on a server with limited permissions and cannot disable the feature using one of the other answers. So, I needed a workaround. This will likely work for at least some others who end up on this question.
I used autohotkey portable and created a macro that once a minute checks to see if the popup box exists, and if it does, clicks the button to close the program. In my case, that's sufficient, and leaves the feature on for other users. It requires that I start the script when I run the at-risk program, but it works for my needs.
The script is as follows:
sleep_duration = 60000 ; how often to check, in milliseconds.
; 60000 is a full minute
Loop
{
IfWinExist, ahk_class #32770 ; use autohotkey's window spy to confirm that
; ahk_class #32770 is it for you. This seemed to be consistent
; across all errors like this on Windows Server 2008
{
ControlClick, Button2, ahk_class #32770 ; sends the click.
; Button2 is the control name and then the following
; is that window name again
}
Sleep, sleep_duration ; wait for the time set above
}
edit: A quick flag. When other things are up, this seems to attempt to activate controls in the foreground window - it's supposed to send it to the program in the background. If I find a fix, I'll edit this answer to reflect it, but for now, be cautious about using this and trying to do other work on a machine at the same time.
After trying everything else on the internet to get rid of just in time debugger, I found a simple way that actually worked and I hope will help someone else.
Go to Control Panel
Go to Administrative Tools
Go to Services
Look down the list for Machine Debug Manager
Right Click on it and click on Properties
Under the General Tab, look for Start Up Type
Click on Disable.
Click on Apply and OK.
I haven't seen the debugger message since, and my computer is running perfectly.
Instead of changing values in the registry you can completly disable the error reporting on Windows Server 2008 R2, Windows Server 2012 and Windows 8 with: serverWerOptin /disable
https://technet.microsoft.com/en-us/library/hh875648(v=ws.11).aspx

Resources