Redémarrer un ordinateur à distance

Tout d’abord, sur l’ordinateur qu’on souhaite faire redémarrer, il faut se rendre dans : Panneau de ConfigurationRéseau et InternetCentre réseau et partageModifier les paramètres de partage avancés puis Activer le partage de fichiers et d’imprimantes dans « Privé » :
20140526_shutdown_1

Ensuite il faut ouvrir la base de registre avec la commande regedt32.exe et aller à HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System. Faites un clic-droit sur « System » et choisir Nouveau > Valeur DWORD (32bits). Appeler la nouvelle variable en LocalAccountTokenFilterPolicy et lui attribuer la valeur 00000001.

Enfin lancer la stratégie de sécurité avec la commande secpol.msc. Aller dans Stratégie LocaleAttribution des droits utilisateur et chercher Forcer l’arrêt à partir d’un système distant. Ajouter l’utilisateur de l’ordinateur.

Maintenant sur l’ordinateur distant taper : net use \\IP_ORDINATEUR_DISTANT et il va demander d’entrer un nom d’utilisateur (mettre celui indiqué dans l’étape précédente) et le mot de passe associé. Ensuite utiliser la commande shutdown /r /m \\IP_ORDINATEUR_DISTANT (voir l’aide pour le détail des commandes)

Cette manipulation permet de corriger l’erreur Access is denied.(5) qui arrive lorsqu’on tente la commande shutdown.

Constant network activity with Android

I’ve had a recent issue with my Android 4.4 phone causing a constant network activity and draining my battery like crazy. After searching over Internet I found that could be due to one of my devices on my local network (because of a packet broadcast). I disconnected everything, but no luck. Then I installed an app from the store to find which apps are using my battery, but it states it was Android System…

Some forum posts said that could be some ICMP traffic due to the phone trying to reach the Google servers, or something similar.

Finally I installed several applications to monitor my phone. The best one was « Network Log » that is able to show the trafic received/sent for each application. I found that one of my app might be the issue: I uninstalled it and the trafic stopped!

So I recommend this app to find out which app could be the reason of the bad network activity.

How to change the Firefox portable main window icon? [Astuce]

If you use Firefox Portable in the same time as the regular Firefox, then it can be annoying to see the same icons for the both Firefox. You can easily change the icon for the main window of the portable version of Firefox. Just find the .ico you want to use and place it into this folder : FirefoxPortable\App\Firefox\browser\chrome\icons\default\main-window.ico

If the folders don’t exist, then create them. Also you have to rename your icon to main-window.ico. When it’s done, just close and reopen Firefox.

That works for, at least, Firefox 27. If you use an older version of Firefox you may want to try this different folder : FirefoxPortable\App\Firefox\chrome\icons\default\main-window.ico

Show the full content of a Sharepoint Calendar event box

With a Sharepoint Calendar the events with a long title/description are cropped and you cannot see the full description, except if you move your mouse over it.
Example:
image001

So I’ve had to do some CSS and a complicated JavaScript code to be able to create some large boxes. Now we are able to see the full content title/description of the event.
The result is below:
image002

As you can see, the boxes for the events are now bigger!

To do so, you’ll have to insert the below code into your page:

<style type="text/css">
.ms-acal-rootdiv div {
  overflow: visible;
  white-space: normal;
}
.ms-acal-item { height:auto !important }
.ms-acal-outday { height:100% !important }
</style>
<script type="text/javascript" src="//code.jquery.com/jquery-1.11.0.min.js"></script>
<script type="text/javascript">
// load the function after the events are loaded
_spBodyOnLoadFunctionNames.push('changeCalendarEventLinkIntercept');
function changeCalendarEventLinkIntercept() {
  var OldCalendarNotify4a = SP.UI.ApplicationPages.CalendarNotify.$4b;
  SP.UI.ApplicationPages.CalendarNotify.$4b = function () {
    OldCalendarNotify4a();
    setTimeout(function() { showFullEvents() }, 250)
  }
}
// on resize the boxes must be replaced
$(window).on('resize', function() {
  setTimeout(function() { showFullEvents() }, 500)
});

function showFullEvents() {
  var prevPos={bottom:0,left:0};
  var minHeight=0,savedHeight=0,savedMinHeight=0,diffHeight=0;
  var aRows=jQuery('.ms-acal-summary-itemrow');
  
  // set the same size for each row
  aRows.each(function() {
    var h=$(this).outerHeight();
    if (savedMinHeight<h) savedMinHeight=h;
    // save the current height of the row
    $(this).data("saved-height",h)
  }).each(function() { $(this).css("height",savedMinHeight+"px"); });
  
  savedHeight=savedMinHeight;
  
  // move the events
  jQuery('.ms-acal-item').each(function() {
    var $this=$(this);
    var pos=$this.position();
    var height=$this.outerHeight();
    var bottom=pos.top+height;
    minHeight+=height;
    // check if the current event is hover the previous one
    if (prevPos.left === pos.left && prevPos.bottom>pos.top) {
      $this.css("top",(1+prevPos.bottom)+"px")
      bottom += prevPos.bottom-pos.top + 1;
      minHeight+=2;
    }
    // check if we need to make the cell bigger
    if (prevPos.left !== pos.left && savedMinHeight<minHeight) {
      diffHeight=minHeight-savedHeight; // diffHeight will permit to move down all the events later
      savedMinHeight=minHeight;
      jQuery('.ms-acal-summary-itemrow > td').css("height",minHeight+"px")
    }
    if (prevPos.left !== pos.left) minHeight=0
    prevPos={bottom:bottom,left:pos.left};
  })
  
  if (diffHeight>0) {
    var prevDiff=0,diff=0,prevRow=0;
    jQuery('.ms-acal-item').each(function(idx) {
      var $this=$(this);
      // find index that defines the row
      var row=1*$this.attr("_index").split(",")[0];
      if (idx===0 || prevRow!=row) {
        prevDiff=diff;
        diff+=savedMinHeight-aRows.eq(row).data("saved-height");
      }
      if (row > 0) $this.css("top",($this.position().top+prevDiff+2)+"px")
      prevRow=row;
    })
  }
}
</script>

The code could be more clean, but I did that during an evening after a long day of work, so I’m just happy that it’s working. If you’re able to produce a cleaner code, please share it with me!

To give some explanations :

  • The CSS permits to wrap the text and make the colored boxes bigger
  • The problem starts when there are more than 1 event in a day because the boxes hover each other
  • So with JavaScript we have to calculate which boxes are hover the others, and then move them down
  • But if you move the boxes, you also have to make the cells bigger…
  • And if the cells are bigger, then you need to move down the events/boxes that are in the below row
  • And finally, when the window is resized, Sharepoint is moving them around, so the script has to execute again after a resize.

Tested only with Sharepoint 2010, with IE7+, Firefox and Chrome.

Override SharePoint OOTB Upload.aspx default for « Add as a new version to existing files » checkbox

With Sharepoint, when we want to upload a file, the « Add as a new version to existing file » is checked by default, and that could be an issue for you.

sharepoint_upload_file

Here is a JavaScript fix to add into your masterpage, just before the </head> tag :

<script type="text/javascript">
function DefaultUploadOverwriteOff() {
  if (document.title.indexOf("Upload Document") > -1) {
    var input=document.querySelectorAll("input");
    for (var i=input.length; i--;) {
      if (input[i].id.search(/\_OverwriteSingle$|\_OverwriteMultiple$/) > -1) input[i].checked=false
    }
  } 
}
_spBodyOnLoadFunctionNames.push('DefaultUploadOverwriteOff');
</script>
</head>

Requête MySQL insensible aux accents

Pour effectuer une requête MySQL qui ne sera pas sensible aux accents (par exemple ‘ö’ = ‘o’ ou ‘à’ = ‘a’) il faut rajouter le mot clé COLLATE avec la bonne collection. Après plusieurs tests, j’utilise la collection utf8_general_ci.
Ce qui donnera :

SELECT ID, Nom FROM Inscrits WHERE Nom LIKE '%heracles%' COLLATE utf8_general_ci ORDER BY Nom

Qui retournera, par exemple, « Héraclès ».

ATTENTION : si cette requête fonctionne sur le serveur directement, mais pas dans votre code PHP, alors il faudra peut-être utiliser mysqli_set_charset('utf8'); dans votre code afin que la liaison se fasse correctement.

Déplacer le volet de détails en bas sous Windows 8 [Astuce]

Windows 8 apporte différentes nouveautés, dont dans l’explorateur. Malheureusement ces modifications ne sont pas toujours les bienvenues… Par exemple le volet de détails apparait désormais à droite et non plus en bas de la fenêtre, ce qui n’est pas pratique et mange de la place.

Heureusement il existe un moyen de la déplacer vers le bas, et de faire quelques autres modifications (comme remettre l’ancienne barre à la place du ruban). Pour cela Tihiy a créé une petite application qui hyper basique et simple à utiliser. Elle est à découvrir sur le forum MSFN (je conserve également une copie sur mon blog si jamais le topic du forum venait à disparaître).

Google Analytics : les recommandations de la CNIL [JavaScript]

La loi a changé concernant les cookies déposés chez les utilisateurs. Pour cela la CNIL a créé une page qui explique ce qu’il en est. Ils proposent même un bout de code pour le opt-in et le opt-out, que j’ai légèrement modifié :

// Remplacez la valeur UA-XXXXXX-Y par l'identifiant analytics de votre site.
var gaProperty = 'UA-XXXXXX-Y';
// Désactive le tracking si le cookie d'Opt-out existe déjà
var disableStr = 'ga-disable-' + gaProperty;
if (document.cookie.indexOf('hasConsent=false') > -1) window[disableStr] = true;
//Cette fonction retourne la date d.expiration du cookie de consentement 
function getCookieExpireDate() { 
  var cookieTimeout = 34214400000; // Le nombre de millisecondes que font 13 mois 
  var date = new Date();
  date.setTime(date.getTime()+cookieTimeout);
  var expires = "; expires="+date.toGMTString();
  return expires;
}
// Cette fonction est appelée pour afficher la demande de consentement
function askConsent(){
  var bodytag = document.getElementsByTagName('body')[0];
  var div = document.createElement('div');
  div.setAttribute('id','cookie-banner');
  div.style.width="50%";
  div.style.position="absolute";
  div.style.left="20%";
  // Le code HTML de la demande de consentement
  // Vous pouvez modifier le contenu ainsi que le style
  div.innerHTML =  '<div style="background-color:transparent;color:#fff">Ce site utilise Google Analytics.\
  En continuant à naviguer, vous nous autorisez à déposer des cookies à des fins de \
  mesure d\'audience. Vous pouvez vous <a href="#optout" onclick="gaOptout()">opposer à ce dépôt</a> ou <a href="#optin" onclick="gaOptIn(); document.getElementById(\'cookie-banner\').style.display=\'none\'">ignorer ce message</a>.</div>';          
  bodytag.insertBefore(div,bodytag.firstChild); // Ajoute la bannière juste au début de la page 
  document.getElementsByTagName('body')[0].className+=' cookiebanner';              
}      
// Retourne la chaine de caractère correspondant à nom=valeur
function getCookie(NomDuCookie)  {
  if (document.cookie.length > 0) {        
    var begin = document.cookie.indexOf(NomDuCookie+"=");
    if (begin != -1)  {
      begin += NomDuCookie.length+1;
      var end = document.cookie.indexOf(";", begin);
      if (end == -1) end = document.cookie.length;
      return unescape(document.cookie.substring(begin, end)); 
    }
  }
  return null;
}
// Fonction d'effacement des cookies   
function delCookie(name)   {
  var path = ";path=" + "/";
  var domain = ";domain=" + "."+document.location.hostname;
  var expiration = "Thu, 01-Jan-1970 00:00:01 GMT";       
  document.cookie = name + "=" + path + domain + ";expires=" + expiration;
}
// Efface tous les types de cookies utilisés par Google Analytics    
function deleteAnalyticsCookies() {
  var cookieNames = ["__utma","__utmb","__utmc","__utmz","_ga"]
  for (var i=0; i<cookieNames.length; i++) delCookie(cookieNames[i])
}
// La fonction d'opt-out   
function gaOptout() {
  document.cookie = disableStr + '=true;'+ getCookieExpireDate() +' ; path=/';       
  document.cookie = 'hasConsent=false;'+ getCookieExpireDate() +' ; path=/';
  var div = document.getElementById('cookie-banner');
  // Ci dessous le code de la bannière affichée une fois que l'utilisateur s'est opposé au dépôt
  // Vous pouvez modifier le contenu et le style
  if ( div!= null ) div.innerHTML = '<div style="background-color:#ffffff"> Vous vous êtes opposé \
  au dépôt de cookies de mesures d\'audience dans votre navigateur.</div>'
  window[disableStr] = true;
  deleteAnalyticsCookies();
}
function gaOptIn() {
  document.cookie = 'hasConsent=true; '+ getCookieExpireDate() +' ; path=/';
}
//Ce bout de code vérifie que le consentement n'a pas déjà été obtenu avant d'afficher la bannière
var consentCookie = getCookie('hasConsent');
//L'utilisateur n'a pas encore de cookie de consentement
if (!consentCookie) askConsent()
// Google Analytics
var _gaq = _gaq || [];
_gaq.push(['_setAccount', gaProperty]);
_gaq.push(['_trackPageview']);

(function() {
  var ga = document.createElement('script');
  ga.src = 'http://www.google-analytics.com/ga.js';
  ga.setAttribute('async', 'true');
  document.documentElement.firstChild.appendChild(ga);
})();

FreeFileSync with size only comparison

FreeFileSync is a powerful backup tool for Windows, Linux and Mac that permits to save over the network to a WebDAV drive for example. They can be very useful with some cloud services like Box.com.

However, it’s best to use the comparison by size only, and not size AND date. The reason is that some WebDAV drives don’t support the date. So if you don’t choose « size only » then everything will be synchronized, all the time !

To do so, read the HelpFile of FreeFileSync: « Expert Settings ». They explain it’s possible to do « size only » in changing the FileTimeTolerance setting. Just close the program and edit the « GlobalSettings.xml » file (see the HelpFile to find where it’s located… on Windows it’s under %AppData%\FreeFileSync). Set the value to -1 (for the number of seconds).

Partage sous Windows 7 et « System error 53 has occurred. »

Ma configuration réseau est un peu particulière : j’ai un ordinateur (machine A) sous Windows 7 en WORKGROUP (avec un login et un mot de passe), et une autre machine Windows 7 du boulot avec un login/pass sur un domaine (machine B).

Pour réussir à se connecter aux disques partagés de la machine A, voici comment j’ai dû procéder :

  1. S’assurer que les deux machines sont connectées sur le même réseau
  2. Faire un clic droit sur le disque à partager sur la Machine A, puis Propriétés. Dans l’onglet Partage, cliquez sur Partage Avancé. Cochez la case « Partager ce dossier » et donnez lui un nom. Enfin cliquez sur Autorisations
    partage_windows_1
  3. Assuez vous de cocher « Contrôle Total » pour « Tout le monde ». Puis valider toutes les fenêtres en cliquant sur OK.
    partage_windows_2
  4. Maintenant allez dans le menu Démarrer de Windows de la Machine A toujours et entrez fsmgmt.msc dans la zone de recherche puis tapez sur ENTRER
  5. Dans la fenêtre qui apparait, cliquez sur Partages. Vous devriez alors voir le dernier partage que vous venez de faire. Clique droit puis Propriétés et enfin onglet Sécurité et Modifier.
    partage_windows_3
  6. Cliquez sur Ajouter…, et dans la zone prévue à cet effet entrez « Tout le monde » et cliquez sur Vérifier les noms pour s’assurer que c’est bien reconnu. Vous pouvez valider.
    partage_windows_4
  7. Assurez-vous de donner le contrôle total à tout le monde
    partage_windows_5
  8. Maintenant allez sur la Machine B. Dans « Network » vous devriez voir la Machine A. Si vous cliquez dessus le système pourrait vous demander un login et password (dans ce cas le login est « Nom Machine A\le nom d’utilisateur que vous utilisez pour vous connecter à Machine A » et le mot de passe associé). Puis vous devriez voir les disques que vous avez précédemment partagés !