Problem with Custom TFS Web Service Plugin - web-services

i'm not sure that what im going to do is the right so i first of all tell you my issue.
I have TFS as Bugtracking System and another system for tracking the worktime. I want that if a workitem status changes the other system changes the status too.
What i did until now is the following.
I wrote a plugin for the TFS web service were i catch the WorkItemChangedEvent.
public EventNotificationStatus ProcessEvent(TeamFoundationRequestContext requestContext, NotificationType notificationType, object notificationEventArgs,
out int statusCode, out string
statusMessage, out ExceptionPropertyCollection properties)
{
statusCode = 0;
properties = null;
statusMessage = String.Empty;
try
{
if (notificationType == NotificationType.Notification && notificationEventArgs is WorkItemChangedEvent)
{
WorkItemChangedEvent ev = notificationEventArgs as WorkItemChangedEvent;
EventLog.WriteEntry("WorkItemChangedEventHandler", "WorkItem " + ev.WorkItemTitle + " was modified");
}
}
catch (Exception)
{
}
return EventNotificationStatus.ActionPermitted;
}
I droped the DLL in C:\Program Files\Microsoft Team Foundation Server 2010\Application Tier\Web Services\bin\Plugins
but i looks like the extension is never called. So nothing apears in the event log.
But if i try to debug the service like in this post http://geekswithblogs.net/jakob/archive/2010/10/27/devleoping-and-debugging-server-side-event-handlers-in-tfs-2010.aspx
i cant hook on the process. So debugging does not work.
Why i cant debug the service? And is there a better way to do this?

Not sure if you fixed this but to me it looks like you are missing the Subscription method in the class.
public Type[] SubscribedTypes()
{
return new Type[1] {typeof(WorkItemChangedEvent)};
}
Without this your plugin will never get hit thus you will be unable to debug.

To debug the w3wp.exe process, you need to be running Visual Studio as an administrator.
From the menu, select Debug > Attach to process (or Ctrl-Alt-P)
Select Show processes from all users and Show processes in all sessions.
Find the w3wp.exe process that corresponds to your TFS Application Pool, and attach to it.
I notice that you're using EventLog.WriteEntry() - have you registered the event source previously in your code? To avoid the registration (which requires admin permissions), you might try using the TFS logger:
TeamFoundationApplication.Log("WorkItem " + ev.WorkItemTitle + " was modified", 0, System.Diagnostics.EventLogEntryType.Information);

Related

WinAPI ReportEvent - component not installed

I've implemented a simple function to log on event viewer from my application. However, I'm getting the following message every time I log something, regardless the error level:
The description for Event ID 0 from source MyAppEvents cannot be found. Either the component that raises this event is not installed on your local computer or the installation is corrupted. You can install or repair the component on the local computer.
If the event originated on another computer, the display information had to be saved with the event.
I'm not an expert on Event log, actually, this is the first time I'm using it in C++, and the documentation is confusing and misleading...
Here is the method I've implemented, to encapsulate event log calls:
HANDLE source = NULL;
void app_log(std::string m, WORD level) {
std::wstring msg_temp (m.begin(), m.end());
LPCWSTR msg = msg_temp.c_str();
std::wstring name(L"MyAppEvents");
if (source == NULL)
source = RegisterEventSource(NULL, name.c_str());
if (source) {
if (!ReportEvent(source, level, 0, 0, NULL, 1, 0, &msg, NULL))
std::cerr << "Error when logging";
}
else
std::cerr << "Error when logging";
}
I have an installer for my app, built with WIX (this installer creates the key needed to log on event viewer - subkey of Application) and it runs smoothly. However, I didn't understand that message, and also don't know how to attach my installed app to the event log - I'm actually not even sure if this is the problem, or if it is maybe one of the parameters I'm passing as NULL or 0.
This message appears also when I debug (without installing, but with the "application subkey" manually created).
Could you help me?
I can't use C++ managed code...
There is nothing wrong with your logging code. The warning message simply means that you have not properly registered the MyAppEvents event source in the Registry. This is documented on MSDN:
RegisterEventSource function:
pSourceName [in]
The name of the event source whose handle is to be retrieved. The source name must be a subkey of a log under the Eventlog registry key. Note that the Security log is for system use only.
Event Sources:
The structure of the event sources is as follows:
HKEY_LOCAL_MACHINE
SYSTEM
CurrentControlSet
Services
EventLog
Application
AppName
Security
System
DriverName
CustomLog
AppName
...
Each event source contains information (such as a message file) specific to the software that will be logging the events
...
An application can use the Application log without adding a new event source to the registry. If the application calls RegisterEventSource and passes a source name that cannot be found in the registry, the event-logging service uses the Application log by default. However, because there are no message files, the Event Viewer cannot map any event identifiers or event categories to a description string, and will display an error. For this reason, you should add a unique event source to the registry for your application and specify a message file.
It is not enough to just create the MyAppEvents subkey, you also have to point it to the message files for your app. If you store your event log categories and event messages as resources of your app executable, the subkey can register the executable itself as the message files.

Run an executable as service in C++

I created a Win32Console application using MSVS2013 and it was compiled successfully. Now I tried creating a service using CreateService and binary path was set to the path of the above produced executable. Though I was able to create the service, I cannot start it using StartService. The error code 1053 is thrown each time. I tried using sc.exe and also tried to start the service manually from Services. The same error is shown. How can I solve it now?
You must create a ServiceMain.
Here is a sample.
If you want to execute a non-service application you can use psexec.
You have collision with SC- manager and your function inside application start service
your name of the function service dispatcher table for service;)
prevent from error 1053 if call was send not from SC - manager
C++ code:
if(argc < 2)
{
if(!Service_Dispatcher_Table())
{
std::cout<<"ERROR :"<< GetLastError();
}
}
else
{
//your command line "argc"
}
//here your commands or function : startservice();

Issue with CQN registration getting dropped implictly

Using custom C++ OCI wrappers, I can successful register a CQN C++ callback-based registration, but it appears that somehow the subscription is dropped right away, behind my back. I get no call back on simple DMLs. If I try to unregister that subscription, for which register() worked just fine, I get ORA-29970: Specified registration id does not exist.
I'm running this test on a Win7 (64-bit) box, running a local 11.2.0.1.0 Oracle Server, and I connect with a C++ client app built against instantclient-11.2.0.2.0 that runs on that same machine.
I tried setting OCI_ATTR_SUBSCR_TIMEOUT explicitly to 0, to no avail.
I checked the job_queue_processes instance param to make sure it's not 0 (it's 1000).
Of course, the user/schema I'm connecting with has been granted CHANGE NOTIFICATION
I'm running out of ideas on this issue, and I would appreciate some insights on what else I could try or check.
I'm starting to wonder if CQN needs to be activated somehow. My DBA skills are close to nonexistent, this is a stock install of 11gR1 on Windows using the installer, with no special configurations or customization done at all.
Thanks, --DD
Update #1
A colleague successfully ran that same test, and he ran it using the server-provided oci.dll. I tried that (I build using instantclient, but forced the PATH at runtime: Path=D:\oracle\product\11.2.0\dbhome_1\BIN;$(Path) in VS Property Page> Debugging> Environment), and indeed the CQN test works! We still haven't figured out whether the slight version difference between client and server, or using instantclient (the Light variant by the way) vs a full client vs a server install is the real culprit.
But it is bad news that a newer instantclient does not support CQN...
Update #2
I've tried all 6 combinations of instantclient Light (65 MB) or Normal (150 MB) in versions 12.2.0.(1|2|3).0 on Win64, and none of them worked. Haven't tested the Full Client yet, nor have we tested on Linux just yet.
Environment_var cqn_env = Environment::create(OCI_EVENTS + OCI_OBJECT);
Connection_var cqn_conn = Connection::logon2(...);
Subscription sub(cqn_conn, "cqn_test", OCI_SUBSCR_NAMESPACE_DBCHANGE);
sub.set<attr::SUBSCR_CALLBACK>( &cqn_callback_func );
sub.set<attr::SUBSCR_CQ_QOSFLAGS>( OCI_SUBSCR_CQ_QOS_QUERY );
try {
sub.register_self();
} catch (const OracleException& ex) {
BOOST_REQUIRE(ex.error_code && *ex.error_code == 29972);
cerr << "\nSKIPPED: test requires CHANGE NOTIFICATION privilege" << endl;
return;
}

I get the "FilenotfoundExceptionunhandled" ? in Console application while displaying the SharePoint site list name

Error Details:
The Web application at
http://dev001aaamaaind:333/ could
not be found. Verify that you have
typed the URL correctly. If the URL
should be serving existing content,
the system administrator may need to
add a new request URL mapping to the
intended application.
string urlSite = "http://dev001aaamaaind:333/";
using (SPSite sc = new SPSite(urlSite))//Getting Error in the line
{
SPWeb site = sc.RootWeb;
foreach (SPList list in site.Lists)
{
if (!list.Hidden)
Console.WriteLine(list.Title);
}
}
Make sure that you have set the Platform in the Project Properties Build tab to either to x64 or Any CPU. This is one common issue that hit when developing using SharePoint 2010 as it is based on 64 bit Arch.
http://spserver2010.blogspot.com/2010/09/visual-studio-2010-beta-console.html

How to detect whether Windows is shutting down or restarting

I know that when Windows is shutting down, it sends a WM_QUERYENDSESSION message to each application. This makes it easy to detect when Windows is shutting down. However, is it possible to know if the computer going to power-off or is it going to restart after Windows has shutdown.
I am not particularly hopeful, considering the documentation at MSDN has this to say about WM_QUERYENDSESSION: "...it is not possible to determine which event is occurring," but the cumulative cleverness of stackoverflow never ceases to amaze me.
In Windows 7 (and probably also in Vista / 8 / Server) you could use the system events to track whether Windows is shutting down (and powering off the computer) or just restarting. Every time a shutdown/reboot is initiated (by any means - clicking the button in Start menu, or programmatically), Windows 7 writes one or two events in the System log, source USER32, event ID 1074. You can see these events recorded if you open the Event Viewer from Administrative Tools (filter the System log to see only ID 1074). The description (message) of these events contains the shutdown type. So you could parse the description of the most recent event of this type (after the shutdown was initiated), looking for the necessary word (shutdown, reboot/restart).
I didn't try to see the shutdown type written in the event when using the power button to gracefully shutdown Windows (I usually disable this function), but some site suggests that it states a "power off" type instead of "shutdown" - so check it out, if you need to be sure. Or simply look for a "reboot" type - if it's not found, then a "shutdown" type is assumed.
In Windows XP, from my experience, an event 1074 is recorded only if the shutdown/reboot is done programmatically (e.g. during a program install or using the shutdown.exe utility). So it does not register the shutdowns initiated from the shell (Explorer), but perhaps you could combine this method with reading the value from registry as proposed in another answer. Also, keep in mind that in WinXP the message of event 1074 contains the word "restart" no matter what the real type of shutdown is, so you should look at the "Shutdown Type:" field, which will state either "shutdown" or "reboot".
Related to this, an event ID 1073 is recorded whenever Windows fails to shutdown/reboot for some reason (e.g. if an application doesn't allow to shutdown as a response to WM_QUERYENDSESSION). In that case the message will also contain words as "shutdown", "reboot" or "power off" - in WinXP. For Win7 this type of event is less useful in our case, since it won't make any difference between shutdown and reboot. But for WinXP - if you only need to intercept the shutdown/reboot, perform some actions, then continue the corresponding shutdown or reboot process - it should work as expected.
From here:
You can read the DWORD value from
"HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Shutdown
Setting" to determine what the user
last selected from the Shut Down
dialog.
A bit of a roundabout solution, but it should do the trick.
A trick that usually works is to trap WM_ENDSESSION and log it. Now keep track of the time. If the system comes back up within a reasonable peroid (say 5 minutes). Then that was a reboot, not a shutdown.
Idea: If the system comes back up within 5 minutes, does it really matter if the user clicked 'shutdown' or 'reboot'?
If you really need to detect a shutdown (and the only reason I think you'd need to do this is if you're depending upon an obscure behavioral software difference between a shutdown vs a reboot) you could investigate API hooking of ExitWindowsEx and related functions but I don't recommend this approach. Rethink if you really need to detect this directly.
Possible experimental solution for Windows7 could be the following. (I'm not sure if this works well with other localizations, therefore I would call it a workaround)
using System.Diagnostics.Eventing.Reader;
namespace MyApp
{
public class RestartDetector : IDisposable
{
public delegate void OnShutdownRequsted(bool restart);
public OnShutdownRequsted onShutdownRequsted;
private EventLogWatcher watcher = null;
public RestartDetector()
{
try
{
EventLogQuery subscriptionQuery = new EventLogQuery(
"System", PathType.LogName, "*[System[Provider[#Name='USER32'] and (EventID=1074)]]");
watcher = new EventLogWatcher(subscriptionQuery);
// Make the watcher listen to the EventRecordWritten
// events. When this event happens, the callback method
// (EventLogEventRead) is called.
watcher.EventRecordWritten +=
new EventHandler<EventRecordWrittenEventArgs>(
EventLogEventRead);
// Activate the subscription
watcher.Enabled = true;
}
catch (EventLogReadingException e)
{
}
}
public void EventLogEventRead(object obj, EventRecordWrittenEventArgs arg)
{
bool restart = false;
try
{
// Make sure there was no error reading the event.
if (arg.EventRecord != null)
{
String[] xPathRefs = new String[1];
xPathRefs[0] = "Event/EventData/Data";
IEnumerable<String> xPathEnum = xPathRefs;
EventLogPropertySelector logPropertyContext = new EventLogPropertySelector(xPathEnum);
IList<object> logEventProps = ((EventLogRecord)arg.EventRecord).GetPropertyValues(logPropertyContext);
string[] eventData = (string[])logEventProps[0];
foreach (string attribute in eventData)
{
if (attribute.Contains("restart")) { restart = true; break; }
}
}
}
catch (Exception e)
{
}
finally
{
if (onShutdownRequsted != null) { onShutdownRequsted(restart); }
}
}
public void Dispose()
{
// Stop listening to events
if (watcher != null)
{
watcher.Enabled = false;
watcher.Dispose();
}
}
}
}
The following is an example of XML which is written to the event log when a PC is restarted:
- <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
- <System>
<Provider Name="USER32" />
<EventID Qualifiers="32768">1074</EventID>
<Level>4</Level>
<Task>0</Task>
<Keywords>0x80000000000000</Keywords>
<TimeCreated SystemTime="2015-12-15T11:10:43.000000000Z" />
<EventRecordID>90416</EventRecordID>
<Channel>System</Channel>
<Computer>WIN7PC</Computer>
<Security UserID="S-1-5-21-1257383181-1549154685-2724014583-1000" />
</System>
- <EventData>
<Data>C:\Windows\system32\winlogon.exe (WIN7PC)</Data>
<Data>WIN7PC</Data>
<Data>No title for this reason could be found</Data>
<Data>0x500ff</Data>
<Data>restart</Data>
<Data />
<Data>WIN7PC\WIN7PCUser</Data>
<Binary>FF00050000000000000000000000000000000000000000000000000000000000</Binary>
</EventData>
</Event>