The recommended way to create an Application Event Log using wix seems to be
<Util:EventSource
Name="BLAH"
Log="Application"
EventMessageFile="[NETFRAMEWORK40FULLINSTALLROOTDIR]EventLogMessages.dll"/>
On 64bit OS you replace it NETFRAMEWORK40FULLINSTALLROOTDIR with NETFRAMEWORK40FULLINSTALLROOTDIR64.
I have noticed that when you run a 32bit app on a 64bit OS it creates an event log with NETFRAMEWORK40FULLINSTALLROOTDIR when your use the .NET EventLog.CreateEventSource method from code.
EventMessageFile => C:\Windows\Microsoft.NET\Framework\v4.0.30319\EventLogMessages.dll
If you run a 64bit version of the app with no eventlog it will create it so
EventMessageFile => C:\Windows\Microsoft.NET\Framework64\v4.0.30319\EventLogMessages.dll
Regardless of whether the EventMessageFile has Framework or Framework64 in the path both 32bit and 64bit versions of the app can write to it merrily once it is created.
Is this supported behavior? What is the correct way to create it if one were to allow both 32bit and 64bit versions of the app side by side ?
The Windows event log allows you to create localized event log message files. When Microsoft is writing a service that is part of Windows they probably want to be able to localize what is written to the event log. However, almost everybody else just wants to be able to write a string in their language of choice to the event log and that is exactly what the .NET event log wrapper provides. Thus .NET provides a very generic event log message file that contains no localized messages but just a message with a single argument placeholder where the supplied string argument is inserted giving you total control of what your .NET application writes to the event log.
I would be surprised if the 32 bit and the 64 bit default event log message files in .NET (EventLogMessages.dll) contained different messages but even with this knowledge you should point your 32 bit service to the 32 bit DLL and the 64 bit service to the 64 bit DLL. And if I understand your question correctly that is exactly the behavior that your are seeing.
There are no real "side-by-side" issues with regard to the .NET event log message file. However, if you for some reason decide to create you own (perhaps localized) event log message file you could either install two copies of this file with the two services or you could share a copy you then install to %CommonProgramFiles%. However, not doing a side-by-side installation with two copies can cause problems down the road if one version is updated independently of the other.
Related
I have manifest-based ETW providers written in C++ and C#. Both providers use same manifest (generated by Microsoft.Diagnostics.Tracing.TraceEvent package from C# code). Channel is Debug.
Event publishing is success (return value is 0) in both providers and I can see them in perfview.
If manifest isn't installed, C++ provider's events are shown in perfview with provider's GUID, event id, etc. There is no "stringed" property like provider name, event name.
But C# provider's events have those properties.
Why C# provider can do this? In EventSource.cs, there is SendManifest method and additional ManifestData event is logged only when I use C# provider. Is this a reason? If so, can C++ provider achieve this behavior?
Edit
I know how to install manifest with wevtutil.exe or eventregister.exe. After some research, I found my necessary is implement "self-describing" event in C++.
The Windows 10 SDK includes support for a new ETW system that doesn't require a manifest at all. You can use the TraceLoggingProvider.h header to generate these events. This new system is also supported in .NET 4.6 or later in EventSource if you use the eventSource.Write method or if you set the manifest-free flag. (There is also an EventSource NuGet package if you want to use the new features but don't want to make .NET 4.6 a prerequisite for your program.)
Note that while the technology requires a new sdk, and you'll need new decoder tools to decide the new log file format, the technology works with programs running on Vista or later. In other words, you'll need to use the Windows 10 SDK to get the new TraceLoggingProvider.h header, but the resulting program will run ok on Vista or later as long as you set the WINVER macro to the right value for the OS you want to target.
The main benefit is that no manifest is needed. The main downside is that your log files will be a little bit larger (since each event needs to include a bit of information about how to decode itself).
The other answer is also correct and valid if you want to use manifest-based ETW. The only officially-supported system for manifest-based events is to register the manifest. The system that EventSource uses (where it throws a copy of the manifest into ETW) isn't well-documented, isn't supported by all of the ETW decoding tools, and I'm not sure that there's any support for you doing it yourself. If you're just interested in collecting and decoding log files, you only need to have the manifest registered on the machine where you'll be doing the decoding (the manifest is only used for merging and decoding -- it isn't needed when the log is being captured).
As far as I know TraceEvent emits the manifest during the rundown to the ETL stream which can then be decoded by WPA. Then WPA can display then the stringified name. If you let run both the C# and the C++ provider you should see one ETW provider with name. Personally I have worked around that by creating a manifest from my C# ETW provider and then registered it with in thy system with wevtutil. Then I always get a name but I need to have admin rights to do that.
See
http://etwcontroler.codeplex.com/SourceControl/latest#ETWControler/ETW/HookEvents.cs
I have developed a small-ish C# console application (TextMatcher.exe) on my local development machine and now need to deploy it to the live environment. It references another class library which I developed which has generic functions, which I intend to use and improve in future console applications.
Ultimately this specific application will be executed from within an SSIS package, but for now I'm just trying to run it from cmd.
I kid you not that this is the actual output from the program:
E:/TextMatcher>TextMatcher.exe
No
E:/TextMatcher>
The computer literally says "No" and gives no further information. I have not included, anywhere in the program, to output the word "No", on any failure or otherwise.
Of course, it runs fine locally. I made sure I included the dll of the utility class library too. I have read other questions (here, here) about how to deploy console apps correctly, and have followed the advice.
NB: This is also proving to be quite hard to Google because of the use of the word "No" being fundamental to the problem...
EDIT - It seems to be working now... I simply copied over the files again from my local machine to the remote machine... I am trying to get it to break again so that I can figure out what on Earth happened, and until I do, I will not accept an answer so that people could maybe shed some more light onto it. Either way it is quite baffling.
There's a chance that someone has modified the Image File Execution Options registry setting on the server to launch a debugger automatically.
In short, examine the registry key HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\currentversion\image file execution options and see if there's an entry that matches the name of your executable.
Check whether you have installed the necessary Framework components,
i.e. the suiting Dot net framework. Application with 4.0 and installed 3.5
can cause very strange behaviour.
Try writing a very simple window application and start it on the deployment machine
(this will give you probably more help what is missing).
Check whether the needed Dlls (that you developed, e.g. your class library) are reachable for the console application. And check whether the right version of your Dll is matched!
Check the plattform settings in your console application. Do they match with
the machine where you want to run your application? (win64 and win32 mismatch)
If all of those do not help, try inspecting your executable on the deployment machine
for example with depends.net, checkasm, or similar.
Does your production environment have AppLocker running? I don't know if its output can be customized to output "No" on a command line. Applocker comes to my mind because you can use it to restrict a system to run only signed executables. If your Textmatcher executable is unsigned, it may get shut down immediately. If you have the ability, I'd be curious to see if signing your binary changes the behavior.
When I execute this statement:
string folderPath =
Environment.GetFolderPath(Environment.SpecialFolder.CommonDocuments);
folderPath is set to C:\ProgramData.
When I execute this statement in the Immediate Window:
Environment.GetFolderPath(Environment.SpecialFolder.CommonDocuments);
C:\Users\Public\Documents is displayed (which is what I expected).
Any thoughts on the difference?
UPDATE 7/6/12:
I’m getting different results in different classes in the same exe.
I have one class that lives in a library, and one that’s linked directly into the app.
The library class returns “C:\ProgramData”.
The linked code returns “C:\Users\Public\Documents”.
Further, the library code returns “C:\ProgramData” for both
“Environment.SpecialFolder.CommonDocuments” and
“Environment.SpecialFolder.ApplicationData”.
The linked code returns “C:\Users\Public\Documents” for “Environment.SpecialFolder.CommonDocuments” and "C:\Users\Me\AppData\Roaming" for “Environment.SpecialFolder.ApplicationData”.
I’m baffled.
This could happen if your program is 64-bit. Since Visual Studio is 32-bit, when you execute Environment.GetFolderPath(Environment.SpecialFolder.CommonDocuments); in the Immediate Window, it looks up the Windows 32 hive, whereas your program would look up the 64 hive. And it is possible that the CommonDocuments folder has been moved, which would only be registered in the 64 hive.
This is a Windows bug as defined here
EDIT Your update says that it is happening in two classes within the same EXE. Since a process can only be 32-bit or 64-bit (not both), this would indicate the above bug does not apply to you (assuming normal comms between the assemblies, not COM with a wrapper for example). Are you able to work it into a suitable test that you can post?
As a quick confirmation, it might also be worthwhile including the following code in each to be doubly sure they are both running in the same process:
Console.WriteLine("{0} Process {1} is {2}bit", GetType().ToString(), System.Diagnostics.Process.GetCurrentProcess().Id, IntPtr.Size * 8);
C:\Users\Public\Documents is the right path:
Per Machine “Documents”
“Document” type files that users create/open/close/save in the application that are used across users. These are usually template or public documents.
Example: MyTemplate.dot
Windows 7: C:\Users\Public
Vista: %SystemDrive%\Users\Public
XP: %ALLUSERSPROFILE%\Documents
Environment Variable: Vista/Win7: %PUBLIC% Note: Does not exist on XP
Known Folder ID: FOLDERID_PublicDocuments
System.Environment.SpecialFolder: System.Environment.SpecialFolder.CommonDocuments
CSIDL: CSIDL_COMMON_DOCUMENTS
It’s obvious after looking at all these locations that where you store your files can be challenging if you are targeting multiple OS versions. The best guidance is to use API’s to find the special folder path. API’s will return the appropriate location for the target OS.
source: http://blogs.msdn.com/b/patricka/archive/2010/03/18/where-should-i-store-my-data-and-configuration-files-if-i-target-multiple-os-versions.aspx
I'm stumped on a windows 7 registry problem and while various questions and answers get me some of the way there, nothings I've seen addresses my particular issue. I don't know if other windows versions affects this problem, but we all have win7x64 machines.
We have a wide variety of tools at our work, some C++, some C#, some python (2.6), etc. We also run a mix of 32 and 64 bit tools. In the past, we've happily stored registry information in HKLM. We've been working on moving stuff into HKCU. We've had a lot of discussions about whether to do this, affects on UAC, etc. We really want to try and make this move. That said:
We are having trouble reading/writing registry keys out of HKCU/software/CompanyABC/App. We have a setup app write in python that writes out registry keys to the above location using _winreg. Whether or not we specify KEY_WRITE|KEY_WOW64_32KEY or just KEY_WRITE, the values get written to HKCU/Software/WOW6432Node/companyABC/app. Fine.
Then I have a C# app that tries to read these values. Using Microsoft.Win32.Registry, I open the subkey ('HKCU/Software/CompanyABC/app') and I don't see my values. Turns out that I'm seeing the following behavior:
When reading/writing registry keys from HKLM, this stuff all just works. The python app will write toHKLM/Softare/Wow6432Node/CompanyABC/app, and the C# code will read from that location. This all makes proper sense too, given how we are building our C# apps, and writing the registry values via python
Reading/writing the registry values from HKCU, I get different behavior. The _winreg functions will write toHKCU/Sofrware/Wow6432Node/CompanyABC/app, but the C# app will read from HKCU/Software/CompanyABC/app. The C# app is built as an x86 app (not Any CPU and not x64) so I assumed that the app would get properly redirected to the wow6432Node, but it doesn't seem to.
after some investigation, it appears that HKCU/Software is different. This article seems to indicate that this area is "shared" and not redirected. If that is the case, then I cannot understand why our python app (again, using _winreg) is writing to a location in HKCU that uses the Wow6432Node - it seems like it should be writing it without that redirection in place. I suppose that it could be a bug in_winreg.
I really want to avoid tacking on WOW6432Node explicitly in our tools, but that is where I am at today. Can anyone explain to me how I can make registry accesses from 32 and 64 bit processes into HKCU work correctly without having to resort to hard coded paths into the 32-bit hive?
I understand from the comments on the question that this issue has gone away, for anyone else that encounters this question, you can use Microsoft.Win32.OpenBaseKey to specify whether to open the 64 or 32-bit portion of the registry when running on a 64-bit machine even if your process is running as a 32-bit process.
If you always want to access the keys in the NON-WOW6432Node section of the registry, then you can safely set the View parameter of OpenBaseKey to RegistryView.Registry64. This will work correctly on both 64 and 32-bit OSes.
We have a .NET application that we distribute to our users via an MSI installer package. We have C++ applications that run each morning to see if the user's copy of the application is out of date, and if so, we pull down the new MSI and install it. If the application is running, we need to take it down so we can perform the update.
Our problem is that every once in a while it seems like windows "loses" our application. It will not report that the process is running - though it is. It will allow us to overwrite, or even delete, the in-use executable file without taking down the application.
Maybe this is something that is common -- but we can't figure out what is going on! Does anyone have any insight into this situation?
It seems like a temporary copy of our application is getting created, and the program is getting ran from that. But if that is the case, why doesn't it happen all the time?
EDIT:
In our program, We are using the "EnumProcesses" function from the Platform SDK, PSAPI.dll, to enumerate all of the running processes.
Could it be that either the script or the application runs as a 64-bit program, and the other as a 32-bit program? If so, then on 64-bit machines the update check could be looking in the wrong location for an existing application and thus reporting it as missing?
What mechanism are you using to check to see if the process is running or not?
Try using something like process explorer to see what path the executable image is loaded from - it should be listed in the modules section.